docker简易命令

时间:2023-03-09 15:08:46
docker简易命令

docker应用

安装

sudo yum install docker

启动 docker 进程

$ sudo service docker start

Docker 默认开机启动

$ sudo chkconfig docker on

下载最新的镜像,如 centos

sudo docker pull centos

查看镜像信息

$ sudo docker images centos
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
centos latest 0b443ba03958 2 hours ago 297.6 MB

运行容器,如果正常运行,你将会获得一个简单的 bash 提示,输入 exit 来退出。

sudo docker run -ti centos /bin/bash

CentOS 项目为开发者提供了大量的的示例镜像

交互式容器,-t 表示在新容器内指定一个伪终端或终端,-i表示允许我们对容器内的 (STDIN) 进行交互。

sudo docker run -t -i ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/#

守护进程,-d 标识告诉 docker 在容器内以后台进程模式运行。docker返回的一个很长的字符串,这个长的字符串叫做容器ID(container ID)。它对于每一个容器来说都是唯一的,所以我们可以使用它。

$ sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147

注意:容器 ID 是有点长并且非常的笨拙,稍后我们会看到一个短点的 ID,某些方面来说它是容器 ID 的简化版。

查询 docker 进程的所有容器

sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e5535038e28 ubuntu:14.04 /bin/sh -c 'while tr 2 minutes ago Up 1 minute insane_babbage

docker ps 命令会返回一些有用的信息,这里包括一个短的容器 ID:1e5535038e28。

我们还可以查看到构建容器时使用的镜像,ubuntu:14.04,当命令运行之后,容器的状态随之改变并且被系统自动分配了名称 insane_babbage。

命令会查看容器内的标准输出

$ sudo docker logs insane_babbage
hello world
hello world
. . .

停止容器

$ sudo docker stop insane_babbage
insane_babbage

使用容器

docker 客户端

$ docker run -i -t ubuntu /bin/bash

运行一个web应用

$ sudo docker run -d -P training/webapp python app.py

-P 标识通知 Docker 将容器内部使用的网络端口映射到我们使用的主机上。我们指定了 training/web 镜像。我们创建容器的时候使用的是这个预先构建好的镜像,并且这个镜像已经包含了简单的 Python Flask web 应用程序。

$ sudo docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse

-l 返回最后启动容器的详细信息。

PORTS
0.0.0.0:49155->5000/tcp

在这种情况下,Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 49155 上。

Docker 能够很容易的配置和绑定网络端口。在最后一个例子中 -P 标识(flags)是 -p 5000 的缩写,它将会把容器内部的 5000 端口映射到本地 Docker。主机的高位端口上(这个端口的通常范围是 32768 至 61000)。我们也可以指定 -p 标识来绑定指定端口。

$ sudo docker run -d -p 5000:5000 training/webapp python app.py

查看网络端口

$ sudo docker port nostalgic_morse 5000
0.0.0.0:49155

查看WEB应用程序容器的进程

$ sudo docker top nostalgic_morse
PID USER COMMAND
854 root python app.py

查看WEB应用程序日志

$ sudo docker logs -f nostalgic_morse
* Running on http://0.0.0.0:5000/
10.0.2.2 - - [23/May/2014 20:16:31] "GET / HTTP/1.1" 200 -
10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 -

查看Docker的底层信息。它会返回一个 JSON 文件记录着 Docker 容器的配置和状态信息。

$ sudo docker inspect nostalgic_morse
[{
"ID": "bc533791f3f500b280a9626688bc79e342e3ea0d528efe3a86a51ecb28ea20",
"Created": "2014-05-26T05:52:40.808952951Z",
"Path": "python",
"Args": [
"app.py"
],
"Config": {
"Hostname": "bc533791f3f5",
"Domainname": "",
"User": "",
. . .

我们也可以针对我们想要的信息进行过滤,例如,返回容器的 IP 地址,

$ sudo docker inspect -f '{{ .NetworkSettings.IPAddress }}' nostalgic_morse
172.17.0.5

停止/重启/删除WEB应用容器

$ sudo docker stop nostalgic_morse
$ sudo docker start nostalgic_morse # $ sudo docker restart nostalgic_morse
$ sudo docker rm nostalgic_morse

docker镜像

列出本地主机上的镜像

sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
training/webapp latest fc77f57ad303 3 weeks ago 280.5 MB
ubuntu 13.10 5e019ab7bf6d 4 weeks ago 180 MB
ubuntu saucy 5e019ab7bf6d 4 weeks ago 180 MB
ubuntu 12.04 74fe38d11401 4 weeks ago 209.6 MB

查找镜像

  • Docker Hub
  • sudo docker search sinatra

创建我们自己的镜像

  • 我们可以从已经创建的容器中更新镜像,并且提交这个镜像。
  • 我们可以使用 Dockerfile 指令来创建一个新的镜像。

更新并且提交更改

使用镜像来创建一个容器
$ sudo docker run -t -i training/sinatra /bin/bash
root@0b2616b0e5a8:/# 已创建容器ID 0b2616b0e5a8
使用 gem 来安装 json
root@0b2616b0e5a8:/# gem install json
输入 exit命令来退出这个容器
$ sudo docker commit -m="Added json gem" -a="Kate Smith" 0b2616b0e5a8 ouruser/sinatra:v2
4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c

-m 标识我们指定提交的信息,就像你提交一个版本控制。-a 标识允许对我们的更新来指定一个作者。我们也指定了想要创建的新镜像容器来源 (我们先前记录的ID) 0b2616b0e5a8 和 我们指定要创建的目标镜像。

使用新镜像

$ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash
root@78e82f680994:/#

使用 docker commit 命令能够非常简单的扩展镜像。但是它有点麻烦,并且在一个团队中也不能够轻易的共享它的开发过程。为解决这个问题,我们使用一个新的命令 docker build , 从零开始来创建一个新的镜像。

为此,我们需要创建一个 Dockerfile 文件,其中包含一组指令来告诉 Docker 如何构建我们的镜像。

$ mkdir sinatra
$ cd sinatra
$ touch Dockerfile

编写:

# This is a comment
FROM ubuntu:14.04
MAINTAINER Kate Smith <ksmith@example.com>
RUN apt-get update && apt-get install -y ruby ruby-dev
RUN gem install sinatra

每一个指令的前缀都必须是大写的。构建镜像

docker build -t ouruser/sinatra:v2 .

我们使用 docker build 命令并指定 -t 标识(flag)来标示属于 ouruser ,镜像名称为 sinatra,标签是 v2。

如果 Dockerfile 在我们当前目录下,我们可以使用 . 来指定 Dockerfile。

Dockerfile 中的每一条命令都一步一步的被执行。我们会看到每一步都会创建一个新的容器,在容器内部运行指令并且提交更改 - 就像我们之前使用的 docker commit 一样。当所有的指令执行完成之后,我们会得到97feabe5d2ed 镜像(也帮助标记为 ouruser/sinatra:v2), 然后所有中间容器会被清除。

连接容器

网络端口映射

$ sudo docker run -d -P training/webapp python app.py
$ sudo docker run -d -p 5000:5000 training/webapp python app.py
$ sudo docker run -d -p 127.0.0.1:5001:5002 training/webapp python app.py
# 绑定容器端口5002到宿主机动态端口,并且让localhost访问
$ sudo docker run -d -p 127.0.0.1::5002 training/webapp python app.py
# 绑定UDP端口
$ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py

Docker容器连接

docker有一个连接系统允许将多个容器连接在一起,共享连接信息。docker连接会创建一个父子关系,其中父容器可以看到子容器的信息。

容器命名

$ sudo docker run -d -P --name web training/webapp python app.py
$ sudo docker inspect -f "{{ .Name }}" aed84ee21bde
/web

容器连接

$ sudo docker run -d --name db training/postgres
$ sudo docker run -d -P --name web --link db:db training/webapp python app.py

我们使用training/postgres容器创建一个新的容器。容器是PostgreSQL数据库,创建一个web容器来连接db容器。

--link name:alias

name是我们连接容器的名字,alias是link的别名。

查看容器连接

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
349169744e49 training/postgres:latest su postgres -c '/usr About a minute ago Up About a minute 5432/tcp db
aed84ee21bde training/webapp:latest python app.py 16 hours ago Up 2 minutes 0.0.0.0:49154->5000/tcp db/web,web

我们还在名字列中可以看到web容器也显示db/web。这告诉我们web容器和db容器是父/子关系。

我们连接容器做什么?我们发现连接的两个容器是父子关系。这里的父容器是db可以访问子容器web。为此docker在容器之间打开一个安全连接隧道不需要暴露任何端口在容器外部。你会注意到当你启动db容器的时候我们没有使用-P或者-p标识。我们连接容器的时候我们不需要通过网络给PostgreSQL数据库开放端口。

Docker在父容器中开放子容器连接信息有两种方法:

  • 环境变量
  • 更新/etc/hosts文件。
  • 查看列表容器的环境变量
$ sudo docker run --rm --name web2 --link db:db training/webapp env
. . .
DB_NAME=/web2/db
DB_PORT=tcp://172.17.0.5:5432
DB_PORT_5000_TCP=tcp://172.17.0.5:5432
DB_PORT_5000_TCP_PROTO=tcp
DB_PORT_5000_TCP_PORT=5432
DB_PORT_5000_TCP_ADDR=172.17.0.5
. . .

每个前缀变量是DB_填充我们指定的别名。如果我们的别名是db1,前缀别名就是DB1_。您可以使用这些环境变量来配置您的应用程序连接到你的数据库db容器。该连接时安全、私有的,只能在web容器和db容器之间通信。

docker除了环境变量,可以添加信息到父主机的/etc/hosts

root@aed84ee21bde:/opt/webapp# cat /etc/hosts
172.17.0.7 aed84ee21bde
. . .
172.17.0.5 db

一项是web容器用容器ID作为主机名字。第二项是使用别名引用IP地址连接数据库容器。现在我们试试ping这个主机:

root@aed84ee21bde:/opt/webapp# apt-get install -yqq inetutils-ping
root@aed84ee21bde:/opt/webapp# ping db
PING db (172.17.0.5): 48 data bytes
56 bytes from 172.17.0.5: icmp_seq=0 ttl=64 time=0.267 ms
56 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.250 ms

我们可以利用这个主机项配置应用程序来使用我们的db容器。

注:你可以使用一个父容器连接多个子容器。例如,我们可以有多个web容器连接到我们的db数据库容器。

管理容器数据

Docker管理数据的两种主要的方法:

  • 数据卷
  • 数据卷容器

数据卷是指在存在于一个或多个容器中的特定目录,此目录能够通过Union File System提供一些用于持续存储或共享数据的特性。

  • 数据卷可在容器之间共享或重用
  • 数据卷中的更改可以直接生效
  • 数据卷中的更改不会包含在镜像的更新中
  • 数据卷的生命周期一直持续到没有容器使用它为止

添加一个数据卷,docker run命令中使用-v标识来给容器内添加一个数据卷,你也可以在一次docker run命令中多次使用-v标识挂载多个数据卷。

$ sudo docker run -d -P --name web -v /webapp training/webapp python app.py

这会在容器内部创建一个新的卷/webapp。类似的,你可以在Dockerfile中使用VOLUME指令来给创建的镜像添加一个或多个数据卷。

挂载一个主机目录作为卷

$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py

把本地目录/src/webapp挂载到容器的/opt/webapp目录。

docker默认情况下是对数据卷有读写权限,添加了ro选项来限制它只读。

$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp:ro training/webapp python app.py

如果你想要容器之间数据共享,或者从非持久化容器中使用一些持久化数据,最好创建一个指定名称的数据卷容器,然后用它来挂载数据。

让我们创建一个指定名称的数据卷容器,实质就是挂载一个数据卷。

$ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres

可以在另外一个容器使用--volumes-from标识,通过刚刚创建的数据卷容器来挂载对应的数据卷。

$ sudo docker run -d --volumes-from dbdata --name db1 training/postgres
$ sudo docker run -d --volumes-from dbdata --name db2 training/postgres
$ sudo docker run -d --name db3 --volumes-from db1 training/postgres

也可以对一个容器使用多个--volumes-from标识,来将多个数据卷桥接到这个容器中。

数据卷容器是可以进行链式扩展的,之前的dbdata数据卷依次挂载到了dbdata 、db1和db2容器,我们还可以使用这样的方式来将数据卷挂载到新的容器db3。

启动了一个挂载dbdata卷的新容器,并且挂载了一个本地目录作为/backup卷。最后,我们通过使用tar命令将dbdata卷的内容备份到容器中的/backup目录下的backup.tar文件中。当命令完成或者容器停止,我们会留下我们的dbdata卷的备份。

$ sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata

恢复数据

$ sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
$ sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar

docker compose

docker machine