天天看点

容器的创建过程及docker常用命令整理

作者:技术怪圈

写在文章最前:

通篇文档比较长,建议收藏以便以后慢慢翻阅

文章里所有涉及的命令请勿在生产环境里做测试。

1、容器的创建过程

通信流程:

容器的创建过程及docker常用命令整理

通信过程

1.1 dockerd 通过 grpc 和 containerd 模块通信(runc)交换,dockerd 和 containerd通信的 socket 文件:

/run/containerd/containerd.sock           

1.2 containerd 在 dockerd 启动时被启动,然后 containerd 启动 grpc 请求监听,containerd 处理 grpc 请求,根据请求做相应动作。

/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock           

1.3 若是创建容器,containerd 拉起一个 container-shim 容器进程 , 并进行相应的创建操作。

1.4 container-shim 被拉起后,start/exec/create 拉起 runC 进程,通过 exit、control文件和 containerd 通信,通过父子进程关系和 SIGCHLD(信号)监控容器中进程状态。

1.5 在整个容器生命周期中,containerd 通过 epoll 监控容器文件,监控容器事件。

gRPC 是 Google 开发的一款高性能、开源和通用的 RPC 框架,支持众多语言客户端。

容器的创建过程及docker常用命令整理

gRPC

容器的生命周期

1.检查本地是否存在镜像,如果不存在即从远端仓库检索
2.利用镜像启动容器
3.分配一个文件系统,并在只读的镜像层外挂载一层可读写层
4.从宿主机的网桥接口中桥接一个虚拟接口到容器
5.从地址池配置一个IP地块给容器
6.执行用户指定的指令
7.执行完毕后容器终止           

2、docker管理常用的命令整理

2.1 创建第一个镜像

~]# docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
b8dfde127a29: Pull complete
Digest: sha256:7d91b69e04a9029b99f3585aaaccae2baa80bcf318f4a5d2165a9898cd2dc0a1
Status: Downloaded newer image for hello-world:latest

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/

 容器启动过程四个步骤
1. Docker客户端联系Docker服务端。
2. Docker服务端从Docker中心拉取“hello-world”映像。
3. Docker服务端(用新拉的镜像)创建了一个新的容器,该容器运行可执行文件(脚本),
生成您当前读取的输出。
4. Docker服务端将信息流推到Docker客户端,由客户端展示在你的终端。           

2.2 镜像操作

搜索docker镜像

~]# docker search alpine           

拉一个镜像

#
~]# docker pull docker.io/library/alpine
~]# docker pull alpine:3.14.2 #指定版本

Using default tag: latest
latest: Pulling from library/alpine
a0d0a0d46f8b: Pull complete
Digest: sha256:e1c082e3d3c45cccac829840a25941e679c25d438cc8412c2fa221cf1a824e6a
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest

~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
alpine        latest    14119a10abf4   2 days ago     5.6MB
hello-world   latest    d1165f221234   5 months ago   13.3kB
~]# docker image ls
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
alpine        latest    14119a10abf4   2 days ago     5.6MB
hello-world   latest    d1165f221234   5 months ago   13.3kB           

给镜像打tag(标签)

~]# docker tag 14119a10abf4 docker.io/sam202025/alpine:lastest

[root@localhost ~]# docker image ls
REPOSITORY         TAG       IMAGE ID       CREATED        SIZE
alpine             latest    14119a10abf4   2 days ago     5.6MB
sam202025/alpine   v3.14.2   14119a10abf4   2 days ago     5.6MB
hello-world        latest    d1165f221234   5 months ago   13.3kB
#IMAGE ID一样的话说明镜像是一样的 前面的tag只是一个指针 就像软链接           

将打好标的镜像推送到远程仓库

~]# docker push docker.io/sam202025/alpine           

镜像名称的结构

${registry_ name}/${repository. name}/${image. name}:${tag. name
                                                       
例如:
docker.io/library/alpine:3.10.1           

删除镜像

~]# docker rmi 14119a10abf4
Untagged: alpine:latest
Untagged: alpine@sha256:e1c082e3d3c45cccac829840a25941e679c25d438cc8412c2fa221cf1a824e6a
Deleted: sha256:14119a10abf4669e8cdbdff324a9f9605d99697215a0d21c360fe8dfa8471bab
Deleted: sha256:e2eb06d8af8218cfec8210147357a68b7e13f7c485b991c288c2d01dc228bb68
~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
hello-world   latest    d1165f221234   5 months ago   13.3kB           

上面的删除操作只是删除了本地的镜像,不会对远程仓库的镜像产生影响

~]# docker pull docker.io/sam202025/alpine           

2.3 容器操作

查看所有容器

~]# docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED          STATUS                      PORTS     NAMES
12aad23d764b   hello-world   "/hello"   56 minutes ago   Exited (0) 56 minutes ago             stoic_hopper           

启动容器

#docker run是日常用的最频繁用的命令之一,同样也是较为复杂的命令之一
#命令格式: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
#OPTIONS :选项
    #-i:表示启动-一个可交互的容器, 并持续打开标准输入
    #-t:表示使用终端关联到容器的标准输入输出上
    #-d:表示将容器放置后台运行
    #--rm:退出后即删除容器
    #--name:表示定义容器唯一名称
    #IMAGE:表示要运行的镜像
    #COMMAND:表示启动容器时要运行的命令*
    #ARG:参数           
#删除已exit的容器
~]# for i in `docker ps -a|grep -i exit|awk '{print $1}'`;do docker rm -f $i;done           

交互式启动

[root@alice ~]# docker run -it alpine:latest
/ #
/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
47: eth0@if48: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:18:26:02 brd ff:ff:ff:ff:ff:ff
    inet 172.24.38.2/24 brd 172.24.38.255 scope global eth0 # 之前/etc/docker/daemon.json写了网段地址
       valid_lft forever preferred_lft forever
~]#
[root@alice ~]# docker ps -a
CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                       PORTS               NAMES
facbbda54346        mmdghh/alpine:latest   "/bin/sh"           2 minutes ago       Exited (130) 6 seconds ago                       nostalgic_bartik
f5895a16fb3d        hello-world            "/hello"            18 minutes ago      Exited (0) 18 minutes ago                        hopeful_edison
~]#
这里退出之后容器就挂了 因为init为1的进程没有夯住 执行完就退出了           

非交互式启动容器

~]# docker run -d --name myalpine alpine /bin/sleep 300
~]# docker ps
CONTAINER ID   IMAGE     COMMAND            CREATED         STATUS         PORTS     NAMES
3838f137eaa6   alpine    "/bin/sleep 300"   3 seconds ago   Up 3 seconds             myalpine
#这里有进程夯住之后 容器就不会挂掉了           

在宿主机查看进程

~]# ps aux |grep sleep |grep -v grep
root      20435  0.0  0.0   1572   252 ?        Ss   14:34   0:00 /bin/sleep 300
#docker用了宿主机的内核 所以虽然是隔离的 但是在宿主机仍然可以查看到docker的进程 
而且有自己的pid           

进入容器

~]# docker exec -it myalpine /bin/sh  # 也可以使用容器的名称进入
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
30: eth0@if31: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
    link/ether 02:42:ac:2f:02:02 brd ff:ff:ff:ff:ff:ff
    inet 172.47.2.2/24 brd 172.47.2.255 scope global eth0
       valid_lft forever preferred_lft forever
/ #           

容器的启动/停止/重启

~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND            CREATED         STATUS         PORTS     NAMES
3838f137eaa6   alpine    "/bin/sleep 300"   8 minutes ago   Up 2 minutes             myalpine
#停止容器
  ~]# docker stop 3838f137eaa6
3838f137eaa6
~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND            CREATED         STATUS                        PORTS     NAMES
3838f137eaa6   alpine    "/bin/sleep 300"   8 minutes ago   Exited (137) 21 seconds ago             myalpine

 #启动容器 
  ~]# docker start 3838f137eaa6
3838f137eaa6
~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND            CREATED         STATUS         PORTS     NAMES
3838f137eaa6   alpine    "/bin/sleep 300"   9 minutes ago   Up 6 seconds             myalpine

  #重启容器
  ~]# docker restart 3838f137eaa6
3838f137eaa6
~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND            CREATED         STATUS         PORTS     NAMES
3838f137eaa6   alpine    "/bin/sleep 300"   9 minutes ago   Up 4 seconds             myalpine
~]# docker restart myalpine # 可以用名字也可以用ID
myalpine           

在宿主机和容器之间传输文件

#容器复制文件到宿主机
~]# docker cp  3838f137eaa6:/1.txt ./
[root@localhost ~]# cat 1.txt
hello-world
#宿主机复制文件到容器
[root@localhost ~]# docker cp 1.log 3838f137eaa6:/

~]#  docker exec -it myalpine /bin/sh
/ # cat 1.txt
hello-world
           

删除容器

~]# docker ps -a
CONTAINER ID   IMAGE         COMMAND            CREATED          STATUS                     PORTS     NAMES
f06ec287330d   hello-world   "/hello"           9 seconds ago    Exited (0) 9 seconds ago             practical_darwin
3838f137eaa6   alpine        "/bin/sleep 300"   23 minutes ago   Up 56 seconds                        myalpine
[root@localhost ~]# docker rm f06ec287330d
f06ec287330d
#正在运行的容器需要用-f 来强制删除
~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND            CREATED          STATUS         PORTS     NAMES
3838f137eaa6   alpine    "/bin/sleep 300"   24 minutes ago   Up 2 minutes             myalpine

#删除所有未在运行的容器
~]# docker rm `docker ps -a -q`
5d396bf4792c
1390ed275479
Error response from daemon: You cannot remove a running container 3838f137eaa6484ae8fd5e692d57b9c236bc28463d3074a931ae786a375ac6d8. Stop the container before attempting removal or force remove # 如果需要删除所有容器 包括正在进行的容器,加上-f即可(慎重)
~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND            CREATED          STATUS         PORTS     NAMES
3838f137eaa6   alpine    "/bin/sleep 300"   26 minutes ago   Up 4 minutes             myalpine

#批量删除所有容器:
~]# docker rm -f $(docker ps -a -q)           

交互式进入容器

~]# docker exec -it 3838f137eaa6 /bin/sh
/ # ls
1.txt  bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var


~]# docker run -it 14119a10abf4 /bin/sh
/ # ls
bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var
#写入到容器的文件并不会保存在镜像里           

-p保存到执行命令这一时刻的内容,之后更新的不会报错

~]#docker ps -a
CONTAINER ID   IMAGE          COMMAND            CREATED          STATUS                          PORTS     NAMES
3ff58b96c0aa   14119a10abf4   "/bin/sh"          3 minutes ago    Exited (0) About a minute ago             laughing_benz
3838f137eaa6   alpine         "/bin/sleep 300"   38 minutes ago   Exited (0) 2 minutes ago                  myalpine

~]# docker commit -p myalpine alpine:v_1.txt
sha256:3c5b072cbf49375a9436161c33102e4dbe671a1b51d2342bdf30fac9523687d0
[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
alpine        v_1.txt   3c5b072cbf49   17 seconds ago   5.77MB
alpine        latest    14119a10abf4   2 days ago       5.6MB
hello-world   latest    d1165f221234   5 months ago     13.3kB
[root@localhost ~]# docker run -it alpine:v_1.txt /bin/sh
/ # ls
1.txt  bin    dev    etc    home   lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var
/ # cat 1.txt
hello-world
           

导入导出镜像

导出: docker save image_name/image_id > xxx.tar

导入: docker load -i xxx.tar 或 docker load < xxx.tar

tip: 如果你导出的时候名称用了 : 记得导入的时候用 \ 转义

~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED         SIZE
alpine        v_1.txt   3c5b072cbf49   6 minutes ago   5.77MB
alpine        latest    14119a10abf4   2 days ago      5.6MB
hello-world   latest    d1165f221234   5 months ago    13.3kB
#导出镜象
~]# docker save 3c5b072cbf49 > alpine_v_1.txt.tar
~]# ls
1.log  1.txt  alpine_v_1.txt.tar

#删除镜像
~]# docker rmi -f alpine:v_1.txt
Untagged: alpine:v_1.txt
Deleted: sha256:3c5b072cbf49375a9436161c33102e4dbe671a1b51d2342bdf30fac9523687d0
[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
alpine        latest    14119a10abf4   2 days ago     5.6MB
hello-world   latest    d1165f221234   5 months ago   13.3kB

#导入镜像
~]# docker load < alpine_v_1.txt.tar
Loaded image ID: sha256:3c5b072cbf49375a9436161c33102e4dbe671a1b51d2342bdf30fac9523687d0
[root@localhost ~]# docker images
REPOSITORY    TAG       IMAGE ID       CREATED          SIZE
<none>        <none>    3c5b072cbf49   11 minutes ago   5.77MB
alpine        latest    14119a10abf4   2 days ago       5.6MB
hello-world   latest    d1165f221234   5 months ago     13.3kB

#给镜像打标签
~]# docker tag 3c5b072cbf49 docker.io/sam202025/alpine:v_1.txt
~]# docker images
REPOSITORY         TAG       IMAGE ID       CREATED          SIZE
sam202025/alpine   v_1.txt   3c5b072cbf49   12 minutes ago   5.77MB
alpine             latest    14119a10abf4   2 days ago       5.6MB
hello-world        latest    d1165f221234   5 months ago     13.3kB
~]# docker run -it docker.io/sam202025/alpine:v_1.txt /bin/sh
/ # cat 1.txt
hello-world           

查看容器日志

docker logs container_id/container_name  [-f]

~]# docker logs 6f89f5ef071a

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.
           

查看容器的详细信息

docker inspect  container_name/container_diargs           

端口映射

-p host_port:container_port           

实战案例1:端口映射

#摘取镜像
~]# docker pull nginx:1.12.2
1.12.2: Pulling from library/nginx
f2aa67a397c4: Pull complete
e3eaf3d87fe0: Pull complete
38cb13c1e4c9: Pull complete
Digest: sha256:72daaf46f11cc753c4eab981cbf869919bd1fee3d2170a2adeac12400f494728
Status: Downloaded newer image for nginx:1.12.2
docker.io/library/nginx:1.12.2

#查看镜像
[root@localhost ~]# docker images
REPOSITORY         TAG       IMAGE ID       CREATED          SIZE
sam202025/alpine   v_1.txt   3c5b072cbf49   36 minutes ago   5.77MB
alpine             latest    14119a10abf4   2 days ago       5.6MB
hello-world        latest    d1165f221234   5 months ago     13.3kB
nginx              1.12.2    4037a5562b03   3 years ago      108MB
[root@localhost ~]# docker images |grep nginx
nginx              1.12.2    4037a5562b03   3 years ago      108MB

[root@localhost ~]# docker run -d --name nginx -p 83:80 nginx:1.12.2   #-p指定端口
8ed5d901b884a4f2cc1fb8c4fed92481b27dc7407696a92dd6df092d68b7babf
[root@localhost ~]# docker ps -a
CONTAINER ID   IMAGE                      COMMAND                  CREATED             STATUS                        PORTS                               NAMES
8ed5d901b884   nginx:1.12.2               "nginx -g 'daemon of…"   7 seconds ago       Up 5 seconds                  0.0.0.0:83->80/tcp, :::83->80/tcp   nginx
6f89f5ef071a   hello-world                "/hello"                 9 minutes ago       Exited (0) 9 minutes ago
brave_


#测试端口
~]# curl 127.0.0.1:83
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
           

挂载目录

docker run -v容器外目录:容器内目录

实战案例2:验证把宿主机的目录挂到容器

#摘取镜像
~]# docker pull nginx:1.12.2
1.12.2: Pulling from library/nginx
f2aa67a397c4: Pull complete
e3eaf3d87fe0: Pull complete
38cb13c1e4c9: Pull complete
Digest: sha256:72daaf46f11cc753c4eab981cbf869919bd1fee3d2170a2adeac12400f494728
Status: Downloaded newer image for nginx:1.12.2

#查看摘取的镜像信息
~]# docker images |grep nginx
nginx               1.12.2              4037a5562b03        2 years ago         108MB

#后台运行容器
~]# docker run -d --name nginx -p 83:80 nginx:1.12.2
6ce9e4bb303b754a576d3bf587e0aaec7e3749a3d20f1e40f43c734b28196c67

#查看所有已运行的容器
~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
6ce9e4bb303b        nginx:1.12.2        "nginx -g 'daemon of…"   4 seconds ago       Up 3 seconds        0.0.0.0:83->80/tcp   nginx
~]#

#宿主机创建要挂载的目录
~]# mkdir html
~]# cd html/
html]# echo "test" > index.html

#运行容器并把目录挂载到容器 -v
html]# docker run -d --name nginx_with_index -p 84:80 -v /root/html:/usr/share/nginx/html nginx:1.12.2
acf79798ce19fdb6e584723d0ab1cc057508082466f6b9be92acc19eca737699

#查看所有已运行的容器
[root@alice html]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
acf79798ce19        nginx:1.12.2        "nginx -g 'daemon of…"   7 seconds ago       Up 5 seconds        0.0.0.0:84->80/tcp   nginx_with_index
6ce9e4bb303b        nginx:1.12.2        "nginx -g 'daemon of…"   6 minutes ago       Up 6 minutes        0.0.0.0:83->80/tcp   nginx

#进入容器里面验证
[root@alice html]# docker exec -it acf79798ce19 /bin/bash
root@acf79798ce19:/# ls /usr/share/nginx/html/
index.html           

查看挂载的详细信息

html]# docker inspect nginx_with_index |grep -A 9 'Mounts'
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/root/html",
                "Destination": "/usr/share/nginx/html",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
html]#           

传递环境变量

-e variate_name=variate_value           
~]# docker run --rm -e E_OPTS=qwert docker.io/mmdghh/alpine:latest printenv
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=62db172fe9da
E_OPTS=qwert
HOME=/root
~]# docker run --rm -e E_OPTS=qwert -e C_OPTS=12345 docker.io/mmdghh/alpine:latest printenv  #传递多个变量
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=3ac265a1cf85
E_OPTS=qwert
C_OPTS=12345
HOME=/root
~]#           

容器内下载软件

红帽系 yum

debian系 apt-get

alpine apt

进入容器并且下载

~]# docker exec -it nginx_with_baidu /bin/bash
root@acf79798ce19:/# curl
bash: curl: command not found
root@acf79798ce19:/# exit
~]# docker exec -it nginx_with_baidu /bin/bash
root@acf79798ce19:/# tee /etc/apt/sources.list << EOF
deb http://mirrors.163.com/debian/ jessie main non-free contrib
deb http://mirrors.163.com/debian/ jessie-updates main non-free contrib
EOF
root@acf79798ce19:/# apt-get update && apt-get install curl -y           

安装好后commit并且推送到仓库

~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                NAMES
acf79798ce19        nginx:1.12.2        "nginx -g 'daemon of…"   About an hour ago   Up About an hour    0.0.0.0:84->80/tcp   nginx_with_baidu
6ce9e4bb303b        nginx:1.12.2        "nginx -g 'daemon of…"   About an hour ago   Up About an hour    0.0.0.0:83->80/tcp   nginx
 
  ~]# docker commit -p acf79798ce19 mmdghh/nginx:curl
sha256:84b7a98f5ee209f0139febe7cac04a7edaaca7254ddf1c043e8ac779504204ba

  ~]# docker push docker.io/mmdghh/nginx:curl
The push refers to repository [docker.io/mmdghh/nginx]
bbadc5b62281: Pushed
4258832b2570: Mounted from library/nginx
683a28d1d7fd: Pushed
d626a8ad97a1: Mounted from library/nginx
curl: digest: sha256:f86f97bacf0ff37e3cc09f98dfb8153c486ee1e8bb9caad5046ed6aa58c43c50 size: 1160