Docker系列文-----Docker的镜像导出和卷的概念(3)
镜像的导出:
1.docker save -o
导出存放的镜像----->静态
- -o:output 输出
root@root:~# docker save -o sc-ubuntu.tar ubuntu
root@root:~# ls
sc-ubuntu.tar snap
使用scp命令传递到另一台服务器:
root@root:~# scp sc-ubuntu.tar root@192.168.63.148:/root
The authenticity of host '192.168.63.148 (192.168.63.148)' can't be established.
ECDSA key fingerprint is SHA256:GxTBpNCA4aIloEX9GB3B9jvi/yhnG5e/9/bV4JadMgo.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '192.168.63.148' (ECDSA) to the list of known hosts.
@192.168.63.148's password:
sc-ubuntu.tar
在另一台服务器上导入镜像:docker load -i (input)
root@root:~# docker load -i sc-ubuntu.tar
Loaded image: ubuntu:latest
2.docker export
导出正在运行的容器的镜像----->动态
root@root:~# docker export -o ubuntu2.tar ubuntu-liu-9
root@root:~# ls
sc-ubuntu.tar snap ubuntu2.tar
scp到另一台电脑上
root@root:~# scp ubuntu2.tar root@192.168.63.148:/
root@192.168.63.148's password:
ubuntu2.tar
将ubuntu2.tar导入到本地镜像命名为ubuntu2且tag为2.0
[root@sc-docker /]# docker import ubuntu2.tar ubuntu2:2.0
sha256:fea262f3bb72fdb5826495086ac47c44284e542cfc7dbd90edca755afde3f4fb
- - - - - - - - - - - - -
查看导入的的镜像文件
[root@sc-docker /]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu2 2.0 fea262f3bb72 2 seconds ago 72.8MB
容器的数据保存问题:
1.使用数据卷的目的:
官方文档给出了这样的解释:
官方文档网站点此处
通俗的理解,数据卷的目的就是为了实现数据持久化存储(Data Persistence),为了数据能够落入磁盘,通过虚拟机和容器进程相应目录之间的挂载实现将数据存储在文件夹中来达成落盘的目的。
[root@sc-docker /]# ps aux|grep container
root 976 0.0 1.3 1351564 52452 ? Ssl 04:16 0:15 /usr/bin/containerd
root 4792 0.0 2.2 1664556 87192 ? Ssl 12:11 0:03 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock
root 4952 0.0 0.2 1078996 9000 ? Sl 12:12 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 9090 -container-ip 172.17.0.2 -container-port 90
root 4958 0.0 0.1 1078996 6804 ? Sl 12:12 0:00 /usr/bin/docker-proxy -proto tcp -host-ip :: -host-port 9090 -container-ip 172.17.0.2 -container-port 90
root 4972 0.0 0.4 712172 16180 ? Sl 12:12 0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id f91a8e535bccb76d36f0b3ca1ab094ef6534f802e95249d49fdd0d30791f4df7 -address /run/containerd/containerd.sock
root 5117 0.0 0.1 1078996 6976 ? Sl 12:43 0:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 12345 -container-ip 172.17.0.3 -container-port 90
root 5123 0.0 0.1 1078996 6852 ? Sl 12:43 0:00 /usr/bin/docker-proxy -proto tcp -host-ip :: -host-port 12345 -container-ip 172.17.0.3 -container-port 90
root 5135 0.0 0.3 713324 13852 ? Sl 12:43 0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id a02d36cea2275453f6b8ccd15cd1efe3952ee3ca1b12ca1d7dd2c42d31e4dc6f -address /run/containerd/containerd.sock
root 5421 0.0 0.4 711916 15384 ? Sl 14:40 0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 5d8983832ccac8743867b8320af079f3c9bca40ce2b5532977f4beb05adf60f4 -address /run/containerd/containerd.sock
root 5764 0.0 0.3 713324 13244 ? Sl 15:14 0:00 /usr/bin/containerd-shim-runc-v2 -namespace moby -id 4426f7d6b461f05b1f7c424ed2cad595446319916928e50b3da2bb5a92cc35e1 -address /run/containerd/containerd.sock
root 5879 0.0 0.0 12324 968 pts/1 S+ 15:53 0:00 grep --color=auto container
docker-proxy:这个进程是专门负责端口映射(监听端口的)
dockerd : docker server的进程
containerd:整个容器的管理进程
containerd-shim-runc-v2:具体某个容器对应的进程
- docker管理这些容器(进程),通过访问这些容器(进程)各自的socket文件来控制
- [root@sc-docker /]# ps aux|grep containerd-shim|wc -l 这个值减去一便可以得到现在开启了多少个容器
2.数据卷作用的测试
首先我们必须要知道数据卷存放的目录(以Centos为例)
/var/lib/docker/volumes 是存放数据卷的目录
[root@sc-docker volumes]# ls
10291027e139637a9bf4febd3d8d44715bb668e5ea781d70638f8270014e7962 63eec0a2acb5c3c0bd1c584ad5e86c848f3fc364acc910e9147e1ac6501e053d metadata.db scc
2fc386ef4194e19435b6b19a3b60f9fccd788dfd6c8dbee5227911500eca3e29 backingFsBlockDev sanchuang
4098cea42c28e882d7b39d162cb5fed02e44ae059e42a3dea8a9ecb996da10c2 f156a12c68d728735eaf14f5a2ab847db651fe369bca2cb1ce24c2623dbef084 sc
可以看到里面这些乱码数字都是对应着一个个数据卷的名字
下面开始测试数据会不会写进来:
1.首先创建并且连接一个MySQL的容器
[root@sc-docker volumes]# docker start sc-mysql-1
sc-mysql-1
[root@sc-docker volumes]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4426f7d6b461 centos "/bin/bash" 55 minutes ago Up 55 minutes luojiajun3
f91a8e535bcc centos "/bin/bash" 4 hours ago Up 4 hours 0.0.0.0:9090->90/tcp, :::9090->90/tcp centos-sc-2
a02d36cea227 centos "/bin/bash" 4 hours ago Up 3 hours 0.0.0.0:12345->90/tcp, :::12345->90/tcp centos-3
5d8983832cca centos "/bin/bash" 5 hours ago Up About an hour centos-1
1468f427a37b mysql:5.7.35 "docker-entrypoint.s…" 23 hours ago Up 1 second 0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp sc-mysql-1
[root@sc-docker volumes]# mysql -uroot -p'sanchuang123' -h'192.168.63.148
2.进入MySQL容器内部然后添加几个库
MySQL [(none)]> create database xyy;
Query OK, 1 row affected (0.002 sec)
MySQL [(none)]> create database xxy;
Query OK, 1 row affected (0.001 sec)
MySQL [(none)]> create database sanchuang;
Query OK, 1 row affected (0.001 sec)
MySQL [(none)]> create database hhahaha;
Query OK, 1 row affected (0.001 sec)
MySQL [(none)]> exit
Bye
3.查看这个mysql使用的是哪个数据卷
[root@sc-docker volumes]# docker container inspect sc-mysql-1|grep volume -C 5
},
"Name": "overlay2"
},
"Mounts": [
{
"Type": "volume",
"Name": "2fc386ef4194e19435b6b19a3b60f9fccd788dfd6c8dbee5227911500eca3e29",
"Source": "/var/lib/docker/volumes/2fc386ef4194e19435b6b19a3b60f9fccd788dfd6c8dbee5227911500eca3e29/_data",
"Destination": "/var/lib/mysql",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
docker container inspect sc-mysql-1|grep volume -C 5
docker container insepct+容器名 ---------查看一个容器的详细信息
grep volume -C -5 ---------筛选出喊volume的上下5行
明显可以看到2fc386ef4194e19435b6b19a3b60f9fccd788dfd6c8dbee5227911500eca3e29 为该数据库的volume名字
4.验证:进入存放数据卷的地方
[root@sc-docker volumes]# cd /var/lib/docker/volumes
[root@sc-docker volumes]# ls
10291027e139637a9bf4febd3d8d44715bb668e5ea781d70638f8270014e7962 4098cea42c28e882d7b39d162cb5fed02e44ae059e42a3dea8a9ecb996da10c2 backingFsBlockDev metadata.db
2fc386ef4194e19435b6b19a3b60f9fccd788dfd6c8dbee5227911500eca3e29 63eec0a2acb5c3c0bd1c584ad5e86c848f3fc364acc910e9147e1ac6501e053d f156a12c68d728735eaf14f5a2ab847db651fe369bca2cb1ce24c2623dbef084
[root@sc-docker volumes]# cd 2fc386ef4194e19435b6b19a3b60f9fccd788dfd6c8dbee5227911500eca3e29/
[root@sc-docker 2fc386ef4194e19435b6b19a3b60f9fccd788dfd6c8dbee5227911500eca3e29]# ls
_data
[root@sc-docker 2fc386ef4194e19435b6b19a3b60f9fccd788dfd6c8dbee5227911500eca3e29]# cd _data
[root@sc-docker _data]# ls
auto.cnf ca.pem client-key.pem ib_buffer_pool ib_logfile0 ibtmp1 performance_schema public_key.pem server-cert.pem sys xyy
ca-key.pem client-cert.pem hhahaha ibdata1 ib_logfile1 mysql private_key.pem sanchuang
发现此时我们新建的几个库已经在_data目录下出现了,验证成功。
如何创建一个数据卷?
查看当前Docker有哪些数据卷
docker volume ls
[root@sc-docker web]# docker volume ls
DRIVER VOLUME NAME
local 2fc386ef4194e19435b6b19a3b60f9fccd788dfd6c8dbee5227911500eca3e29
local 63eec0a2acb5c3c0bd1c584ad5e86c848f3fc364acc910e9147e1ac6501e053d
local 4098cea42c28e882d7b39d162cb5fed02e44ae059e42a3dea8a9ecb996da10c2
local 10291027e139637a9bf4febd3d8d44715bb668e5ea781d70638f8270014e7962
local f156a12c68d728735eaf14f5a2ab847db651fe369bca2cb1ce24c2623dbef084
创建一个数据卷
docker volume create + 卷名
[root@sc-docker web]# docker volume create sc
sc
查看当前的卷
[root@sc-docker web]# docker volume ls
DRIVER VOLUME NAME
local 2fc386ef4194e19435b6b19a3b60f9fccd788dfd6c8dbee5227911500eca3e29
local 63eec0a2acb5c3c0bd1c584ad5e86c848f3fc364acc910e9147e1ac6501e053d
local 4098cea42c28e882d7b39d162cb5fed02e44ae059e42a3dea8a9ecb996da10c2
local 10291027e139637a9bf4febd3d8d44715bb668e5ea781d70638f8270014e7962
local f156a12c68d728735eaf14f5a2ab847db651fe369bca2cb1ce24c2623dbef084
local sc
查看一个卷的详细信息
docker volume inspect +容器名
[root@sc-docker sc]# docker volume inspect sc
[
{
"CreatedAt": "2021-08-12T16:30:06+08:00",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/sc/_data",
"Name": "sc",
"Options": {},
"Scope": "local"
}
]
让一个nginx容器使用这个卷
- -mount source=sc,target=/usr/share/nginx/html
前面接的是卷的名字,后面接的需要挂载的目录
同样:\为续行符
[root@sc-docker _data]# docker run -d \
--name fan-nginx-1 \
--mount source=sc,target=/usr/share/nginx/html \
-p 7799:80 \
nginx:latest
c2d3c180392ebe26527c2cfe29e03e64b7c415bb90ccb3974dc9b85e0e0e9614
注意:
Volume是一个公共的,是一个共享的数据中心。
可以有多个容器同时使用,达到共享数据的目的
简单来说,再挂载一个同上例的容器命名为fan-nginx-2 7780端口,这时候就可以发现,我们访问的数据是一样的,然后进入sc卷下的_data目录,修改index.html,发现两个容器对应的端口的首页都发生了改变,这就证明了上面这两点。
Tips:
当Centos容器内连不上网络时该怎么做?
首先考虑一下-p选项,虽然关系不大,但是我还是想解释一下
-p 做端口映射的时候,会发布到iptables一条SNTA和DNAT的策略
不加p选项的时候 满足SNAT发布策略,别人是访问不了自己的(DNAT)
加了p选项既可以访问别人,又可以让别人访问进来。
可以考虑一下本机的路由功能是否打开:
临时打开路由功能:
[root@sc-docker /]# cat /proc/sys/net/ipv4/ip_forward
1
永久打开路由功能:
修改配置文件
[root@sc-docker /]# vim /etc/sysctl.conf
在末尾加上一行
net.ipv4.ip_forward = 1
[root@sc-docker /]# sysctl -p 从/etc/sysctl.conf中重新加载配置文件
net.ipv4.ip_forward = 1
server docker restart 重启docker,会到iptables里去添加相关规则
最后如果不行,还是老办法,重启docker的服务试试!
启动容器时如何限制容器的内存和可使用的资源?
docker run -it --cpu-shares 30 -m 100000000 -d --name luojiajun3 centos:7
–cpu-shares 30:限制使用cpu
cpu的计算资源:1–》1000份—》1m
1s ----》1000ms
此时容器中不管你cpu有多少个核心,都是看作一个整体来计算
8核—》1—》30m
-m 100000000 限制内存的使用 byte
–memory bytes
内存溢出会怎么样呢(OOM)?
oom ----->out of memory 内存溢出
有两种情况导致oom:
- 分配的少了
- 应用用的太多了,并且用完的没释放,浪费了
理论上:
[root@sc-docker volumes]# docker container inspect rose-1|grep -C 5 OOM
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 8459,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-08-12T10:34:41.65003868Z",
此时的 “OOMKilled”: false 代表着:正常情况下容器没有被Docker杀死
但是一但超过设置的内存达到OOM条件时,容器会被kill掉,此后, “OOMKilled”: ture
如何限制一个进程可以使用多少cpu和多少内存?
鉴于我们刚学习了容器,我们就可以巧妙的利用容器来启动进程,达到控制cpu和内存使用的目的
创建一个容器,让这个进程在容器里run,这样可以限制容器所使用的cpu和内存,从而可以达到限制这个进程的cpu和内存的使用。