1. Docker 基础
菜鸟教程:传送门
1.1 Docker Hello World
Docker 允许你在容器内运行应用程序, 使用 docker run
命令来在容器内运行一个应用程序;
[root@bogon /]# docker run ubuntu:15.10 /bin/echo "Hello world"
Hello world
Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo "Hello world",然后输出结果;
- 参数解析:
-
docker
: Docker 的二进制执行文件; -
run
:与前面的 docker 组合来运行一个容器; -
ubuntu
:15.10指定要运行的镜像,Docker首先从本地主机上查找镜像是否存在,如果不存在,Docker 就会从镜像仓库 Docker Hub 下载公共镜像; -
/bin/echo "Hello world"
: 在启动的容器里执行的命令;
-
1.1.1 运行交互式的容器
通过docker的两个参数 -i -t
,让docker运行的容器实现"对话"的能力:
[root@bogon /]# docker run -i -t ubuntu:15.10 /bin/bash
root@b453fa34daea:/# cat /proc/version
Linux version 3.10.0-957.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Thu Nov 8 23:39:32 UTC 2018
root@b453fa34daea:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
执行命令后已进入一个 ubuntu15.10系统的容器,在容器中运行命令 cat /proc/version
和 ls
分别查看当前系统的版本信息和当前目录下的文件列表;
- 参数解析:
-
-t
: 在新容器内指定一个伪终端或终端; -
-i
: 允许你对容器内的标准输入 (STDIN) 进行交互;
-
1.1.2 启动容器(后台模式)
命令中加入 -d
以创建一个以进程方式运行的容器,执行后出现的长字符串叫做容器ID,对每个容器来说都是唯一的,我们可以通过容器ID来查看对应的容器发生了什么;
[root@bogon /]# docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
7f940a34f32a44fd1f7a386072ae073d7e5f8498eb79f5b1f13bcdc35dd09b49
通过执行 docker ps
来查看容器有在运行:
[root@bogon /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7f940a34f32a ubuntu:15.10 "/bin/sh -c 'while t…" About a minute ago Up About a minute youthful_leakey
CONTAINER ID:容器ID;NAMES:自动分配的容器名称
通过执行 docker logs 容器ID/容器NAMES
命令,查看容器内的标准输出;
[root@bogon /]# docker logs 7f940a34f32a 或 [root@bogon /]# docker logs youthful_leakey
hello world
...
1.1.3 停止容器
通过执行 docker stop 容器ID/容器NAMES
命令来停止容器,再通过执行 docker ps
来查看容器有在运行;
[root@bogon /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7f940a34f32a ubuntu:15.10 "/bin/sh -c 'while t…" 10 minutes ago Up 10 minutes youthful_leakey
[root@bogon /]# docker stop 7f940a34f32a 或 [root@bogon /]# docker stop youthful_leakey
youthful_leakey
[root@bogon /]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1.2 Docker 容器使用
1.2.1 Docker 客户端
通过执行 docker
命令来查看到 Docker 客户端的所有命令选项;
通过执行 docker command --help
命令更深入的了解指定的 Docker
命令使用方法,如查看 docker stats
指令的具体使用方法;
1.2.2 运行一个web应用
使用 docker
构建一个 web
应用程序,例如在docker容器中运行一个 Python Flask
应用来运行一个web应用:
[root@localhost ~]# docker pull training/webapp
[root@localhost ~]# docker run -d -P training/webapp python app.py
db5e673a8de956b3873c2fe0384cabc895e683c9453a9eb72e8d3066c924aa7d
- 参数说明:
-
-d
: 让容器在后台运行; -
-P
: 将容器内部使用的网络端口映射到我们使用的主机上;
-
1.2.3 查看 WEB 应用容器
使用 docker ps
命令来查看我们正在运行的容器:
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
db5e673a8de9 training/webapp "python app.py" 37 seconds ago Up 31 seconds 0.0.0.0:32768->5000/tcp suspicious_wozniak
[root@localhost docker]# ip addr # 查看docker映射主机的ip地址:192.168.74.128
其中 Docker
开放了 5000 端口(默认 Python Flask
端口)映射到主机端口 32769
上,可以通过浏览器输入192.168.74.128:327769
访问WEB应用;
还可以通过 -p
参数来设置不一样的端口,然后再通过 docker ps
查看正在运行的容器,最后通过浏览器输入192.168.74.128:5000
访问WEB应用:
[root@localhost ~]# docker run -d -p 5000:5000 training/webapp python app.py
162469a9aec01edd590d28eb1295637c41f6d039794878ce8b0c96cdc8575164
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
162469a9aec0 training/webapp "python app.py" 3 seconds ago Up 2 seconds 0.0.0.0:5000->5000/tcp focused_beaver
1.2.4 网络端口的快捷方式
通过 docker ps
命令可以查看到容器的端口映射,docker 还提供了另一个快捷方式 docker port
,使用 docker port
可以查看指定 (ID 或者名字)容器的某个确定端口映射到宿主机的端口号:
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
162469a9aec0 training/webapp "python app.py" 3 seconds ago Up 2 seconds 0.0.0.0:5000->5000/tcp focused_beaver
[root@localhost ~]# docker port 162469a9aec0
5000/tcp -> 0.0.0.0:5000
1.2.5 查看 WEB 应用程序日志
docker logs [ID或者名字]
可以查看容器内部的标准输出:
[root@localhost docker]# docker logs -f 162469a9aec0
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.74.1 - - [24/Aug/2019 18:46:12] "GET / HTTP/1.1" 200 -
192.168.74.1 - - [24/Aug/2019 18:46:12] "GET /robots.txt HTTP/1.1" 404 -
192.168.74.1 - - [24/Aug/2019 18:46:12] "GET /favicon.ico HTTP/1.1" 404 -
192.168.74.1 - - [24/Aug/2019 18:46:14] "GET / HTTP/1.1" 200 -
-
-f
: 让docker logs
像使用tail -f
一样来输出容器内部的标准输出;
1.2.6 查看WEB应用程序容器的进程
使用 docker top [容器名称]
来查看容器内部运行的进程:
[root@localhost docker]# docker top focused_beaver
UID PID PPID C STIME TTY TIME CMD
root 16017 16000 0 02:45 ? 00:00:00 python app.py
1.2.7 检查 WEB 应用程序
使用 docker inspect [容器名称]
来查看 Docker
的底层信息, 会返回一个 JSON 文件记录着 Docker
容器的配置和状态信息;
[root@localhost docker]# docker inspect focused_beaver
...
1.2.8 停止 WEB 应用容器
使用 docker stop [容器名称]或者[容器ID]
停止 WEB 应用容器;
1.2.9 重启WEB应用容器
对已停止的容器使用 docker start [容器名称]
进行启动;正在运行的容器,我们可以使用 docker restart [容器名称]
命令来重启;
使用docker ps -l
查询最后一次创建的容器;
1.2.10 移除WEB应用容器
使用 docker rm [容器名称]
命令来删除不需要的容器,注意删除容器时,容器必须是停止状态,否则会报如下错误;
1.3 Docker 镜像使用
1.3.1 列出镜像列表
使用 docker images
来列出本地主机上的镜像:
[root@localhost docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 7 months ago 1.84kB
ubuntu 15.10 9b9cb95443b5 3 years ago 137MB
training/webapp latest 6fae60ef3446 4 years ago 349MB
各个选项说明:
-
REPOSITORY
:表示镜像的仓库源; -
TAG
:镜像的标签; -
IMAGE ID
:镜像ID; -
CREATED
:镜像创建时间; -
SIZE
:镜像大小;
同一仓库源可以有多个 TAG
,代表这个仓库源的不同个版本,如 ubuntu
仓库源里,有15.10、14.04
等多个不同的版本,我们使用 REPOSITORY:TAG
来定义不同的镜像,例如版本为15.10的ubuntu系统镜像来运行容器时:docker run -t -i ubuntu:15.10 /bin/bash
;
1.3.2 获取一个新的镜像
当我们在本地主机上使用一个不存在的镜像时 Docker
就会自动下载这个镜像;也可以使用 docker pull
命令来预下载指定名称版本号的镜像,下载完成后,可以直接使用这个镜像来运行容器。
[root@localhost docker]# docker pull ubuntu:14.04
1.3.3 查找镜像
可以从 Docker Hub
网站来搜索镜像,Docker Hub 网址为: https://hub.docker.com/,也可以使用 docker search
命令来搜索镜像,例如需要一个 httpd
的镜像来作为我们的web服务,就可以使用docker search
命令来搜索;
[root@localhost docker]# docker search httpd
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
httpd The Apache HTTP Server Project 2622 [OK]
centos/httpd 24 [OK]
centos/httpd-24-centos7 Platform for running Apache httpd 2.4 or bui… 22
arm32v7/httpd The Apache HTTP Server Project 8
-
NAME
: 镜像仓库源的名称; -
DESCRIPTION
: 镜像的描述; -
OFFICIAL
: 是否docker官方发布;
1.3.4 拖取镜像
使用命令 docker pull
来下载镜像,下载完成后,我们就可以使用 docker run httpd
运行这个镜像了。
1.3.5 创建镜像
若从docker
镜像仓库中下载的镜像不能满足需求时,可以通过以下两种方式对镜像进行更改:
- 从已经创建的容器中更新镜像,并且提交这个镜像;
- 使用
Dockerfile
指令来创建一个新的镜像;
1.3.6 更新镜像
更新镜像之前,需要使用镜像来创建一个容器,如: docker run -t -i ubuntu:15.10 /bin/bash
;然后再运行的容器中使用 apt-get update
命令进行更新;完成操作后使用 exit 进行退出;此时afe22e398ee5
ID的容器就是按照需求更改的容器,再通过命令 docker commit
来提交容器副本;
[root@localhost docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest 7d85cc3b2d80 2 days ago 154MB
hello-world latest fce289e99eb9 7 months ago 1.84kB
ubuntu 15.10 9b9cb95443b5 3 years ago 137MB
training/webapp latest 6fae60ef3446 4 years ago 349MB
[root@localhost docker]# docker run -t -i ubuntu:15.10 /bin/bash
root@afe22e398ee5:/# apt-get update # 同步 /etc/apt/sources.list 和 /etc/apt/sources.list.d 中列出的源的索引,这样才能获取到最新的软件包,只是更新了apt的资源列表
...
root@afe22e398ee5:/# exit
[root@localhost docker]# docker commit -m="has update" -a="runoob" afe22e398ee5 runoob/ubuntu:v2
各个参数说明:
-
-m
: 提交的描述信息; -
-a
:指定镜像作者; -
e218edb10161
:容器ID; -
runoob/ubuntu:v2
: 指定要创建的目标镜像名
1.3.7 构建镜像
使用命令 docker build
从零开始来创建一个新的镜像;为此需要创建一个 Dockerfile
文件,其中包含一组指令来告诉 Docker
如何构建镜像,测试是在虚拟机的/home/dockerBuildTest
目录下新建了一个 Dockerfile
文件,将下面的内容复制进去:
[root@localhost home]# cat Dockerfile
FROM centos:6.7
MAINTAINER Fisher "fisher@sudops.com"
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
- 每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的;
- 第一条
FROM
,指定使用哪个镜像源; -
RUN
指令告诉docker
在镜像内执行命令,安装了什么; - 然后使用
Dockerfile
文件,通过docker build
命令来构建一个镜像:
[root@localhost home]# docker build -t runoob/centos:6.7 .
Sending build context to Docker daemon 2.048kB
Step 1/9 : FROM centos:6.7
6.7: Pulling from library/centos
cbddbc0189a0: Pull complete
Digest: sha256:4c952fc7d30ed134109c769387313ab864711d1bd8b4660017f9d27243622df1
Status: Downloaded newer image for centos:6.7
---> 9f1de3c6ad53
Step 2/9 : MAINTAINER Fisher "fisher@sudops.com"
---> Running in 0c187664f82c
Removing intermediate container 0c187664f82c
---> cd27f5545362
Step 3/9 : RUN /bin/echo 'root:123456' |chpasswd
---> Running in 79ffe342cc0e
Removing intermediate container 79ffe342cc0e
---> fe4cc14abecc
Step 4/9 : RUN useradd runoob
---> Running in 23ef5afd9655
Removing intermediate container 23ef5afd9655
---> 7af4fef8c0aa
Step 5/9 : RUN /bin/echo 'runoob:123456' |chpasswd
---> Running in c93e51643569
Removing intermediate container c93e51643569
---> e11a014ca16d
Step 6/9 : RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
---> Running in bfb908697150
Removing intermediate container bfb908697150
---> 2f730ba3cc10
Step 7/9 : EXPOSE 22
---> Running in 7b35db7f6085
Removing intermediate container 7b35db7f6085
---> b5cefb31f421
Step 8/9 : EXPOSE 80
---> Running in a93483068a8c
Removing intermediate container a93483068a8c
---> a5fca49d0d9a
Step 9/9 : CMD /usr/sbin/sshd -D
---> Running in 8502582a965f
Removing intermediate container 8502582a965f
---> 7c3b7236c7a8
Successfully built 7c3b7236c7a8
Successfully tagged runoob/centos:6.7
构建命令的参数说明:
-
-t
:指定要创建的目标镜像名; -
.
:Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径;
使用docker images
查看创建的镜像已经在列表中存在,镜像 ID为 7c3b7236c7a8
[root@localhost home]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
runoob/centos 6.7 7c3b7236c7a8 2 minutes ago 191MB
httpd latest 7d85cc3b2d80 2 days ago 154MB
centos 6.7 9f1de3c6ad53 5 months ago 191MB
hello-world latest fce289e99eb9 7 months ago 1.84kB
ubuntu 15.10 9b9cb95443b5 3 years ago 137MB
training/webapp latest 6fae60ef3446 4 years ago 349MB
最后使用新的镜像来创建容器,查看新镜像已经包含创建的用户runoob:
[root@localhost home]# docker run -t -i runoob/centos:6.7 /bin/bash
[root@471fa88eb567 /]# id runoob
uid=500(runoob) gid=500(runoob) groups=500(runoob)
1.3.8 设置镜像标签
使用 docker tag [镜像ID]
命令,为镜像添加一个新的标签:
[root@localhost home]# docker tag 7c3b7236c7a8 geekleng/centos:dev
[root@localhost home]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
geekleng/centos dev 7c3b7236c7a8 16 minutes ago 191MB
runoob/centos 6.7 7c3b7236c7a8 16 minutes ago 191MB
httpd latest 7d85cc3b2d80 2 days ago 154MB
centos 6.7 9f1de3c6ad53 5 months ago 191MB
hello-world latest fce289e99eb9 7 months ago 1.84kB
ubuntu 15.10 9b9cb95443b5 3 years ago 137MB
training/webapp latest 6fae60ef3446 4 years ago 349MB
使用 docker images
命令可以看到,ID为 7c3b7236c7a8
的镜像多一个名称 geekleng/centos
和标签dev
;
1.4 Docker 容器连接
1.4.1 网络端口映射
可以指定容器绑定的网络地址以及端口号,比如绑定到 127.0.0.1:5000
,使用之前的 python
应用的容器:
[root@localhost home]# docker run -d -P training/webapp python app.py
[root@localhost home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4c5536ccc37a training/webapp "python app.py" 11 seconds ago Up 9 seconds 0.0.0.0:32768->5000/tcp epic_montalcini
[root@localhost home]# docker run -d -p 5000:5000 training/webapp python app.py
[root@localhost home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a8cd6936ab21 training/webapp "python app.py" 10 seconds ago Up 7 seconds 0.0.0.0:5000->5000/tcp laughing_kilby
4c5536ccc37a training/webapp "python app.py" 55 seconds ago Up 53 seconds 0.0.0.0:32768->5000/tcp epic_montalcini
[root@localhost home]# docker run -d -p 127.0.0.1:5001:5000 training/webapp python app.py
82de5f1b230e2401e89e28f83c97e4ae66dd6e95be3b89fc8454d91c44880fd0
[root@localhost home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
82de5f1b230e training/webapp "python app.py" 3 seconds ago Up 1 second 127.0.0.1:5001->5000/tcp zen_proskuriakova
a8cd6936ab21 training/webapp "python app.py" About a minute ago Up 57 seconds 0.0.0.0:5000->5000/tcp laughing_kilby
4c5536ccc37a training/webapp "python app.py" About a minute ago Up About a minute 0.0.0.0:32768->5000/tcp epic_montalcini
使用 -P
参数创建一个容器,使用 docker ps
可以看到容器端口 5000
绑定主机端口 32768
; 使用 -p
标识来指定容器端口
绑定到主机端口
,两种方式的区别是:
-P
(大写P): 是容器内部端口随机映射到主机的高端口;
-p
(小写p): 是容器内部端口绑定到指定的主机端口;
1.4.2 Docker容器连接
端口映射并不是唯一把 docker
连接到另一个容器的方法; docker
有一个连接系统允许将多个容器连接在一起,共享连接信息; docker
连接会创建一个父子关系,其中父容器可以看到子容器的信息;
容器命名:在创建一个容器的时候, docker
会自动对它进行命名;也可以使用 --name
标识来命名容器;
[root@localhost home]# docker run -d -P --name runoob training/webapp python app.py
431af1c61e6a8c5171318e1b07c2eb0d074766c09212305322d80d39bee6789c
[root@localhost home]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
431af1c61e6a training/webapp "python app.py" 3 seconds ago Up 2 seconds 0.0.0.0:32769->5000/tcp runoob