docker容器
Docker容器
1.Docker容器介绍
镜像是静态的,将镜像运行起来就是容器,所以说容器是动态的。镜像只会占用磁盘,但是容器会占用cpu,内存和网络。
镜像的英文:image
容器的英文:container
注意:你不能将容器理解成一个操作系统,因为容器本身并不包含内核,没有内核的东西自然不能称为操作系统。
2.运行容器
1. 一次性运行容器
#docker run就是我们要运行容器时候的命令
[root@localhost ~]# docker run
[root@localhost ~]# docker container run
#早期就是用docker run来运行一个容器,但是在Docker后期版本对命令行进行更加明显的使用方法,docker image …就表示操作docker镜像,docker container …就表示操作容器
#docker run或者docker container run并不会直接运行一个容器,因为你缺少了运行容器所必须的条件。
#运行第一个容器
[root@localhost ~]# docker run centos
#需要注意的是如果docker run 后面指定的镜像没有加tag,那么默认就会运行tag为latest的镜像。
#查看运行的容器命令为docker ps
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#我们通过docker ps命令并没有查看到我们之前运行的基于centos:latest的容器。原因是什么呢?原因其实非常简单,容器已经运行完毕了,运行完就自动退出了。我们可以使用docker ps -a查看所有的容器(包括运行结束退出的容器也可以查看到)
[root@localhost ~]# docker ps -a
2.交互式运行容器
#-i就表示交互的意思
#-t就表示tty,表示为容器开启一个终端
[root@localhost ~]# docker run -i -t centos
#我们通过pwd和ls命令查看到了,这个容器并没有/boot目录,原因也很好理解,因为容器不是操作系统,所以不需要引导,也自然就没有内核存放的位置。
[root@80e53ca247b4 /]# pwd
/
[root@80e53ca247b4 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin
srv sys tmp usr var
#容器内部的第一个进程/bin/bash
[root@80e53ca247b4 /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 12132 3368 pts/0 Ss 13:24 0:00 /bin/bash
root 25 0.0 0.3 44636 3416 pts/0 R+ 13:28 0:00 ps aux
[root@80e53ca247b4 /]# exit
exit
#容器所在主机的第一个进程/usr/lib/systemd/systemd
[root@localhost ~]# ps aux
#由于我们在容器中使用exit命令退出了,就相当于退出了/bin/bash,也就意味着这个容器中唯一的进程被退出了, 所以容器自然而然的就退出了。
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost ~]# docker ps -a
#如果你使用-i -t参数以交互式的形式运行了容器,那么你可以使用ctrl+p+q(按住ctrl,再按p,p松手,再按
q)临时的退出容器,这个容器就并没有真正的被关闭。
[root@localhost ~]# docker run -i -t centos
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
5b4a0e771011 centos “/bin/bash” About a minute ago Up About a minute
heuristic_carson
80e53ca247b4 centos “/bin/bash” 8 minutes ago Exited (0) 4 minutes ago
modest_bhaskara
0caf099391e7 centos “/bin/bash” 14 minutes ago Exited (0) 14 minutes ago
stoic_ellis
#当临时的退出容器,并不是exit退出的时候,可以使用docker attach命令,再回到容器
[root@localhost ~]# docker attach 5b4a0e771011
[root@5b4a0e771011 /]# read escape sequence
[root@localhost ~]# docker attach 5b4a0e771011
[root@5b4a0e771011 /]# read escape sequence
[root@localhost ~]# docker attach 5b4a0e771011
[root@5b4a0e771011 /]# read escape sequence
#-d参数表示daemon的意思,表示将容器以守护进程的形式运行,说白了就是在后台运行。
[root@localhost ~]# docker run -d centos
41db22bcd9ed78fb9aba7401c766c5a6ff378f050af14f1fdbdf216d82e814f2
#那为什么在后台运行之后也是直接退出了呢?运行一次在前台退出和在后台退出是一样的。就好比运行一个ls命令一样,不管你是在前台运行还是在后台运行,都是运行完之后就退出。
[root@localhost ~]# docker ps -a
#如何让一个容器在运行之后不退出呢?我们需要增加一个-t参数,-t参数的意思是开启一个终端。docker run “image” “command”后面的command会替代image构建的最后一个命令。
[root@localhost ~]# docker run -d centos /bin/bash
79392e4ab5b18dd5041f16e0ecf8507cc57285a669bf4a6a8b826f5f1bbe3a4a
[root@localhost ~]# docker ps -a
[root@localhost ~]# docker run -dt centos /bin/bash
1facba8577aee22a061f6115d79d58faa318b210813427368ad0a2a7d22885c0
[root@localhost ~]# docker ps -a
#强烈不建议使用docker attach命令进入在后台运行的容器,建议使用docker exec加上对应参数进入后台运行的容器。
[root@localhost ~]# docker ps
#docker exec表示容器的执行-i -t和docker run的参数是一样的 1facba8577ae表示的是容器的ID,bash表示以bash命令运行这个容器。
[root@localhost ~]# docker exec -it 1facba8577ae bash
[root@1facba8577ae /]# ps aux
[root@1facba8577ae /]# exit
exit
[root@localhost ~]# docker ps
#因为你看上面的进程PID为1的进程为/bin/bash就是我在用docker run运行起来容器的那个进程,还有一个PID为15的bash进程,是我用docker exec运行的进程,所以我使用exit并不是退出/bin/bash,而是退出bash,所以由于容器里面的PID为1的进程/bin/bash还在,所以我exit之后没有退出容器,只是退出了容器里面的一个bash而已。
[root@1facba8577ae /]# ps aux
[root@1facba8577ae /]# echo $$
30
[root@1facba8577ae /]# exit
exit
[root@localhost ~]# docker run -dt centos /bin/sh
41f5f33fb20be88015410ec7fbaa9406f82bdde210ea6b1ac06c1bef250a8449
[root@localhost ~]# docker ps
[root@localhost ~]# docker exec -it 41f5f33fb20b /bin/sh
sh-4.4# ps aux
[root@localhost ~]# docker run -dt centos /bin/sh
5bd5c48a9b21d00c08b306ba62b5ae15d6db31ff97affc8ffbf389e361036431
[root@localhost ~]# docker exec -it 5bd5c48a9b /bin/bash
[root@5bd5c48a9b21 /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.3 0.3 12028 3096 pts/0 Ss+ 13:53 0:00 /bin/sh
root 7 1.0 0.3 12028 3256 pts/1 Ss 13:53 0:00 /bin/bash
root 21 0.0 0.3 44636 3424 pts/1 R+ 13:53 0:00 ps aux
[root@5bd5c48a9b21 /]# exit
exit
3.容器的生命周期管理
1.容器的启动
docker run
docker container run
2.容器的停止
[root@localhost ~]# docker stop 5bd5c48a9b21
5bd5c48a9b21
[root@localhost ~]# docker ps -a
[root@localhost ~]# docker start 5bd5c48a9b21
5bd5c48a9b21
[root@localhost ~]# docker ps -a
#没有加-d参数的容器,即使我们将它手工启动,也不会让他持续性运行
[root@localhost ~]# docker start 0caf099391e7
0caf099391e7
[root@localhost ~]# docker ps -a
#只有以后台的形式运行的容器才有生命周期管理的意义
#Exited后面有一个数字,数字代表着容器结束时候的返回值,返回值是0表示容器是正常结束的,返回值非0表示容器是非正常结束的。
#docker kill是强行干掉一个容器,docker stop是正常关闭一个容器
[root@localhost ~]# docker kill 5b4a0e771011
5b4a0e771011
[root@localhost ~]# docker ps -a
3.容器的重启
[root@localhost ~]# docker restart 5b4a0e771011
5b4a0e771011
[root@localhost ~]# docker ps -a
4.容器的删除
#默认情况下只能删除停止的容器,运行的容器删除会报错,但是也可以使用-f参数强行删除运行的容器(强烈不建议)
[root@localhost ~]# docker container rm 0caf099391e7
0caf099391e7
[root@localhost ~]# docker container rm 5b4a0e771011
Error response from daemon: You cannot remove a running container
5b4a0e7710112143b33a738b85a0f335da9ed6ad2047e69af039c67824b99fd7. Stop the container
before attempting removal or force remove
[root@localhost ~]# docker container rm 5b4a0e771011 -f
5b4a0e771011
[root@localhost ~]# docker ps -a
#容器查看的技巧
- q参数表示只查看容器的ID
[root@localhost ~]# docker ps -q
5bd5c48a9b21
41f5f33fb20b
1facba8577ae
#docker ps -qa就是查看所有运行的或者终止的容器的ID
[root@localhost ~]# docker ps -qa
5bd5c48a9b21
41f5f33fb20b
1facba8577ae
79392e4ab5b1
41db22bcd9ed
80e53ca247b4
#强行删除所有容器(仅限于lab环境操作)
[root@localhost ~]# docker rm -f
docker ps -qa
5bd5c48a9b21
41f5f33fb20b
1facba8577ae
79392e4ab5b1
41db22bcd9ed
80e53ca247b4
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
删除所有已停用的容器
sudo docker rm
docker ps -a|grep Exited|awk '{print $1}'
4.查看容器信息
1.查看容器log
docker logs
[root@localhost ~]# docker run -dt –name web nginx
[root@localhost ~]# docker logs web
2.查看容器进程信息
#一般情况你可以进入到容器内部使用ps命令查看容器的进程信息,但并不是所有的容器都支持这么操作
[root@localhost ~]# docker exec -it centos-test bash
[root@d3f4e13bca0a /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.3 12028 3136 pts/0 Ss+ 02:08 0:00 /bin/bash
root 15 1.0 0.3 12028 3328 pts/1 Ss 02:11 0:00 bash
root 29 0.0 0.3 44636 3396 pts/1 R+ 02:11 0:00 ps aux
[root@localhost ~]# docker exec -it web bash
root@cf839d63840e:/# ps aux
bash: ps: command not found
root@cf839d63840e:/# top
bash: top: command not found
root@cf839d63840e:/# exit
exit
[root@localhost ~]# docker top web
UID PID PPID C STIME
TTY TIME CMD
root 2025 2005 0 10:09
pts/0 00:00:00 nginx: master process nginx -g
daemon off;
101 2077 2025 0 10:09
pts/0 00:00:00 nginx: worker process
3.查看容器内部细节
[root@localhost ~]# docker inspect web
这命令显示了这个容器的所有信息,返回的是一个json格式。
4.容器和主机间的文件拷贝
#将ubuntu-latest.tar拷贝到centos-test容器的根目录下
[root@localhost ~]# docker cp ./ubuntu-latest.tar centos-test:/
[root@localhost ~]# rm -rf ubuntu-latest.tar
[root@localhost ~]# docker cp centos-test:/ubuntu-latest.tar .
[root@localhost ~]# ls anaconda-ks.cfg ubuntu-latest.tar
5.Docker容器网络
当你使用容器时(以docker为例),容器的通信就变得至关重要。要解决容器的通信问题,必须具备一定的网络基础。Docker有4种网络模式,只有两种是常用的。这4种网络模式分别为bridge,host,none,container。常用的是host模式和bridge模式。
1.Docker的bridge网络模式
bridge网络模式会为每个容器分配IP地址。分配的IP地址从何而来呢?
[root@localhost ~]# ip a show docker0
[root@localhost ~]# nmcli device status
[root@localhost ~]# nmcli con show
[root@localhost ~]# nmcli connection show docker0 | grep ‘connection.type’
在该模式中,Docker进程创建了一个以太网桥docker0,这个以太网桥你可以理解成一个交换机,新建的容器默认会自动的桥接到这个网桥上。
#从RHEL8或者CentOS8开始已经默认不使用brctl命令查看网桥和网卡的关系了,代替的是bridge命令
[root@localhost ~]# docker ps
[root@localhost ~]# bridge link
[root@localhost ~]# ip a show veth1e09d15
[root@localhost ~]# ip a show veth73a6134
[root@localhost ~]# docker exec -it centos-test ip a
[root@localhost ~]# docker inspect web | grep -i macaddress
#可以看到在host上看到的两个桥接到docker网桥的网卡和容器内部看到的网卡并不是一个,因为mac地址不同。
#在host上看到的网卡和容器内部的网卡其实叫做veth pair
#veth pair其实是一对虚拟网卡,这一对虚拟网卡就像”网线”一样。具体内容如下图所示(下图的网络应该是172.17.0.0/16,手残输错了)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w1MGtwan-1681109547000)(docker%E5%AE%B9%E5%99%A8%204ef0e88973f042c2b506721cd01afda1/Untitled.png)]
[root@localhost ~]# docker inspect web | grep -i ipaddress
“SecondaryIPAddresses”: null,
“IPAddress”: “172.17.0.3”,
“IPAddress”: “172.17.0.3”,
[root@localhost ~]# docker inspect centos-test | grep -i ipaddress
“SecondaryIPAddresses”: null,
“IPAddress”: “172.17.0.2”,
“IPAddress”: “172.17.0.2”,
[root@localhost ~]# docker exec -it centos-test bash
[root@d3f4e13bca0a /]# ping -c 1
www.baidu.com
[root@d3f4e13bca0a /]# exit
[root@localhost ~]# iptables -L -t nat -n
#查看docker的网络
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
3c53ba4dfbef bridge bridge local
23e291bc1ec1 host host local
bab83bfc1452 none null local
#连接到bridge的容器都在bridge的网桥中被记录了
[root@localhost ~]# docker network inspect bridge
总结:Docker的bridge网络模式的底层采用的是Linux bridge,veth pair,iptables
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-e48eu2xj-1681109547004)(docker%E5%AE%B9%E5%99%A8%204ef0e88973f042c2b506721cd01afda1/Untitled%201.png)]
2.Docker的Host网络模式
Docker的Host网络模式其实就是容器和host共享一个网络。说白了就是容器完全的使用容器所在主机上的网络,并不对容器网络做任何隔离。
[root@localhost ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
3c53ba4dfbef bridge bridge local
23e291bc1ec1 host host local
bab83bfc1452 none null local
#使用–network指定容器运行时的网络模式
[root@localhost ~]# docker run -dt –name centos1 –network host centos
c278f5ae3a05b4a014b4301a838d89217a746f806e2486d4a5a3ec2483109715
[root@localhost ~]# docker ps
[root@localhost ~]# docker exec -it centos1 bash
[root@localhost /]# ip a
[root@localhost /]# ps aux
#采用host网络模式的Docker容器,可以直接使用宿主机的IP地址与外界通信,若是宿主机的eth0是一个公有IP,那么容器也会共享这个公有IP,同时容器服务的端口也可以使用宿主机的端口,无需进行SNAT的转换。带来的好处就是性能好,带来的劣势就是容器的网络缺少了隔离性,增加了风险,并且由于所有容器和宿主机共享同一个网络,网络资源也受到了限制。
[root@localhost ~]# docker inspect centos1 | grep -i network
[root@localhost ~]# docker network inspect host
[root@localhost ~]# docker ps
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kx24ygkd-1681109547005)(docker%E5%AE%B9%E5%99%A8%204ef0e88973f042c2b506721cd01afda1/Untitled%202.png)]
3.Docker的none网络模式
none的网络模式是Docker容器中最容易理解的一种网络模式,因为如果使用了none作为Docker容器的网络模式,那么就意味着容器会禁用网络功能,只会留一个环回接口。我们同样可以使用–network参数在容器运行的时候指定none类型的网络。
[root@localhost ~]# docker run -dt –name centos2 –network none centos
b94ecd6d39091bc339295ca944acbd7879d58bf531bd7b6a6dfc0660e018d450
[root@localhost ~]# docker exec -it centos2 ip a show
none模式的好处就是Docker容器几乎不参与网络的配置,那么如果你想针对这个容器配置网络,就需要第三方的driver。none模式的优点就是让你容器的网络设置更加的开放,不再局限于Docker自带的网络模式。
[root@localhost ~]# docker network inspect none
[root@localhost ~]# docker inspect centos2 | grep -i network
4.Docker的container网络模式
[root@localhost ~]# docker run -dt –network container:centos1 –name centos3 centos
container类型的网络表明指定一个容器,和那个容器共享一个网络
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZkMCW9Ky-1681109547006)(docker%E5%AE%B9%E5%99%A8%204ef0e88973f042c2b506721cd01afda1/Untitled%203.png)]
5.Docker自定义网络和网络连接
通过我们之前的学习,我们知道了,Docker容器网络的几种常见的模式。默认情况下docker容器会使用bridge类型的网络。
[root@localhost ~]# docker network create gzy-network
[root@localhost ~]# ip a show
[root@localhost ~]# docker run -dt –network gzy-network –name gzy-centos1 centos
[root@localhost ~]# docker run -dt –network gzy-network –name gzy-centos2 centos
[root@localhost ~]# docker exec -it gzy-centos1 ip a
[root@localhost ~]# docker exec -it gzy-centos2 ip a
[root@localhost ~]# docker network disconnect gzy-network gzy-centos1
[root@localhost ~]# docker network disconnect gzy-network gzy-centos2
[root@localhost ~]# docker exec -it gzy-centos1 ip a
[root@localhost ~]# docker exec -it gzy-centos2 ip a
[root@localhost ~]# docker network connect gzy-network gzy-centos1
[root@localhost ~]# docker network connect gzy-network gzy-centos2
[root@localhost ~]# docker exec -it gzy-centos1 ip a
[root@localhost ~]# docker exec -it gzy-centos2 ip a
[root@localhost ~]# docker network connect bridge gzy-centos1
[root@localhost ~]# docker exec -it gzy-centos1 ip a
#如果你想删除一个网络,那么必须要先将这个网络中的容器断连,全部断连之后,你才能删除这个网络
[root@localhost ~]# docker network disconnect gzy-network gzy-centos1
[root@localhost ~]# docker network disconnect gzy-network gzy-centos2
[root@localhost ~]# docker network rm gzy-network
gzy-network
[root@localhost ~]# docker network ls
6.Docker容器间网络通信
Docker网络设置的目的无非就是两个,第一个要保证容器间的通信,第二要保证外部能够访问到我们的容器承载的业务。
比如说我们有一些复杂的应用,要部署在不同的容器中,那么我们为了让着个复杂的应用能够完美运行,我们一般都要求不同容器的端口实现通信。
[root@localhost ~]# docker rm -f
docker ps -qa
[root@localhost ~]# docker ps -a
想实现容器之间的通信,有两种方法,第一种就是将容器放到同一个bridge中,第二种就是将容器都设置为host的网络模式,让容器和宿主机共享一个网络。
[root@localhost ~]# docker run -dt –name b-centos1 centos
cc57dbcc0497e394dd65f00ff8e9e507f641b6df316be92c1b80438d1ddee5ed
[root@localhost ~]# docker run -dt –name b-centos2 centos
5c3995b00ed93d56a0f223d8d2976c16041d6983eadc18681ec956c962f51a0d
[root@localhost ~]# docker exec -it b-centos1 ip a
[root@localhost ~]# docker exec -it b-centos2 ip a
[root@localhost ~]# docker exec -it b-centos2 ping -c 1 172.17.0.2
7.Docker容器被外部访问
Docker容器被外部访问一般基于两种网络模式,第一种是bridge,第二种是Host。
如果是bridge模式则需要通过DNAT的方法让我们的Docker容器被访问到如果是Host模式,则我们的Docker容器可以直接被访问到
[root@localhost ~]# docker run -dt –name gzy-web1 nginx
a8377054e8eadbfbc248b40a769a426c4c8db2bbac2145611a9be9af64b46aa9
[root@localhost ~]# docker ps
[root@localhost ~]# docker inspect gzy-web1 | grep -i ip
[root@localhost ~]# ping 172.17.0.4
[root@localhost ~]# curl 172.17.0.4:80
#上面的情况默认外部是访问不到nginx容器的,因为nginx容器所获得的地址是docker网桥内部的地址。
[root@localhost ~]# docker run -dt –name gzy-web2 -p 8080:80 nginx
[root@localhost ~]# docker ps
- p参数表示端口映射,-p 8080:80的意思是将宿主机的8080端口映射到容器的80端口
[root@localhost ~]# netstat -tunlp
[root@localhost ~]# iptables -L -t nat -n
[root@localhost ~]# curl localhost:8080
[root@localhost ~]# docker inspect gzy-web2 | grep -i NetworkSettings -A 10
如果容器的网络模式是host,那就简单了,由于容器会和host共享一个网络,那么容器曝露的端口将会被直接访问到
root@localhost ~]# docker run -dt –network host –name gzy-web3 nginx
[root@localhost ~]# docker ps
[root@localhost ~]# netstat -tunlp
6.Docker容器的持久化存储
1.Docker镜像的分层
[root@localhost ~]# docker rm -f
docker ps -qa
[root@localhost ~]# df -Th
[root@localhost ~]# docker run -dt centos
[root@localhost ~]# df -Th
[root@localhost ~]# docker ps -a
[root@localhost ~]# docker exec -it eb34cd7c5ac7 bash
[root@eb34cd7c5ac7 /]# ls
[root@eb34cd7c5ac7 /]# pwd
/
[root@eb34cd7c5ac7 /]# touch gzy
[root@eb34cd7c5ac7 /]# ls
[root@eb34cd7c5ac7 /]# exit
exit
[root@localhost ~]# df -Th
[root@localhost ~]# cd
[root@localhost merged]# ls
[root@localhost merged]# touch gzy1
[root@localhost merged]# docker exec -it eb34cd7c5ac7 ls
[root@localhost ~]# docker inspect eb34cd7c5ac7 | grep -i merge
Docker容器和Docker镜像的关系。
Docker镜像运行之后就是Docker容器。(通俗的解释)
基于Docker镜像挂载一个可读可写的文件系统,这个文件系统就是Docker容器的根分区。有了根分区,我们才能认为Docker容器像一个操作系统,可以运行。
Docker镜像本身是没有写权限的。基于Docker镜像之上挂载一个可读可写的文件系统就可以当这个文件系统是一个Docker容器的文件系统。
也就是说我们针对Docker容器的操作,其实是我们在可读可写的文件系统上操作,而不是操作Docker容器底层的镜像。因为Docker镜像是不具备写权限的。所以无论你在Docker容器内做任何操作都不会影响到Docker镜像。
为何Docker容器的存储是非持久化的?
因为Docker容器的文件系统是即用即删的。也就意味着,当你的Docker容器被删除之后,你挂载的Docker文件系统也会被删除,那么你在Docker容器中做的任何操作,都会随着Docker容器的文件系统删除而删除。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-99iDRMzR-1681109547007)(docker%E5%AE%B9%E5%99%A8%204ef0e88973f042c2b506721cd01afda1/Untitled%204.png)]
2.Docker容器使数据卷Volume
#如果想让容器实现持久化存储,那么可以使用data volume来实现。data volume叫做数据卷,我们可以将数据库挂载到容器当中,进而让存储在数据卷中的数据不会随着容器的删除而删除。
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
#默认情况下,没有任何的volume
[root@localhost ~]# ls /var/lib/docker/volumes/
backingFsBlockDev metadata.db
#/var/lib/docker/volume是存储本地volume的默认路径,所以说我们创建的volume默认都存放在这个位置
[root@localhost ~]# docker volume create gzy1
gzy1
[root@localhost ~]# ls /var/lib/docker/volumes/
backingFsBlockDev gzy1 metadata.db
[root@localhost ~]# ls /var/lib/docker/volumes/gzy1/
_data
[root@localhost ~]# ls /var/lib/docker/volumes/gzy1/_data/
[root@localhost ~]#
[root@localhost ~]# df -Th /var/lib/docker/volumes/gzy1/_data/
[root@localhost ~]# docker run -dt –name goudan1 -v gzy1:/gzy1 centos
d59160ad9fee05f28f2c516473f90de634d8cee209e75143ebf644b37d3fa667
[root@localhost ~]# docker exec -it goudan1 bash
[root@d59160ad9fee /]# ls
[root@d59160ad9fee /]# df -Th
[root@d59160ad9fee /]# touch /gzy1/glshs
[root@d59160ad9fee /]# exit
exit
[root@localhost ~]# find / -name glshs
/var/lib/docker/volumes/gzy1/_data/glshs
#通过上面的操作,我们可以看到,在容器的/gzy1目录下创建的文件都会被映射
到/var/lib/docker/volumes/gzy1/_data这个目录中。
[root@localhost ~]# ls /var/lib/docker/volumes/gzy1/_data/
glshs
[root@localhost _data]# pwd
/var/lib/docker/volumes/gzy1/_data
[root@localhost _data]# touch glshq
[root@localhost _data]# ls
glshq glshs
[root@localhost _data]# docker exec -it goudan1 bash
[root@d59160ad9fee /]# ls /gzy1/
glshq glshs
[root@localhost ~]# docker rm -f goudan1
goudan1
[root@localhost ~]# ls /var/lib/docker/volumes/gzy1/_data/
[root@localhost ~]# docker run -dt –name goudan1 -v gzy1:/gzy1 centos
8663d3807a5bd6654586f0e7d8a6b2cd05c8cc1dfd0b1fe8e6b9689d9fee5df5
[root@localhost ~]# docker exec -it goudan1 bash
[root@8663d3807a5b /]# ls /gzy1/
[root@localhost ~]# docker inspect goudan1 | grep gzy1 -A 5 -B 5
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local gzy1
#我们之前的步骤是先创建volume,再挂载(local形式的数据卷)
#我们现在换一种方法使用数据卷
[root@localhost ~]# docker run -dt –name goudan2 -v gzy2 centos
[root@localhost ~]# docker ps
[root@localhost ~]# docker volume ls
如果创建容器的时候不使用-v参数的标准格式来使用数据卷,那么docker会自动帮你创建一个数据卷,并且如果以上
面的例子来看,那么gzy2并不是任何的数据卷,而是挂载点,而且是/gzy2
[root@localhost ~]# touch
/var/lib/docker/volumes/38f1f89f1f51a00a0a807d779774d8dbfe171549038ebfb929f7c0c7a62dc7e
5/_data/glshh
[root@localhost ~]# docker exec -it goudan2 bash
[root@b3caa31a5c0e /]# ls /gzy2/
[root@localhost ~]# docker run -dt –name goudan3 -v web:/web nginx
bc5cf0574ef0cdf00f238fba85ba8cd43ba1f3d1519a12518784830dab6f4012
[root@localhost ~]# docker volume ls
3.Docker容器使用bind mounts
容器的bind mounts相比于容器的数据卷来说,使用上更加的灵活。
[root@localhost ~]# mkdir /mnt/gzy5
[root@localhost ~]# docker run -dt –name goudan5 -v /mnt/gzy5:/gzy5 centos
d7e2f31f781f72f674676d37a93e4db11fe7bfdbbb4f8dfedfcd797b711707e2
[root@localhost ~]# docker inspect goudan5 | grep gzy5 -B 5 -A 5
[root@localhost ~]# docker exec -it goudan5 bash
[root@d7e2f31f781f /]# df -Th
[root@localhost ~]# cd /mnt/gzy5/
[root@localhost gzy5]# ls
[root@localhost gzy5]# touch glshh
[root@localhost gzy5]# docker exec -it goudan5 bash
[root@d7e2f31f781f /]# ls /gzy5/
glshh
[root@d7e2f31f781f /]# touch /gzy5/glshs
[root@d7e2f31f781f /]# exit
exit
[root@localhost gzy5]# ls /mnt/gzy5/
4.Docker容器持久化存储实践
[root@localhost ~]# docker pull httpd
[root@localhost ~]# docker images
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
[root@localhost ~]# docker run -dt –name web1 httpd
dd0a031b9170eab94bdde4fb07a26940133778e1c859caf97138a7134397a746
[root@localhost ~]# docker ps -a
#查看容器中的进程信息
[root@localhost ~]# docker top web1
[root@localhost ~]# docker rm -f web1
web1
[root@localhost ~]# docker run -dt –name web1 –network host httpd
[root@localhost ~]# docker ps -a
[root@localhost ~]# netstat -tunlp | grep 80
[root@localhost ~]# curl localhost
It works!
[root@localhost ~]# systemctl disable firewalld –now
[root@localhost ~]# docker exec -it web1 bash
root@localhost:/usr/local/apache2# pwd
/usr/local/apache2
root@localhost:/usr/local/apache2# ls
bin build cgi-bin conf error htdocs icons include logs modules
root@localhost:/usr/local/apache2# cd htdocs/
root@localhost:/usr/local/apache2/htdocs# ls
index.html
root@localhost:/usr/local/apache2/htdocs# cat index.html
It works!
#当我们进入到容器之后,我们可以看到我们当前的web页面实际的目录是/usr/local/apache2/htdocs
[root@localhost ~]# docker rm -f web1
web1
[root@localhost ~]# docker run -dt –name web1 -v /web:/usr/local/apache2/htdocs –
network host httpd
dcd0664afbeab5a106bd82485f919712260f1fa1525794a432d9600fbf808695
[root@localhost ~]# docker ps
[root@localhost ~]# docker exec -it web1 ls /usr/local/apache2/htdocs
[root@localhost ~]# ls /web/
[root@localhost ~]# echo “glshs” >> /web/index.html
[root@localhost ~]# docker exec -it web1 ls /usr/local/apache2/htdocs
index.html
[root@localhost ~]# docker run -dt –name web2 -v /web:/usr/local/apache2/htdocs –network host httpd
777603dea2c3b5ef88c54bd3b0b97b507fafe003f0db27fdc70c8e8b026e24aa
[root@localhost ~]# docker ps -a
[root@localhost ~]# docker logs web2
5.Docker容器的自启动策略
docker容器默认情况下,如果宿主机关机再开机之后,docker容器将不会自动启动。
1.我们必须要确保容器的服务是开机自启动的
[root@localhost ~]# systemctl enable docker –now
2.我们必须要确保哪些容器需要开机自启动
[root@localhost ~]# docker run -dt –name web5 -v /web:/usr/local/apache2/htdocs -p 8082:80 httpd
[root@localhost ~]# docker ps -a
[root@localhost ~]# curl localhost:8082
[root@localhost ~]# reboot
[root@eveng-home ~]# ssh 10.163.1.110
[root@localhost ~]# docker ps -a
[root@localhost ~]# docker rm -f web5
web5
[root@localhost ~]# docker run -dt –name web1 -v /web:/usr/local/apache2/htdocs -p 8082:80 –restart=always httpd
b49f06e4fcd668d70fb2446c749c5c207c27a3b0d509be4f020d204b04372e72
[root@localhost ~]# !cur
curl localhost:8082
glshs
glshq
[root@localhost ~]# reboot
Connection to 10.163.1.110 closed by remote host.
Connection to 10.163.1.110 closed.
[root@eveng-home ~]# ssh 10.163.1.110
[root@localhost ~]# docker ps -a
[root@localhost ~]# docker run -dt –name web2 -v /web:/usr/local/apache2/htdocs –network host httpd
a7efb2561f7c02b408c638ae134f938284b0c19da72cdd7621e96714d4a37179
[root@localhost ~]# docker run -dt –name web3 -v /web:/usr/local/apache2/htdocs –network host httpd
ba4aca4c2133d045b0e64b438f8904e577cfb749cd7c3c10da5930bbbfdc04b6
[root@localhost ~]# docker ps -a
[root@localhost ~]# docker logs web3
[root@localhost ~]# docker rm -f web2
web2
[root@localhost ~]# docker rm -f web3
web3
[root@localhost ~]# docker run -dt –name web2 -v /web:/usr/local/apache2/htdocs –network host –restart=on-failure httpd
73fb4f2c737172c0ebc7e50d0ebf97167c0707e4bbc9924bfee61ad1838565cb
[root@localhost ~]# docker ps -a
[root@localhost ~]# docker run -dt –name web3 -v /web:/usr/local/apache2/htdocs –network host –restart=on-failure httpd
20a8a33ad7330f7c0afa2d50847cb48fb901c1960a086df46135cc7a014d9d35
[root@localhost ~]# docker ps -a
#–restart参数有三个
默认是no,表示容器退出时,不重启容器
on-failure表示只有容器在非0状态退出时才重新启动容器
always表示无论任何状态退付出,都重启容器
[root@localhost ~]# docker ps -a