获取镜像
之前我们提到过 Docker 官方提供了一个公共的镜像仓库:Docker Hub,我们就可以从这上面获取镜像,获取镜像的命令:docker pull,格式为:
docker pull [选项] [Docker Registry 地址[:端口]/]仓库名[:标签]
- Docker 镜像仓库地址:地址的格式一般是 <域名/IP>[:端口号],默认地址是 Docker Hub。
- 仓库名:这里的仓库名是两段式名称,即 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像。比如:
[root@localhost ~]# docker pull ubuntu:16.04 16.04: Pulling from library/ubuntu 976a760c94fc: Downloading [==========> ] 9.313MB/44.15MB c58992f3c37b: Download complete 0ca0e5e7f12e: Download complete f2a274cc00ca: Download complete
上面的命令中没有给出 Docker 镜像仓库地址,因此将会从 Docker Hub 获取镜像。而镜像名称是 ubuntu:16.04,因此将会获取官方镜像 library/ubuntu 仓库中标签为 16.04 的镜像。 从下载过程中可以看到我们之前提及的分层存储的概念,镜像是由多层存储所构成。下载也是一层层的去下载,并非单一文件。下载过程中给出了每一层的 ID 的前 12 位。并且下载结束后,给出该镜像完整的sha256
的摘要,以确保下载一致性。
- 查看本地镜像
MacBook-Pro:~ lucky$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 16.04 56bab49eef2e 8 days ago 123MB
运行
有了镜像后,我们就能够以这个镜像为基础启动并运行一个容器。以上面的 ubuntu:16.04 为例,如果我们打算启动里面的 bash 并且进行交互式操作的话,可以执行下面的命令。
MacBook-Pro:~ lucky$ docker run -it --rm ubuntu:16.04 /bin/bash root@9f20efdaf1f4:/# ls bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var root@9f20efdaf1f4:/# cat /etc/os-release NAME="Ubuntu" VERSION="16.04.6 LTS (Xenial Xerus)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 16.04.6 LTS" VERSION_ID="16.04" HOME_URL="http://www.ubuntu.com/" SUPPORT_URL="http://help.ubuntu.com/" BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/" VERSION_CODENAME=xenial UBUNTU_CODENAME=xenial
docker run
就是运行容器的命令,具体格式我们会在后面的课程中进行详细讲解,我们这里简要的说明一下上面用到的参数。
- -it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
- --rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用
--rm
可以避免浪费空间。 - ubuntu:16.04:这是指用 ubuntu:16.04 镜像为基础来启动容器。
- bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash。
进入容器后,我们可以在 Shell 下操作,执行任何所需的命令。这里,我们执行了cat /etc/os-release
,这是 Linux 常用的查看当前系统版本的命令,从返回的结果可以看到容器内是 Ubuntu 16.04.4 LTS 系统。最后我们通过 exit
退出了这个容器。
- 查看运行的容器
[root@localhost ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 41a6dead6f09 ubuntu:16.04 "/bin/bash" 6 seconds ago Up 5 seconds reverent_newton
查看镜像
[root@localhost ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 16.04 56bab49eef2e 8 days ago 123MB
查看所有的容器(运行的和关闭的)
[root@localhost ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
删除容器(容器ID或名称)
MacBook-Pro:~ lucky$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ceb9464e4dbc ubuntu:16.04 "/bin/bash" 2 hours ago Exited (0) 2 hours ago awesome_payne MacBook-Pro:~ lucky$ docker rm ceb9464e4dbc ceb9464e4dbc
列出镜像
[root@localhost ~]# docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 16.04 56bab49eef2e 8 days ago 123MB
列表包含了仓库名、标签、镜像 ID、创建时间以及所占用的空间。镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个标签。
镜像大小
如果仔细观察,会注意到,这里标识的所占用空间和在 Docker Hub 上看到的镜像大小不同。比如,ubuntu:16.04 镜像大小,在这里是 127 MB,但是在Docker Hub显示的却是 43 MB。这是因为 Docker Hub 中显示的体积是压缩后的体积。在镜像下载和上传过程中镜像是保持着压缩状态的,因此 Docker Hub 所显示的大小是网络传输中更关心的流量大小。而docker image ls
显示的是镜像下载到本地后,展开的大小,准确说,是展开后的各层所占空间的总和,因为镜像到本地后,查看空间的时候,更关心的是本地磁盘空间占用的大小。
另外一个需要注意的问题是,docker image ls
列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。由于 Docker 使用Union FS
,相同的层只需要保存一份即可,因此实际镜像硬盘占用空间很可能要比这个列表镜像大小的总和要小的多。你可以通过以下命令来便捷的查看镜像、容器、数据卷所占用的空间。
[root@localhost ~]# docker system df TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 1 1 122.6MB 0B (0%) Containers 1 1 0B 0B Local Volumes 0 0 0B 0B Build Cache 0B 0B
强制删除容器
[root@localhost ~]# docker rm -f 41a6dead6f09 41a6dead6f09 [root@localho
下载镜像
[root@localhost ~]# docker pull hello-world Using default tag: latest latest: Pulling from library/hello-world 1b930d010525: Pull complete Digest: sha256:4df8ca8a7e309c256d60d7971ea14c27672fc0d10c5f303856d7bc48f8cc17ff Status: Downloaded newer image for hello-world:latest
运行一个容器
MacBook-Pro:~ lucky$ docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
查看所有运行的容器
MacBook-Pro:~ lucky$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES MacBook-Pro:~ lucky$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 547577bec57d hello-world "/hello" 18 seconds ago Exited (0) 17 seconds ago agitated_chaplygin e204bc186807 hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago interesting_agnesi 424b93a93827 hello-world "/hello" 6 minutes ago Exited (0) 6 minutes ago crazy_lederberg e48fb20490c1 hello-world "/hello" 14 minutes ago Exited (0) 14 minutes ago eloquent_volhard MacBook-Pro:~ lucky$
指定容器名,并在后台运行。
MacBook-Pro:~ lucky$ docker run --name hello-d hello-world Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
查看日志
MacBook-Pro:~ lucky$ docker logs hello-d Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
删除运行和非运行容器
MacBook-Pro:~ lucky$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES b333d73cf10f hello-world "/hello" 2 minutes ago Exited (0) 2 minutes ago hello-d 547577bec57d hello-world "/hello" 9 minutes ago Exited (0) 8 minutes ago agitated_chaplygin e204bc186807 hello-world "/hello" 11 minutes ago Exited (0) 11 minutes ago interesting_agnesi 424b93a93827 hello-world "/hello" 15 minutes ago Exited (0) 15 minutes ago crazy_lederberg e48fb20490c1 hello-world "/hello" 23 minutes ago Exited (0) 23 minutes ago eloquent_volhard MacBook-Pro:~ lucky$ docker rm hello-d hello-d
列出所有的CONTAINER ID
MacBook-Pro:~ lucky$ docker ps -aq 547577bec57d e204bc186807 424b93a93827 e48fb20490c1
删除本地镜像
MacBook-Pro:~ lucky$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 16.04 56bab49eef2e 9 days ago 123MB hello-world latest fce289e99eb9 11 months ago 1.84kB MacBook-Pro:~ lucky$ docker rmi hello-world Untagged: hello-world:latest Untagged: hello-world@sha256:4df8ca8a7e309c256d60d7971ea14c27672fc0d10c5f303856d7bc48f8cc17ff Deleted: sha256:fce289e99eb9bca977dae136fbe2a82b6b7d4c372474c9235adc1741675f587e Deleted: sha256:af0b15c8625bb1938f1d7b17081031f649fd14e6b233688eea3c5483994a66a3
后台运行
更多的时候,需要让 Docker 在后台运行而不是直接把执行命令的结果输出在当前宿主机下。此时,可以通过添加-d
参数来实现。下面举两个例子来说明一下。
如果不使用-d
参数运行容器。
MacBook-Pro:~ lucky$ docker run -d ubuntu:16.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
0ad690ee45c60c60ec82ae87d9f0d739ebca3541b01669df0f860b92960e3c0e
MacBook-Pro:~ lucky$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0ad690ee45c6 ubuntu:16.04 "/bin/sh -c 'while t…" 4 seconds ago Up 3 seconds peaceful_poincare
查看日志
MacBook-Pro:~ lucky$ docker logs 0ad690ee45c6
终止容器
可以使用docker container stop
来终止一个运行中的容器。此外,当 Docker 容器中指定的应用终结时,容器也自动终止。
例如对于上一章节中只启动了一个终端的容器,用户通过 exit 命令或 Ctrl+d 来退出终端时,所创建的容器立刻终止。终止状态的容器可以用docker container ls -a
命令看到。例如
MacBook-Pro:~ lucky$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ceb9464e4dbc ubuntu:16.04 "/bin/bash" 6 seconds ago Exited (0) 3 seconds ago awesome_payne MacBook-Pro:~ lucky$ docker start ceb9464e4dbc ceb9464e4dbc MacBook-Pro:~ lucky$ docker restart ceb9464e4dbc ceb9464e4dbc MacBook-Pro:~ lucky$ docker stop ceb9464e4dbc ceb9464e4dbc
进入容器
在使用-d
参数时,容器启动后会进入后台。某些时候需要进入容器进行操作:exec 命令 -i -t 参数。
只用-i
参数时,由于没有分配伪终端,界面没有我们熟悉的Linux
命令提示符,但命令执行结果仍然可以返回。 当-i -t
参数一起使用时,则可以看到我们熟悉的 Linux
命令提示符。
MacBook-Pro:~ lucky$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu 16.04 56bab49eef2e 9 days ago 123MB MacBook-Pro:~ lucky$ docker run -itd ubuntu:16.04 89da25e2991f80915be5db222b76702f2b365fa1f08c95899f4daf1071395cdf MacBook-Pro:~ lucky$ docker exec -it 89da2 /bin/bash root@89da25e2991f:/# ls bin dev home lib64 mnt proc run srv tmp var boot etc lib media opt root sbin sys usr
删除所有容器
列出所有的CONTAINER ID
MacBook-Pro:~ lucky$ docker ps -aq 547577bec57d e204bc186807 424b93a93827 e48fb20490c1
删除所有的容器
MacBook-Pro:~ lucky$ docker rm -f $(docker ps -qa) 547577bec57d e204bc186807 424b93a93827 e48fb20490c1
docker commit定制镜像
镜像是容器的基础,每次执行docker run
的时候都会指定哪个镜像作为容器运行的基础。在之前的例子中,我们所使用的都是来自于 Docker Hub 的镜像。直接使用这些镜像是可以满足一定的需求,而当这些镜像无法直接满足需求时,我们就需要定制这些镜像。接下来的几节就将讲解如何定制镜像。
回顾一下之前我们学到的知识,镜像是多层存储,每一层是在前一层的基础上进行的修改;而容器同样也是多层存储,是在以镜像为基础层,在其基础上加一层作为容器运行时的存储层。
现在让我们以定制一个 Web 服务器为例子,来讲解镜像是如何构建的。
MacBook-Pro:~ lucky$ docker run --name webserv -d -p 80:80 nginx Unable to find image 'nginx:latest' locally latest: Pulling from library/nginx 000eee12ec04: Pull complete eb22865337de: Pull complete bee5d581ef8b: Pull complete Digest: sha256:50cf965a6e08ec5784009d0fccb380fc479826b6e0e65684d9879170a9df8566 Status: Downloaded newer image for nginx:latest f47b7d3df98617cb4dc95be6438b531da1d538d28eff884a9fd44b2079e11d1b MacBook-Pro:~ lucky$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f47b7d3df986 nginx "nginx -g 'daemon of…" 48 seconds ago Up 47 seconds 0.0.0.0:80->80/tcp webserv 89da25e2991f ubuntu:16.04 "/bin/bash" 11 minutes ago Up 11 minutes nifty_banzai 0ad690ee45c6 ubuntu:16.04 "/bin/sh -c 'while t…" 19 minutes ago Up 19 minutes peaceful_poincare MacBook-Pro:~ lucky$
这条命令会用 nginx 镜像启动一个容器,命名为 webserver,并且映射了 80 端口,这样我们可以用浏览器去访问这个 nginx 服务器。
如果是在 Linux 本机运行的 Docker,或者如果使用的是 Docker for Mac、Docker for Windows,那么可以直接访问:http://localhost;如果使用的是 Docker Toolbox,或者是在虚拟机、云服务器上安装的 Docker,则需要将 localhost 换为虚拟机地址或者实际云服务器地址。
直接用浏览器访问的话,我们会看到默认的 Nginx 欢迎页面。
现在,假设我们非常不喜欢这个欢迎页面,我们希望改成欢迎 Docker 的文字,我们可以使用 docker exec命令进入容器,修改其内容。
MacBook-Pro:~ lucky$ docker exec -it webserv bash root@f47b7d3df986:/# echo '<h1>Hello, Docker!</h1>' > /usr/share/nginx/html/index.html root@f47b7d3df986:/# exit exit
我们以交互式终端方式进入 webserver 容器,并执行了 bash 命令,也就是获得一个可操作的 Shell。 然后,我们用<h1>Hello, Docker!</h1>
覆盖了 /usr/share/nginx/html/index.html的内容。 现在我们再刷新浏览器的话,会发现内容被改变了。
我们修改了容器的文件,也就是改动了容器的存储层。我们可以通过docker diff
命令看到具体的改动。
MacBook-Pro:~ lucky$ docker diff webserv C /root A /root/.bash_history C /usr C /usr/share C /usr/share/nginx C /usr/share/nginx/html C /usr/share/nginx/html/index.html C /var C /var/cache C /var/cache/nginx A /var/cache/nginx/scgi_temp A /var/cache/nginx/uwsgi_temp A /var/cache/nginx/client_temp A /var/cache/nginx/fastcgi_temp A /var/cache/nginx/proxy_temp C /run A /run/nginx.pid
现在我们定制好了变化,我们希望能将其保存下来形成镜像。
要知道,当我们运行一个容器的时候(如果不使用卷的话),我们做的任何文件修改都会被记录于容器存储层里。而 Docker 提供了一个docker commit
命令,可以将容器的存储层保存下来成为镜像。换句话说,就是在原有镜像的基础上,再叠加上容器的存储层,并构成新的镜像。以后我们运行这个新镜像的时候,就会拥有原有容器最后的文件变化。
其中--author
是指定修改的作者,而--message
则是记录本次修改的内容。这点和 git 版本控制相似,不过这里这些信息可以省略留空。
我们可以在docker image ls
中看到这个新定制的镜像:
MacBook-Pro:~ lucky$ docker commit --author "www.centoscn.cn" --message "修改了默认首页" webserv nginx:v2 sha256:c2200adf1a7e5ca93e425a1eff263a9a73037f67aeba523e49ebc6123d5c2232 MacBook-Pro:~ lucky$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE nginx v2 c2200adf1a7e 11 seconds ago 126MB ubuntu 16.04 56bab49eef2e 9 days ago 123MB nginx latest 231d40e811cd 13 days ago 126MB
查看镜像的修改内容
MacBook-Pro:~ lucky$ docker history nginx IMAGE CREATED CREATED BY SIZE COMMENT 231d40e811cd 13 days ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B <missing> 13 days ago /bin/sh -c #(nop) STOPSIGNAL SIGTERM 0B <missing> 13 days ago /bin/sh -c #(nop) EXPOSE 80 0B <missing> 13 days ago /bin/sh -c ln -sf /dev/stdout /var/log/nginx… 22B <missing> 13 days ago /bin/sh -c set -x && addgroup --system -… 57.1MB <missing> 13 days ago /bin/sh -c #(nop) ENV PKG_RELEASE=1~buster 0B <missing> 13 days ago /bin/sh -c #(nop) ENV NJS_VERSION=0.3.7 0B <missing> 13 days ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.17.6 0B <missing> 13 days ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B <missing> 13 days ago /bin/sh -c #(nop) CMD ["bash"] 0B <missing> 13 days ago /bin/sh -c #(nop) ADD file:bc8179c87c8dbb3d9… 69.2MB MacBook-Pro:~ lucky$ docker history nginx:v2 IMAGE CREATED CREATED BY SIZE COMMENT c2200adf1a7e 2 minutes ago nginx -g daemon off; 180B 修改了默认首页 231d40e811cd 13 days ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B <missing> 13 days ago /bin/sh -c #(nop) STOPSIGNAL SIGTERM 0B <missing> 13 days ago /bin/sh -c #(nop) EXPOSE 80 0B <missing> 13 days ago /bin/sh -c ln -sf /dev/stdout /var/log/nginx… 22B <missing> 13 days ago /bin/sh -c set -x && addgroup --system -… 57.1MB <missing> 13 days ago /bin/sh -c #(nop) ENV PKG_RELEASE=1~buster 0B <missing> 13 days ago /bin/sh -c #(nop) ENV NJS_VERSION=0.3.7 0B <missing> 13 days ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.17.6 0B <missing> 13 days ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B <missing> 13 days ago /bin/sh -c #(nop) CMD ["bash"] 0B <missing> 13 days ago /bin/sh -c #(nop) ADD file:bc8179c87c8dbb3d9… 69.2MB
启动刚才定制的镜像
MacBook-Pro:~ lucky$ docker run --name webserver2 -itd -p 8080:80 nginx:v2 760548d38d2a3556c488f3e8ce1217386d2b4b9957ca36e81fcc65d632acf0c1 MacBook-Pro:~ lucky$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 760548d38d2a nginx:v2 "nginx -g 'daemon of…" 6 seconds ago Up 4 seconds 0.0.0.0:8080->80/tcp webserver2 f47b7d3df986 nginx "nginx -g 'daemon of…" 27 minutes ago Up 27 minutes 0.0.0.0:80->80/tcp webserv 89da25e2991f ubuntu:16.04 "/bin/bash" 38 minutes ago Up 38 minutes nifty_banzai 0ad690ee45c6 ubuntu:16.04 "/bin/sh -c 'while t…" 46 minutes ago Up 46 minutes peaceful_poin
- 我的QQ
- QQ扫一扫
-
- 我的头条
- 头条扫一扫
-
评论