Docker命令使用入门

一、安装Docker

以CentOS 7安装Docker18.06.3-ce为例。
卸载旧版本Docker

[root@master ~]# yum -y remove docker docker-common docker-selinux docker-engine

更新yum包

[root@master ~]# yum -y upgrade

添加docker-ce源

[root@master ~]# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装Docker

[root@master ~]# yum list docker-ce --showduplicates        # 列出所有可用的软件包
[root@master ~]# yum -y install docker-ce-18.06.3.ce-3.el7  # 安装指定版本

启动Docker

[root@master ~]# systemctl enable docker.service
[root@master ~]# systemctl start docker.service

验证

[root@master ~]# docker version
[root@master ~]# docker ps

异常处理:

安装完Docker启动时遇到了以下错误:

Error starting daemon:Error initializing network controller: list bridge addresses failed: no available network

解决办法:

[root@master ~]# ip link add name docker0 type bridge
[root@master ~]# ip addr add dev docker0 172.17.42.1/16

配置镜像加速器
这里使用了163的容器镜像加速器,使用加速器可以提升获取Docker官方镜像的速度。

[root@master ~]# tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["http://hub-mirror.c.163.com"]
}
EOF
[root@master ~]# systemctl daemon-reload
[root@master ~]# systemctl restart docker.service

二、基础知识

Docker
简单概括图中的内容,就是容器运行着由镜像定义的系统。镜像由一个或多个层加上一些Docker元数据组成。
一个Docker镜像是由文件和元数据组成的。镜像文件占用了大部分空间。因为每个容器提供的隔离性,它们必须拥有自己所需工具的副本,包括语言环境和库。元数据包含了环境变量、端口映射、卷等。同一个镜像可以运行多个容器。
容器是从镜像中创建的,继承了它们的文件系统,并使用它们的元数据来确定其启动配置。容器是相互隔离的,但可以配置进行彼此通信。容器在启动时会运行一个进程。在这个进程完成时,容器将停止。这个启动进程可以派生其他进程。文件的变更通过写时复制(copy-on-write)机制存储在容器中。基础镜像不会受容器影响。
层是文件变更的集合。每当一个运行中的容器需要写入一个文件时,它会通过将该项目复制到磁盘的一个新区域来记录这一修改。在执行Docker提交时,这块磁盘新区域将被冻结并记录为具有自身标识符的一个层。每个层都可以被多个运行中的容器共享,就像一个共享库可以在内存中被多个运行中的进程共享一样。
写时复制:现有一个父进程P1,在其虚拟地址空间上有:正文段、数据段、堆、栈。相应的,内核要为这四部分分配各自的物理块,即:正文段块、数据段块、堆块、栈块。用fork()函数为该进程创建一个子进程P2。在写时复制技术下,内核只为新生成的子进程创建虚拟空间结构,它们来复制父进程的虚拟空间结构,但是不为这些段分配物理内存,它们共享父进程的物理空间,当父子进程中有更改相应段的行为发生时,再为子进程相应的段分配物理空间。

三、构建一个Docker应用程序

以构建一个to-do应用程序为例。

3.1、编写dockerfile

dockerfile是包含一系列特定命令的文本文件:

# cat dockerfile 
FROM node
MAINTAINER  admin@example.com
RUN git clone -q https://github.com/docker-in-practice/todo.git
WORKDIR  todo
RUN npm install > /dev/null
EXPOSE  8000
CMD  ["npm","start"]
  • 使用FROM命令定义基础镜像;
  • MAINTAINER命令声明维护人员。这一行不是必需的,但最好有;
  • 使用RUN命令运行git命令克隆todoapp代码。Git是在基础node镜像中已经安装好的;
  • 使用WORKDIR移动到git命令克隆的新目录中。这不仅会改变构建环境中的目录,最后一条WORKDIR命令还决定了从所构建的镜像启动容器时用户所处的默认目录;
  • 使用RUN命令运行node包管理器的安装命令(npm),这将为应用程序设置依赖,并且将安装过程中输出的内容重定向到/dev/null中;
  • 使用EXPOSE指定从所构建的镜像启动容器时应该监听8000端口。
  • CMD命令告诉Docker在容器启动时将运行哪条命令。

3.2、构建Docker镜像

# docker build . -t todoapp:v1      # “.”指dockerfile所在的路径,这里用“.”表示当前目录
                                    #-t为镜像指定名称
Sending build context to Docker daemon  53.25kB
Step 1/7 : FROM node
latest: Pulling from library/node
……
Status: Downloaded newer image for node:latest
 ---> bd4dba13afd5                  #Dockerfile中的每个命令会创建一个新镜像,此处为新镜像的ID
Step 2/7 : MAINTAINER  admin@example.com
 ---> Running in a397b75b6cad
Removing intermediate container a397b75b6cad
 ---> 6bbab057a572
Step 3/7 : RUN git clone -q https://github.com/docker-in-practice/todo.git
 ---> Runni‘“”’ng in fbd818e76730
Removing intermediate container fbd818e76730
 ---> edbd90598f11
Step 4/7 : WORKDIR  todo
 ---> Running in 7792550b37fc
Removing intermediate container 7792550b37fc
 ---> b65105cc694d
Step 5/7 : RUN npm install > /dev/null
 ---> Running in 26210c1cc161
……
Removing intermediate container 26210c1cc161
 ---> a5819820aaae
Step 6/7 : EXPOSE  8000
 ---> Running in fc1f16b72459
Removing intermediate container fc1f16b72459
 ---> e711a9ae6159
Step 7/7 : CMD  ["npm","start"]
 ---> Running in 067aa33b3b82
Removing intermediate container 067aa33b3b82
 ---> ebcb87c16086
Successfully built ebcb87c16086     #此次构建的最终镜像ID
Successfully tagged todoapp:v1      #像“ebcb87c16086”这样的ID引用起来会很麻烦,所以在命令中通过“-t”选项为镜像指定了标签:“todoapp:v1”。

3.3、运行Docker容器

使用刚刚构建好的镜像运行一个容器:

# docker run -d -p 8000:8000 --name example1 todoapp:v1
  • -d选项:以后台程序的形式运行容器;
  • -p选项:将宿主机的8000端口映射到容器的8000端口上,前一个8000端口是宿主机上的端口;
  • --name:为容器指定唯一的名称;
  • “todoapp:v1”:使用的镜像。

如果容器正常运行,就可以通过http://localhost:8000来访问应用程序了。

3.4、查看容器的状态

使用docker ps命令查看正在运行的容器的状态:

# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
e1013207cff7        todoapp:v1          "docker-entrypoint.s…"   5 minutes ago       Up 5 minutes        0.0.0.0:8000->8000/tcp   example1

使用docker stop命令停止容器:

# docker stop example1

使用docker ps -a查看所有容器,包含已经停止运行的容器的状态:

# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
e1013207cff7        todoapp:v1          "docker-entrypoint.s…"   7 minutes ago       Exited (1) 9 seconds ago                       example1

使用docker start运行已经停止的容器:

# docker start example1

使用docker diff命令查看由镜像运行容器后的文件变化:

# docker diff example1
  • A:容器运行后增加的文件;
  • D:容器运行后删除的文件;
  • C:容器运行后有变更的文件。

四、管理容器

4.1、以交互方式运行一个容器

# docker run -t -i busybox /bin/sh
  • -t:分配一个终端;
  • -i:进入交互模式;
  • busybox:基础镜像的名称,是一个能保证系统运行的最精简的镜像;
  • /bin/sh:运行容器后启动一个bash。

4.2、以守护进程方式运行容器

docker run命令中使用-d选项,可以在后台运行一个Docker容器:

# docker run -d --name daemon busybox /bin/sh -c "while true;do echo 'hello' && sleep 1;done"

运行docker logs命令查看容器的输出:

# docker logs daemon
hello
……

强制删除正在运行的容器:

# docker rm -f daemon     #对于已经退出的容器,执行`docker rm`即可
daemon

4.3、退出容器时不停掉它

如果想在退出一个容器的交互会话时不停掉容器,可以先按下Ctrl+P然后再按Ctrl+Q

# docker run -t -i busybox /bin/sh
/ # 
# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
3d16f36f319d        busybox             "/bin/sh"           35 seconds ago      Up 35 seconds                           trusting_goldstine

4.4、退出容器后自动删除

运行容器时加上--rm参数,会在容器退出后自动删除该容器:

# docker run -t -i --rm --name example2 busybox /bin/sh
/ # exit
# docker ps -a | grep example2

4.5、进入正在运行的容器

首先在后台运行一个容器:

# docker run -d --name sleeper busybox sleep infinity

使用docker exec命令以交互方式进入到该容器:

# docker exec -t -i sleeper /bin/sh

4.6、容器重启策略

docker run命令的--restart选项允许用户应用一组容器终止时需要遵循的规则(即所谓“重启策略”):

  • no:容器退出时不重启,是默认策略;
  • always:容器退出时总是自动重启;
  • on-failure[:max-retry]:只在失败时重启,也可以指定尝试重启的次数。

如下的例子,将在容器退出时自动重启,并且在重启三次后退出:

# docker run -d --name example3 --restart=on-failure:3 busybox /bin/sh -c "sleep 30;exit 1"

4.7、为容器开放端口

通过-p选项将宿主机的12345端口映射到容器的12345端口上,前一个8000端口是宿主机上的端口:

# docker run -d -p 12345:12345 --name example4 busybox nc -l -p 12345

4.8、链接容器

假如host1容器运行着MySQL,其他容器可以通过--link连接MySQL。
--link选项用于链接容器,同时会设置容器的hosts文件

# docker run -d -p 3306:3306 --name host1 busybox nc -l -p 3306
# docker run --link host1:host1 --name host2 busybox ping host1 
PING host1 (172.17.0.5): 56 data bytes
64 bytes from 172.17.0.5: seq=0 ttl=64 time=0.170 ms

4.9、挂载数据卷

通过-v选项可以将宿主机中的文件挂载到容器中:

# mkdir test
# touch test/1.txt
# docker run --rm -v /root/test/:/test/ busybox /bin/sh -c "ls /test"
1.txt`

-v:是–volume的缩写,表示为容器指定一个外部的卷,告诉Docker将外部的/root/test/目录映射到容器的/test目录。如果外部目录和内部容器不存在均会被自动创建

4.10、数据容器

为了防止数据意外丢失,可以启动一个数据容器,让其它容器都来挂载该数据容器。
首先,启动一个数据容器:

# docker run -v /shared_data --name dc busybox touch /shared_data/somefile

其它容器通过--volumes-from挂载该数据容器:

# docker run --rm --volumes-from dc busybox /bin/sh -c "ls /shared_data" 
somefile

注意:数据容器并不需要运行,它只需要存在,在宿主机上运行过并且没有被删除。

4.11、获取容器详细信息

使用docker inspect查看和过滤容器的元数据:

# docker inspect example1

另外,通过--format选项可以获取指定信息。例如IP地址(正在运行的容器才能获取到IP地址):

# docker inspect --format={{.NetworkSettings.IPAddress}} sleeper
172.17.0.3

获取正在运行的容器的IP然后逐个ping:

# docker ps -q | xargs docker inspect --format={{.NetworkSettings.IPAddress}} | xargs -l1 ping -c1
  • docker ps -q:获取所有正在运行的容器的ID;
  • docker inspect:针对容器ID获取它们的IP;
  • xargs -l1:ping命令每次只能接受一个IP,所以给xargs传入一个额外的参数,告诉它对每个单独的行执行该命令。

4.12、干净地杀掉容器

命令行kill程序的默认工作方式是向指定的进程发送TERM信号(即信号值为15)。这个信号表示程序应该终止,但是不要强迫程序终止。当这个信号被处理时,大部分程序将会执行某种清理工作,但是该程序也可以执行其他操作,包括忽略该信号;
docker kill使用的是kill信号(即信号值是9),会强迫指定的程序终止。这使得程序没办法处理终止过程,意味着包括运行进程ID之类的文件可能会残留在文件系统中;
docker stop命令则像kill命令那样工作,发送的是一个TERM信号。

4.13、找出异常退出的容器

通常,正常退出的容器,退出状态码为0。其他的可以被认为是异常退出的容器:

# comm -3 <(docker ps -a -q --filter status=exited | sort) <(docker ps -a -q --filter exited=0 | sort)
  • bash里的"<(command)"语法称为进程替换。允许把一个命令的输出结果作为一个文件,传递给其他命令,在无法使用管道的时候很有用;
  • docker ps -a -q --filter status=exited | sort:找出所有已经退出的容器ID,并排序;
  • docker ps -a -q --filter exited=0 | sort:找出所有正常退出的容器,并排序;
  • comm -3:列出只在第一个文件而不在第二个文件中的行。

关于comm命令:

comm -12 file1 file2: Print only lines present in both file1 and file2;
comm -3 file1 file2:Print lines in file1 not in file2, and vice versa。

4.14、批量删除已经退出的容器

# docker ps -a -q --filter status=exited | xargs --no-run-if-empty docker rm
  • --filter根据条件过滤容器。命令根据退出状态;
  • xargs --no-run-if-empty:避免在前面的命令完全没有输出的情况下执行该命令

也可以根据4.13中的comm命令,找出异常退出的容器并删除。

五、创建Docker镜像的方式

5.1、使用Docker命令创建镜像

用已有的基础镜像运行一个容器,并在容器中做一些改动,构建自定义的镜像。
首先使用基础镜像运行一个容器,例如使用busybox镜像运行名称为“temp”的容器,并在其中创建/data/hello文件:

# docker run -ti --name temp busybox /bin/sh
/ # mkdir /data
/ # touch /data/hello
/ # exit

使用docker commit命令基于该容器构建名称为“mybusybox:v1”的镜像:

# docker commit temp mybusybox:v1
# docker images | grep mybusybox

使用自定义的镜像运行容器:

# docker run --rm mybusybox:v1 /bin/sh -c "ls /data/"
hello

5.2、使用dockerfile构建镜像

构建步骤参考步骤三中的内容。
除了3.1中用到的dockerfile命令,还有以下常见的命令:

  • ADD:将宿主机中的目录或文件添加到镜像中,并且会自动解压文件。如:bzip2、gzip、tar、xz等;
  • COPY:作用同ADD命令,但是不会自动解压缩文件;
  • ENTRYPOINT:入口点。总是在容器启动之后运行,如果用户在运行容器时传入一条命令,将会作为参数被传给入口点,然后取代在CMD部分定义的默认值。只能通过--entrypoint选项给docker run命令来重载入口点。
  • VOLUME:挂载数据卷。

5.3、关于构建镜像时的缓存

使用Dockerfile进行构建时,可以利用一个很有用的缓存功能:已经运行过的构建步骤只有在命令内容发生变化时才会被重新执行。
如果在重新构建时不希望使用缓存,可以使用--no-cache参数:

# docker build --no-cache .

5.4、导入、导出镜像

通过save导出镜像,load导入镜像:

# docker save todoapp:v1 -o todoapp.tar   #将镜像导出为文件
# docker tag todoapp:v1 todoapp:v2        #重命名已有的镜像,避免同名镜像
# docker load -i todoapp.tar              #将导出的文件导入

通过export导出容器,import将容器作为镜像导入。也是构建镜像的一种方法:

# docker export host1 -o host1.tar    #将运行中的容器导出
# docker import host1.tar host1:v1    #将容器导入为镜像 
或者简化为:
# docker export host1 | docker import - host1:v2

5.5、镜像构建历史

可以通过docker history查看镜像的构建历史:

# docker history todoapp:v1

这样的,其他用户可以指定任何一个构建过程中的分层运行一个容器,如果该分层里敏感信息,则将暴露给其他用户。
为了避免这种情况,可以通过docker export | docker import对镜像做扁平化处理:

# docker history host1:v1
IMAGE               CREATED             CREATED BY          SIZE                COMMENT
c8cda2e05870        14 seconds ago                          1.23MB              Imported from -
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值