docker创建容器后如何使用(容器的创建过程及docker常用命令整理)
docker创建容器后如何使用(容器的创建过程及docker常用命令整理)1.4 container-shim 被拉起后,start/exec/create 拉起 runC 进程,通过 exit、control文件和 containerd 通信,通过父子进程关系和 SIGCHLD(信号)监控容器中进程状态。/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock1.3 若是创建容器,containerd 拉起一个 container-shim 容器进程 并进行相应的创建操作。通信过程1.1 dockerd 通过 grpc 和 containerd 模块通信(runc)交换,dockerd 和 containerd通信的 socket 文件:/run/containerd/containerd.sock1.2 containerd 在 dockerd 启动时被启动,然后 con
写在文章最前:
通篇文档比较长,建议收藏以便以后慢慢翻阅
文章里所有涉及的命令请勿在生产环境里做测试。
1、容器的创建过程通信流程:
通信过程
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 框架,支持众多语言客户端。
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