docker因为轻量,易部署,广泛运用到微服务,devops等领域,作为一位合格程序员,能够熟练使用docker也是必备技能。本文将从实践角度,快速入门docker。
对于开发来说,git也是必备技能,如果你熟练使用git,那么docker实践起来会事半功倍,因为两者设计逻辑高度相似.
1 docker 中涉及的基本概念
1.1 镜像
镜像(image)是一个只读的模板,docker容器是通过镜像来创建的。
1.2 容器
容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
1.3 仓库
仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上, 仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。 国内的公开仓库包括 Docker Pool等,可以提 供大陆用户更稳定快速的访问。
2 docker 安装
ubuntu 上安装docker非常方便
sudo apt-get install -y docker.io
3 镜像操作
3.1 拉取镜像
sudo docker pull ubuntu
通过docker pull 可以拉取镜像,默认从docker hub 拉取tag为latest的镜像。 当拉取完成后,可以通过如下命令查看本地所有的镜像。
sudo docker image ls
3.2 运行容器
通过如下命令,可以运行制定的镜像
sudo docker run -t -i ubuntu:12.04 /bin/bash
其中 -t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i可以 理解交互式打开容器。
可以通过如下命令查看运行的容器
sudo docker container ls
3.3 通过既有镜像创建新的镜像
下面以ubuntu镜像安装emacs,创建包含emacs的ubuntu镜像为例来演示如何通过既有镜像创建新镜像。
3.3.1 首先启动ubuntu容器
sudo docker run -t -i ubuntu /bin/bash
3.3.2 在容器中安装emacs
root@ac7f51de4790:/# apt update root@ac7f51de4790:/# apt install emacs
3.3.3 退出容器
root@ac7f51de4790:/# exit
3.3.4 根据刚才运行的容器,提交,创建新镜像
wphome@wphome:~$ sudo docker commit -m"install emacs" -a "xxx" ac7f51de4790 ubuntu:v2 sha256:a297e2654f699b070cc8e73d99101853308d582de874865278143f60829b6ecb
3.3.5 查看创建的镜像
wphome@wphome:~$ sudo docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu v2 a297e2654f69 29 seconds ago 402MB ubuntu latest a8780b506fa4 4 weeks ago 77.8MB
3.3.6 尝试运行创建的镜像
wphome@wphome:~$ sudo docker run -t -i ubuntu:v2 /bin/bash root@2e3f4a13a6fe:/# emacs
3.4 修改docker镜像tag
比如刚才创建的镜像tag名称不合适,可以通过如下命令修改镜像。
wphome@wphome:~/3.person/1.personal-note/org-dir$ sudo docker tag ubuntu:v3 ubuntu:devl wphome@wphome:~/3.person/1.personal-note/org-dir$ sudo docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu devl 420358cdc6ec 3 minutes ago 402MB ubuntu v3 420358cdc6ec 3 minutes ago 402MB ubuntu latest a8780b506fa4 4 weeks ago 77.8MB
上面命令将tag为ubuntu:v3的镜像修改为ubuntu:devl.
3.5 上传新建的镜像到docker hub
3.5.1 在docker hub创建知己的账户
如果没有自己的docker hub账户,可以登录https://hub.docker.com,注册自己的账户。
3.5.2 本地登录
在本地登录docker hub账户。
wphome@wphome:~/3.person/1.personal-note/org-dir$ sudo docker login Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: *** Password: *** WARNING! Your password will be stored unencrypted in /root/.docker/config.json. ... Login Succeeded
3.5.3 提交docker镜像
wphome@wphome:~/3.person/1.personal-note/org-dir$ sudo docker push robin2003/ubuntu-emacs:v1 The push refers to repository [docker.io/robin2003/ubuntu-emacs] .... v1: digest: sha256:e6c3c8de8b01d6b22bfa85e7ca442298baec2e84eaaf45e01bb01791f64bd974 size: 954
如上命令,将会将本地robin2003/ubuntu-emacs:v1镜像提交到docker hub上。
3.6 重启已经退出的docker 容器
3.6.1 查看已经退出的容器
wphome@wphome:~/3.person/3.code/4.docker/1.docker-build$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0da3d79f1af9 ubunt-emacs:devl "bash" 18 seconds ago Exited (0) 12 seconds ago practical_ellis c4c9cf98331c robin2003/ubuntu-emacs:v1 "emacs" 26 minutes ago Exited (0) 26 minutes ago recursing_noyce
3.6.2 启动并attach到容器中
wphome@wphome:~/3.person/3.code/4.docker/1.docker-build$ sudo docker start -ai 0da3d79f1af9 root@0da3d79f1af9:/# emacs
也可以通过docker 容器名称启动。
3.7 移除docker镜像
sudo docker image rm -f 5b117edd0b76
-f后参数为container id.
3.8 指定名称运行docker容器
wphome@wphome:~/3.person/3.code/4.docker/1.docker-build$ sudo docker run --name emacs -v /home/wphome/.emacs.d:/.emacs.d -it ubunt-emacs:devl wphome@wphome:~/3.person/3.code/4.docker/1.docker-build$ sudo docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e57dce8f5c33 ubunt-emacs:devl "bash" 13 hours ago Exited (0) 13 hours ago emacs wphome@wphome:~/3.person/3.code/4.docker/1.docker-build$ sudo docker inspect -f "{{.Name}}" e57dce8f5c33 /emacs
–name 指定容器运行名称.
3.9 为docker 容器指定数据卷
由于容器中没法持久化,为使得容器能够持久化数据,可以在容器启动时候通过指定数据卷,来实现该功能。
wphome@wphome:~/3.person/3.code/4.docker/1.docker-build$ sudo docker run -v /home/wphome/.emacs.d:/home/root/.emacs.d -it ubunt-emacs:devl root@60213efbbd5c:/# cd /home/root/ root@60213efbbd5c:/home/root# ll total 12 drwxr-xr-x 3 root root 4096 Dec 3 14:07 ./ drwxr-xr-x 1 root root 4096 Dec 3 14:07 ../ drwxrwxr-x 15 1000 1000 4096 Dec 3 13:22 .emacs.d/
-v 指定本地emacs配置文件路径/home/wphome/.emacs.d映射到docker容器的/home/root/.emacs.d路径下.
3.10 通过docker file创建新镜像
Dockerfile 由一行行命令语句组成,并且支持以 # 开头的注释行。一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。 其中,一开始必须指明所基于的镜像名称,接下来推荐说明维护者信息。后面则是镜像操作指令,例如 RUN 指令, RUN 指令将对镜像执行跟随的命令。每运行一条 RUN 指令, 镜像添加新的一层,并提交。最后是 CMD 指令,来指定运行容器时的操作命令。
3.10.1 指令
- FROM
格式为 FROM <image> 或 FROM <image>:<tag> 。 第一条指令必须为 FROM 指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 FROM指令(每个镜像一次)。
- MAINTAINER
格式为 MAINTAINER <name> ,指定维护者信息。
- CMD
格式为 RUN <command> 或 RUN ["executable", "param1", "param2"] 。 前者将在 shell 终端中运行命令,即 /bin/sh -c ;后者则使用 exec 执行。指定使用其它终端可以通过 第二种方式实现,例如 RUN ["/bin/bash", "-c", "echo hello"] 。每条 RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 \ 来换行。
- RUN
支持三种格式: CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式; CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用; CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数; 指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。 如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。
- EXPOSE
格式为 EXPOSE <port> [<port>…] 。 告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动 分配一个端口转发到指定的端口。
- ENV
格式为 ENV <key> <value> 。 指定一个环境变量,会被后续 RUN 指令使用,并在容器运行时保持。
- ADD
格式为 ADD <src> <dest> 。 该命令将复制指定的 <src> 到容器中的 <dest> 。 其中 <src> 可以是Dockerfile所在目录的一个相对路 径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。
- COPY
格式为 COPY <src> <dest> 。 复制本地主机的 <src> (为 Dockerfile 所在目录的相对路径)到容器中的 <dest> 。 当使用本地目录为源目录时,推荐使用 COPY 。
- ENTRYPOINT
两种格式: ENTRYPOINT ["executable", "param1", "param2"] ENTRYPOINT command param1 param2 (shell中执行)。 配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。 每个 Dockerfile 中只能有一个 ENTRYPOINT ,当指定多个时,只有最后一个起效。
- VOLUME
格式为 VOLUME ["/data"] 。 创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
- USER
格式为 USER daemon 。 指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户. 当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例 如: RUN groupadd -r postgres && useradd -r -g postgres postgres 。要临时获取管理员权限可以 使用 gosu ,而不推荐 sudo 。
- WORKDIR
格式为 WORKDIR /path/to/workdir 。 为后续的 RUN 、 CMD 、 ENTRYPOINT 指令配置工作目录。 可以使用多个 WORKDIR 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如 WORKDIR /a WORKDIR b WORKDIR c RUN pwd 则最终路径为 /a/b/c 。
- ONBUILD
格式为 ONBUILD [INSTRUCTION] 。 配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。 例如,Dockerfile 使用如下的内容创建了镜像 image-A 。 […] ONBUILD ADD . /app/src ONBUILD RUN /usr/local/bin/python-build –dir /app/src […] 如果基于 image-A 创建新的镜像时,新的Dockerfile中使用 FROM image-A 指定基础镜像时,会自动执行 ONBUILD 指令内容,等价于在后面添加了两条指令。 FROM image-A #Automatically run the following ADD . /app/src RUN /usr/local/bin/python-build –dir /app/src 使用 ONBUILD 指令的镜像,推荐在标签中注明,例如 ruby:1.9-onbuild 。指令
3.10.2 通过docker file 创建 docker镜像
编写完成 Dockerfile 之后,可以通过 docker build 命令来创建镜像。基本的格式为 docker build [选项] 路径 ,该命令将读取指定路径下(包括子目录)的 Dockerfile,并将 该路径下所有内容发送给 Docker 服务端,由服务端来创建镜像。因此一般建议放置 Dockerfile 的目录为空目录。也可以通过 .dockerignore 文件(每一行添加一条匹配模式)来让 Docker 忽略路径下的目录和文 件。要指定镜像的标签信息,可以通过 -t 选项。
$ sudo docker build -t myrepo/myapp /tmp/test1/
3.11 docker实践
下面通过docker file来创建ubuntu中包含emacs的镜像,创建新用户emacs,将基本的emacs配置拷贝到镜像中,并且以emacs用户来运行镜像.
3.11.1 编写docker file
#This is a comment FROM ubuntu:latest MAINTAINER xxx <[email protected]> #install emacs RUN apt update RUN apt install emacs --assume-yes #add group RUN groupadd -r emacs && useradd -r -g emacs emacs #create dest folder RUN mkdir -p /home/emacs #put config to docker COPY emacs.d /home/emacs/.emacs.d #copy customer config COPY custom.el /home/emacs/.custom.el #change own&group RUN chown -R emacs:emacs /home/emacs #change mode RUN chmod -R 755 /home/emacs #switch user USER emacs
3.11.2 生成docker 镜像
wphome@wphome:~/3.person/3.code/4.docker/1.docker-build$ sudo docker build -t ubuntu-emacs:v4 ubuntu-emacs-folder/ Sending build context to Docker daemon 2.048kB
该命令创建docker 镜像,指定镜像标签为ubuntu:v4, docker file路径在ubuntu-emacs-folder.
3.11.3 查看新创建的镜像
wphome@wphome:~/3.person/3.code/4.docker/1.docker-build$ sudo docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE ubuntu-emacs v4 97f2804a77f6 About a minute ago 402MB ubuntu v2 a297e2654f69 24 minutes ago 402MB ubuntu latest a8780b506fa4 4 weeks ago 77.8MB
3.11.4 运行新创建的镜像
sudo docker run -it -v /home/wphome/5.project:/home/emacs/5.project --name emacs --rm ubuntu-emacs:v4 root@ec3ab4fb09d1:/# emacs
通过如上命令映射本地文件夹/home/wphome/5.project到容器/home/emacs/5.project,这样可以把源代码放到该路径下,当容器启动后就可以直接访问使用并且修改.
3.11.5 上传镜像
sudo docker push robin2003/ubuntu-emacs:v4
效果如下: