Akemi

Docker管理

2024/05/14

如果出现无法载图的情况,请检查与github的连通性

Docker架构

Docker构成
1、docker deamon 守护进程(提供docker服务)
2、docker restful-api(http/https 发起访问)
3、client docker cli(运维使⽤docker 命令⾏进⾏docker管理)(容器/镜像/存储/⽹络)

Docker框架
1、docker host运行docker主机
2、docker client命令行控制的客户端
3、docker registry镜像仓库

docker版本:
——CE版本(社区版)
——EE版本(企业版)
——edge版-每月更新 体验版
——stable版-稳定版

镜像相关:
docker registry是存放容器镜像的仓库,用户可以进行镜像下载和访问,分为公有和私有两类registry

公有镜像仓库比如
docker hub,是docker公司为公众提供的托管registry,是世界上最大的容器镜像仓库Docker Hub
quay.io,是红帽的公共托管registryRepositories · Quay

私有镜像仓库可以由企业搭建私有registry,也可以由个人搭建

Docker的安装

从官网安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#Docker安装
#环境
centos7.8.2003
192.168.8.150/24
gw 192.168.8.254
NAT网络,确保能连上网络即可
#1、通过get.docker.com官网下载get-docker.sh,并且增加参数,跳过安全验证
curl -fskSL get.docker.com -o get-docker.sh
#2、下载安装
#从外网直接安装
sudo sh get-docker.sh
#从阿里云安装
sudo sh get-docker.sh --mirror Aliyun
#3、自启动
systemctl enable docker --now
#4、把用户添加到docker组内,使其可以使用docker
usermod -aG docker ws
id ws
#uid=1000(ws) gid=1000(ws) groups=1000(ws),982(docker)
su - ws
#5、测试
docker run hello-world
#6、查看docker守护进程
ps -ef | grep -i dockerd
root 13168 0.4 1.9 1554288 75428 ? Ssl 18:40 0:57 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

从yum/apt等包管理器安装

1
2
3
4
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum -y update
yum -y install docker-ce
systemctl enable docker --now

基础docker操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
#查看docker版本
docker --version
docker version
#查看docker状态,可以看到docker的客户端与服务器状态、远端仓库地址等
docker info

#容器管理
#容器运行
docker run httpd #直接在前台运行
docker run -d #在后台运行
docker run -p 1234:8080/tcp #端口映射,指定端口,将宿主机端口1234映射到容器8080端口,指定tcp协议
docker run -P #端口映射,随机端口
docker run --name #指定名字
docker run -it ...... /bin/bash#使其可交互,并且分配bash
docker run -v 宿主机路径:容器内地址 #指定外部挂载到容器内部,建议使用绝对路径
eg:docker run -itd --name test -p 1234:8080/tcp -v /iso:/var/tftp/boot centos /bin/bash
#CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#886c57251999 centos "/bin/bash" 37 seconds ago Up 36 seconds 0.0.0.0:1234->8080/tcp, :::1234->8080/tcp test

#重新进入已经后台运行的容器
docker exec -it 886c57251999 /bin/bash
exit #退出

#
docker start containerID #容器,启动!
docker restart containerID #重启
#查看正在运行的docker container
docker ps
#查看所有的docker container,包括没起来的
docker ps -a
#查看所有的正在运行docker的容器id
docker ps -q
#关闭容器
docker stop containerID #正常关闭
docker stop $(docker ps -aq) #全部关闭
docker kill containerID #强制关闭
#删除容器
docker rm containerID
docker rm -f containerID #强制删除
docker rm $(docker ps -aq) #全部删除
#复制文件
docker cp 宿主机⽂件路径 容器id:路径

#镜像管理
#在镜像仓库中搜索镜像
docker search httpd
#从docker官网拉取镜像
#使用阿里云镜像加速,拉取镜像就会优先从远端阿里云仓库拉取,就会快很多
#https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
docker pull httpd
docker pull mysql:5.7 #指定版本拉取
#查看镜像
docker images
docker images -a #查看所有镜像
docker images -q #只查看镜像id
#给image添加tag
docker tag xxxxxxxx httpd
#删除镜像,默认删除latest版本
docker rmi httpd #指定名称
or
docker image rm httpd #同意思
docker rmi hello-world:latest #指定版本
docker rmi -f hello-world #强制删除

Docker镜像

1
2
3
4
5
6
7
容器镜像封装加载
docker pull centos/httpd-24-centos7
docker run -d -p 10001:8080 --name cm01 centos/httpd-24-centos7

容器打包
docker commit -m "描述信息" -a "作者信息" 容器ID/容器名称 ⾃定义镜像名称:⾃定义标签
docker commit -m "ws" -a "ws" cm01 wsapache:v1.0

1
2
镜像封装
docker save 镜像名称:标签 -o 镜像打包的⽂件名 #默认当前目录

1
2
3
4
5
6
7
8
关闭容器
docker stop cm01
删除镜像
docker rmi wsapache:v1.0
删除容器
docker rm cm01
通过其他机器打包的镜像包,进行镜像载入到本机
docker load -i wsapache.tar

Docker网络

本文转载自我的CSDN,水印就不去了
https://blog.csdn.net/qq_72569959/article/details/134894177

docker网络原理

​​与ovs类似,docker容器采用veth-pair + linux bridge (虚拟交换机)的通信方式
以Bridge类型举例

​​​​

查看得到:
容器外的if20连接了容器cm01的if21网卡
容器外的if22连接了容器cm02的if23网卡
数字不固定,一般宿主机是偶数,容器内是奇数

查看br状态,看到有两个veth-pair网卡连接到了br0

容器内的ip地址通过vRouter的NAT转换成宿主机地址

1
2
3
4
5
6
7
8
9
10
11
12
#二层mac表寻址
docker run -dit --name cm01 alpine
docker run -dit --name cm02 alpine
#互ping后
brctl showmacs docker0
port no mac addr is local? ageing timer
1 02:42:ac:11:00:02 no 0.14
2 02:42:ac:11:00:03 no 0.14
2 36:5c:3a:ff:64:14 yes 0.00
2 36:5c:3a:ff:64:14 yes 0.00
1 ae:84:17:1c:93:6c yes 0.00
1 ae:84:17:1c:93:6c yes 0.00

docker网络类型

docker默认创建了三种网络类型

1
2
3
4
5
6
docker network ls
NETWORK ID NAME DRIVER SCOPE
a21005000639 bridge bridge local
e6a21ab3e3b4 host host local
6725e5c3cb83 none null local
docker network inspect a21005000639 #查看网络类型详细信息

docker共有5种网络类型,各有特点

1、none 只有loopback,容器内部无网卡

2、host 容器使用宿主机网络,类似于VMwareworkstation的桥接网络
————直接共享宿主机的网络状态
————不同容器之间需要使用不同的IP地址
————直接访问,效率更高

3、bridge (容器默认使用并连接到docker0网桥) 最常用的方式
————通过NAT进行访问,外部访问即指定端口号
————二层通过linux Bridge mac表进行交换
————三层通过iptables和路由表进行转发
————经过NAT装换,效率相对较低

4、container 共享容器命名空间
————主机和主机共享命名空间
————不同容器之间可以使用相同的IP地址
————k8s打包pod时使用

5、vxlan cluster 集群网络
————用于集群内容器实现大二层通信
———通过安装etcd实现

Bridge网络

创建新的网桥br1

1
2
3
4
5
6
7
8
9
10
11
12
docker network create
-d #指定网络类型
--gateway #指定网关
--subnet #指定子网

docker network create -d bridge br1 #添加了类型为Bridge的网桥
docker network rm br1 #删除网桥
#如果指定子网创建
docker network create -d bridge --subnet 192.168.1.0/24 -- gateway 192.168.1.1 br1

通过查看docker network ls和brctl show,可以发现都多了一个网桥br1

没有指定子网的情况下,子网会顺延创建,默认的docker0使用的是172.17网段,br1使用172.18网段

1
2
3
4
5
创建新的容器并指定网络
docker run -itd --name cm04 --network br1 alpine
docker exec -it cm04 ash
ip a
能看到新的容器已经获得了地址

新的br上增加了一个interface

查看iptables

将容器切换网桥

docker network disconnect bridge cm01 #断开连接

docker network connect br1 cm01 #重新连接

docker network inspect br1 #查看br1状态,可以看到有两个容器获得了地址

自定义网桥的域名访问

在用户自定义的网络类型中,自带了域名解析功能,可以使用域名直接进行访问

给容器设置别名来使用网络

1
2
3
4
5
6
7
8
9
10
#使用alpine镜像
docker run -itd --name cm01 alpine /bin/ash
#docker run时使用--link=参数,相当于将cm01与test做解析的绑定
docker run -itd --name cm02 --link=cm01:test alpine /bin/ash
docker exec -it cm01 /bin/ash
ip a
#172.17.0.3
docker exec -it cm02 /bin/ash
ip a
#172.17.0.4

host网络

复制宿主机网络状态,与宿主机共用同一个网络命名空间

1
2
3
docker run -itd --name cm05 --network host alpine
docker exec -it cm05 ash
ip a

none网络

1
2
3
docker run -itd --name cm08 --network none alpine
docker exec -ti cm08 ash
ip a

container网络

复制另外容器的网络状态,与另外容器共用同一个网络命名空间

1
2
3
docker run -itd --name cm06 --network container:cm01 alpine
docker exec -it cm06 ash
ip a #与cm01使用的网络一样

vxlan cluster网络

集群场景下,两个宿主机要跨网段进行大二层交换,需要安装etcd分布式数据库,构建etcd存储,用以同步网络信息

注意:docker版本为Docker 20.10.6,如果不是这个版本可能会报错

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#下载etcd
wget https://github.com/coreos/etcd/releases/download/v3.0.12/etcd-v3.0.12-linux-amd64.tar.gz
#如果报错也可以用迅雷下载后传到宿主机中
我将其放在了根目录下
tar -zxvf etcd-v3.0.12-linux-amd64.tar.gz

#创建etcd集群,宿主机1
cd /etcd-v3.0.12-linux-amd64/
nohup ./etcd --name docker-node1 --initial-advertise-peer-urls \
http://192.168.8.150:2380 \
--listen-peer-urls http://192.168.8.150:2380 \
--advertise-client-urls http://192.168.8.150:2379 \
--listen-client-urls http://192.168.8.150:2379,http://127.0.0.1:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster docker-node1=http://192.168.8.150:2380,docker-node2=http://192.168.8.148:2380 \
--initial-cluster-state new&

#创建etcd集群,宿主机2
cd /etcd-v3.0.12-linux-amd64/
nohup ./etcd --name docker-node2 --initial-advertise-peer-urls \
http://192.168.8.148:2380 \
--listen-peer-urls http://192.168.8.148:2380 \
--advertise-client-urls http://192.168.8.148:2379 \
--listen-client-urls http://192.168.8.148:2379,http://127.0.0.1:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster docker-node1=http://192.168.8.150:2380,docker-node2=http://192.168.8.148:2380 \
--initial-cluster-state new&

创建完之后再单开一个terminal
#验证
ps -ef | grep etcd
#root 2655 2428 9 03:37 pts/1 00:00:00 ./etcd --name docker-node2 --initial-advertise-peer-urls http://192.168.8.148:2380 --listen-peer-urls http://192.168.8.148:2380 --advertise-client-urls http://192.168.8.148:2379 --listen-client-urls http://192.168.8.148:2379,http://127.0.0.1:2379 --initial-cluster-token etcd-cluster --initial-cluster docker-node1=http://192.168.8.150:2380,docker-node2=http://192.168.8.148:2380 --initial-cluster-state new

#检查健康状态
cd /etcd-v3.0.12-linux-amd64/
./etcdctl cluster-health
#member 55bbbb082228277b is healthy: got healthy result from http://192.168.8.150:2379
#member fd79a45b0c14607d is healthy: got healthy result from http://192.168.8.148:2379
#cluster is healthy

#docker关联etcd
#宿主机1
systemctl stop docker.service
systemctl stop docker.socket
/usr/bin/dockerd -H tcp://0.0.0.0:2375 \
-H unix://var/run/docker.sock \
--cluster-store=etcd://192.168.8.150:2379 \
--cluster-advertise=192.168.8.150:2375&
#宿主机2
systemctl stop docker.service
systemctl stop docker.socket
/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock \
--cluster-store=etcd://192.168.8.148:2379 \
--cluster-advertise=192.168.8.148:2375&

#集群主机中创建network
#在宿主机1创建与查看
docker network create -d overlay etcd_network
docker network ls
#NETWORK ID NAME DRIVER SCOPE
#80e52b011080 bridge bridge local
#47b97959e9a3 etcd_network overlay global
#736b5705ffbf host host local
#cc7dfdbc929a none null local
docker inspect etcd_network

在宿主机2查看与宿主机1一致
docker network ls
#NETWORK ID NAME DRIVER SCOPE
#80e52b011080 bridge bridge local
#47b97959e9a3 etcd_network overlay global
#736b5705ffbf host host local
#cc7dfdbc929a none null local

Docker存储

通过命令查看存储驱动程序
docker info | grep -i storage
#Storage Driver: overlay2

一般采用的都是overlay2

overlay2

不使用volume或bind mount时,默认使用overlay2的Storage Driver,通过merge将容器可读可写层融合在镜像上,其默认挂载路径为/var/lib/docker/overlay2

在创建了容器后,通过df -Th可以看到多了一个overlay [filesystem]挂载路径在/var/lib/docker/overlay2/中,并且容器删除之后就会消失
下面用实验演示一下

1
2
3
4
5
6
7
8
[root@192 ~]# ls /var/lib/docker/overlay2/ | wc -l
51
[root@192 ~]# docker rm -f
centos cm01 test
[root@192 ~]# docker rm -f test
test
[root@192 ~]# ls /var/lib/docker/overlay2/ | wc -l
49

可以看到删除容器后目录下的条目变少了

如果要进行持久化存储,则可以通过两种方式,volume与bind mount来实现

volume

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
docker run -tid --name centos -v /etc/selinux/ centos
ls /var/lib/docker/volumes/a2b9ad6de48699da4e609f909b38b9c030b40f97b28b98841505c19b9a506a51/_data/
可以看到多了个semanage.conf文件,这是从容器中挂载出的文件,在这个文件中修改时也会将其同步到容器内

列出volume卷
docker volume ls
DRIVER VOLUME NAME
local a2b9ad6de48699da4e609f909b38b9c030b40f97b28b98841505c19b9a506a51

查看volume卷详情
docker volume inspect a2b9ad6de48699da4e609f909b38b9c030b40f97b28b98841505c19b9a506a51
[
{
"CreatedAt": "2023-12-10T21:04:12+08:00",
"Driver": "local",
"Labels": {
"com.docker.volume.anonymous": ""
},
"Mountpoint": "/var/lib/docker/volumes/a2b9ad6de48699da4e609f909b38b9c030b40f97b28b98841505c19b9a506a51/_data",
"Name": "a2b9ad6de48699da4e609f909b38b9c030b40f97b28b98841505c19b9a506a51",
"Options": null,
"Scope": "local"
}
]

特点:
1.Volume完全由Docker管理.是将特定⽬录挂载给容器。
2.使⽤卷Volume时,会在主机上的Docker存储⽬录中创建⼀个新⽬录,Docker会管理该⽬录的内容。
3.Volume的内容存在于容器的⽣命周期之外:删除容器后,Docker数据卷仍然存在。
4.挂载volume时,不需要指定mount源,指定mount point即可。
5.Docker会在/var/lib/docker/volumes路径下为每个volume⽣成⼀个⽬录,作为mount源。
6.若mount point指向容器中的已有⽬录,则该⽬录下的数据会被copy到volume中。
7.若mount point指向容器中的空⽬录,则会⾃动创建所需⽬录。
8.若启动挂载尚不存在的卷的容器,Docker会为⾃动创建卷。
9.volume在使⽤时,可通过ro参数将容器对volume的权限设置为只读。

bind mount

将宿主机上已有的目录或文件mount到容器中

下面这个操作是创建一个http服务器,并且将本地文件挂载到服务展示文件的位置
docker run --name web01 -dit -p 8080:80 -v /root/htdocs:/usr/local/apache2/htdocs httpd:2.4

特点:
1.Linux绑定挂载(bind mount)主要作⽤是允许将⼀个⽬录或者⽂件(不是整个设备)挂载到⼀个指定的⽬录上。
2.在该挂载点上进⾏的任何操作,只是发⽣在被挂载的⽬录或者⽂件上,⽽原挂载点的内容则会被隐藏起来且不受影
响。
3.容器运⾏过程中,对bind mount⽬录中改动的数据,将被保存。删除容器后,bind mount中的数据仍然存在。
4.bind mount可以挂载⼀个⽬录到容器,也可以挂载⼀个⽂件到容器。但必须要指定⽬录或⽂件的路径,即mount
源,当然也必须指定mount point。这也限制了容器的可移植性。
5.若将bind mount绑定到容器上的某⾮空⽬录下,则会隐藏容器⽬录下的现有内容。若不希望容器的整个⽬录被覆
盖,可单独挂载某个⽂件。
6.若mount源指向的⽂件或⽬录在宿主机上不存在。则会⾃动创建。
7.使⽤bind mount时,可通过ro参数将容器对数据的权限设置为只读。(设置ro参数后,容器⽆法对数据进⾏修改,但宿主机依旧有权限修改其内容。

Dockerfile的介绍与书写

Dockerfile是一个用于定义Docker镜像的文本文件,包含了一系列的指令和参数,用于指示Docker在构建镜像时应该执行哪些操作,例如基于哪个基础镜像、复制哪些文件到镜像中、运行哪些命令等。

是除了从镜像仓库拉取、解压保存镜像以外的自定义构建镜像的方式,通过docker bulid dockerfile来构建

主要有几个部分组成,包括基础镜像,创建者信息,镜像操作指令,容器启动指令

构建指令:docker build -t=”image-name” <文件目录> –load

#Dockerfile文件指令
#FROM
FROM指定基础镜像,这个文件需要在本地有
如果在docker build后增加–load参数 可以去docker官网进行拉取
Dockerfile文件中定义的镜像就以FROM的镜像为基础,可指定tag

#MAINTAINER
是备注,用以指定创建者信息

#COPY
将同目录下的文件复制到镜像中
也可以使用—chown=参数指定权限
格式为 filename path

#ADD
格式同COPY
区别是移动tar文件后会自动解压
docker官方推荐使用COPY

#RUN
说明镜像构建过程中需要运行的命令,每次执行都会增加一层
有shell模式和exec模式
shell模式:
直接使用linux命令即可
exec模式:
RUN [“/bin/bash”,”-c”,” yum -y install xxx”]
/bin/bash表示解释器位置
-c代表指定后面是要执行的命令

#EXPOSE
声明端口,说明这个端口是容器映射出去的端口
可以指定多个
声明后,docker run -P会随机将宿主机端口映射到声明后的端口

#CMD
CMD在docker run命令执行时执行
有shell模式和exec模式
但会被docker run后自带的命令所覆盖
如果使用了ENTRYPOINT指令,作为其默认参数

#ENTERYPOINT
作用于CMD相同
有shell模式和exec模式ENTERYPOINT
不会被docker run后自带的命令覆盖,如果使用了参数–entrypoint则可以覆盖

ENTRYPOINT与CMD混用:
ENTRYPOINT [“nginx”,”-c”]
CMD [“/nginx.conf”]
nginx是nginx的命令行工具
-c代表用xx文件执行该命令
/nginx.conf基于根目录下的nginx.conf运行,即该文件是默认文件
但如果docker run指定了命令,就会覆盖掉CMD指定的文件,转而使用docker run指定的文件

#VOLUME
指定容器内的默认挂载点,使用后会默认把宿主机/var/lib/docker/volumes中挂载到容器中的挂载点,在docker run时可以通过-v手动指定宿主机挂载点
1.持久化存储,避免因为重启导致数据丢失
2.可以通过-v来更好管理存储

#WORKDIR
指定命令的工作目录,需要提前创建好

#ENV
指定环境变量
ENV key=value
例如ENV VERSION= 1.0,就可以使用$VERSION来引用

#USER
用以指定用户和用户组

#ONBUILD
延迟执行创建的命令,在某次构建镜像时不会执行,但下次如果有新的dockerfile使用了本镜像进行镜像构建时,就会执行这条命令。

nginx镜像构建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
mkdir wsdockerfile
#centos8已经停更了,下载软件需要另外的源,这个文件清华镜像站和centos官网都能找到
cp Centos-vault-8.5.2111.repo wsdockerfile/
cd wsdockerfile/
#删除并替换/etc/yum.repos.d/的源文件
#下载nginx并开放80端口
#用ENTRYPOINT使docker启动时自动启动nginx
cat > dockerfile << EOF
FROM centos
MAINTAINER ws
RUN rm -rf /etc/yum.repos.d/*
COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/
RUN yum install -y nginx
COPY index.html /usr/share/nginx/html/
EXPOSE 80
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]
EOF

echo 123 > index.html

docker build -t="ws/nginx:v1" . #开始构建
#[+] Building 130.1s (10/10) FINISHED docker:default
# => [internal] load build definition from dockerfile 0.0s
# => => transferring dockerfile: 270B 0.0s
# => [internal] load .dockerignore 0.0s
# => => transferring context: 2B 0.0s
# => [internal] load metadata for docker.io/library/centos:latest 0.0s
# => [1/5] FROM docker.io/library/centos 0.0s
# => [internal] load build context 0.0s
# => => transferring context: 77B 0.0s
# => CACHED [2/5] RUN rm -rf /etc/yum.repos.d/* 0.0s
# => CACHED [3/5] COPY Centos-vault-8.5.2111.repo /etc/yum.repos.d/ 0.0s
# => [4/5] RUN yum install -y nginx 129.6s
# => [5/5] COPY index.html /usr/share/nginx/html/ 0.0s
# => exporting to image 0.4s
# => => exporting layers 0.4s
# => => writing image sha256:075aaa08f6799ed252578b0c82645e41c61a818584e6e183053a6ce 0.0s
# => => naming to docker.io/ws/nginx:v1 0.0s
docker images | grep ws/nginx
#ws/nginx v1 075aaa08f679 51 seconds ago 342MB
docker run -d -p 80 --name wshttp ws/nginx:v1
#1f57b4d4b5a8d73fa5488b792099c08fe15cb1bbfdc71d166c1430f5be9e15d4
docker ps
#CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
#1f57b4d4b5a8 ws/nginx:v1 "/usr/sbin/nginx -g …" 19 seconds ago Up 18 seconds 0.0.0.0:32768->80/tcp, :::32768->80/tcp wshttp

图片

Docker数据卷容器与备份

数据卷容器的概念:其他容器通过这个容器实现数据共享,这个容器就叫数据卷容器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#创建一个数据卷容器
#可以采用docker run的时候选择-v参数,也可以选择使用dockerfile文件创建时使用VOLUME指令
cat > dockerfile << EOF
FROM centos
VOLUME ["/volume1","/volume2"]
CMD /bin/bash
EOF
#构建
docker build -t="volume" .
#运行,容器名为data-container
docker run -itd --name data-container volume
#进入容器,在/volume1目录中添加文件
docker exec -it data-container /bin/bash
cd volume1 && touch 123 && exit
#创建data-container2
docker run --name data-container2 --volumes-from data-container -itd centos /bin/bash
#查看container2中卷的情况,能看到data-container和data-container2已经共享了卷
docker exec -it data-container2 /bin/bash
ls volume1
#123

#备份
docker run --volumes-from data-container2 -v /root/backup:/backup \
--name backup-container centos tar zcvf /backup/volume1.tar.gz /volume1
#指定共享data-container2中的卷
#指定宿主机/root/backup与容器/backup共享
#指定容器名为backup-container
#传入命令tar zcvf /backup/volume1.tar.gz /volume1,把/volume1打包到/backup/volume1.tar.gz
ls /root/backup/
#volume1.tar.gz
#备份完成后原内容就被删除

#备份的还原
docker rm -f data-container2
docker run --volumes-from backup-container \
-v /root/backup:/backup centos tar zxvf /backup/volume1.tar.gz -C /
#进入查看
docker exec -it data-container2 /bin/bash
ls volume1

docker资源配额

Docker资源配额指的是对Docker容器或服务在系统资源使用方面的限制。
通过资源配额,可以控制和限制Docker容器可以使用的CPU、内存、磁盘空间和网络带宽等资源。

需要根据应用程序的需求和系统环境来设置适当的资源配额。过于严格的配额可能导致应用程序性能下降,而过于宽松的配额可能会导致资源浪费和冲突,资源配额提供了更好的资源控制和管理机制,以确保容器化环境的稳定性和性能。

CPU资源配额

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#查看帮助
docker run --help | grep cpu
--cpu-period int Limit CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota
--cpu-rt-period int Limit CPU real-time period in microseconds
--cpu-rt-runtime int Limit CPU real-time runtime in microseconds
-c, --cpu-shares int CPU shares (relative weight)
--cpus decimal Number of CPUs
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)

#CPU份额-c, --cpu-shares
CPU shares在创建容器时指定容器所使用的CPU份额值
是一个相对的加权值,不能保证获取绝对的core数量,默认docker容器cpu份额为1024
份额为1000的A容器和2000的B容器,B获取CPU占用时间的是A的两倍
如果CPU是充足,那么A和B都能获得充足的CPU
docker run -itd --name cpu1 --cpu-shares 1000 centos /bin/bash
docker exec -it cpu1 /bin/bash
cat /sys/fs/cgroup/cpu/cpu.shares
#1000

#CPU核数--cpuset-cpus、--cpuset-mems
可以控制容器运行限定使用哪些cpu内核和内存节点
更适用于具有NUMA拓扑(具有多CPU、多内存节点)的服务器
#nproc查看有多少个可用cpu
8
#使其绑定两个CPU
docker run -itd --name cpu1 --cpuset-cpus 0,1 centos /bin/bash

#puset-cpus和cpu-shares混合使用
docker run -itd --name cpu1 --cpuset-cpus 0,1 --cpu-shares 1000 centos /bin/bash
docker exec -it cpu1 /bin/bash
rm -rf /etc/yum.repos.d/* && exit

docker cp Centos-vault-8.5.2111.repo cpu1:/etc/yum.repos.d/
docker run -itd --name cpu2 --cpuset-cpus 0,1 --cpu-shares 2000 centos /bin/bash
docker exec -it cpu2 /bin/bash
rm -rf /etc/yum.repos.d/* && exit
docker cp Centos-vault-8.5.2111.repo cpu2:/etc/yum.repos.d/
#在容器内下载与使用stress压测软件,然后我忘了要在里面放centos8的源文件了
docker exec -it cpu1 yum install -y epel-release
docker exec -it cpu1 yum install -y stress
docker exec -it cpu2 yum install -y epel-release
docker exec -it cpu2 yum install -y stress
stress --help #查看stress帮助,直接看example就行
#Example: stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s

#开始测试,开三个terminal,一个cpu1,一个cpu2,一个看top
docker exec -it cpu1 /bin/bash
stress -c 2 --timeout 5m
docker exec -it cpu2 /bin/bash
stress -c 2 --timeout 5m
#再开一个terminal看top

内存资源配额

1
2
3
4
5
6
7
8
9
10
11
根据容器所运行的业务,配置相应最大内存,防止用太多影响其他的业务
docker run --help | grep -i memory
--kernel-memory bytes Kernel memory limit
-m, --memory bytes Memory limit
--memory-reservation bytes Memory soft limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--memory-swappiness int Tune container memory swappiness (0 to 100) (default -1)

docker run -itd --name mem1 -m 1g centos
docker exec -it mem1 cat /sys/fs/cgroup/memory/memory.limit_in_bytes
1073741824

IO资源配额

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
控制IO资源
docker run --help | grep write
--device-write-bps list Limit write rate (bytes per second) to a device (default [])
--device-write-iops list Limit write rate (IO per second) to a device (default [])
docker run --help | grep read
--device-read-bps list Limit read rate (bytes per second) from a device (default [])
--device-read-iops list Limit read rate (IO per second) from a device (default [])

#创建容器io,设置存储映射关系,设备sda限制io速度1mb每秒
docker run -it -v /test/:/test/ --device /dev/sda:/dev/sda \
--device-write-bps /dev/sda:1mb --name io centos /bin/bash
#使用dd命令,从sda写到/test/内,块大小1M,传送60个块,绕过内核缓存,直接读取和写入设备
time dd if=/dev/sda of=/test/transblock bs=1M count=60 oflag=direct,nonblock

#读数据同理

docker的结束运行资源释放

1
2
3
4
5
6
7
8
设置容器结束运行后自动释放资源,适用于一次性的容器如测试容器
如果容器是异常退出了也会被删除
docker run --help | grep rm
--rm Automatically remove the container when it exits
#只设置一个5秒钟的任务
docker run -it --rm --name rmtest alpine sleep 5
docker ps -a | grep rm
#无,已经被自动删除了
CATALOG
  1. 1. Docker架构
  2. 2. Docker的安装
    1. 2.1. 从官网安装
    2. 2.2. 从yum/apt等包管理器安装
    3. 2.3. 基础docker操作
  3. 3. Docker镜像
  4. 4. Docker网络
    1. 4.1. docker网络原理
    2. 4.2. docker网络类型
    3. 4.3. Bridge网络
      1. 4.3.1. 创建新的网桥br1
      2. 4.3.2. 将容器切换网桥
      3. 4.3.3. 自定义网桥的域名访问
      4. 4.3.4. 给容器设置别名来使用网络
    4. 4.4. host网络
    5. 4.5. none网络
    6. 4.6. container网络
    7. 4.7. vxlan cluster网络
  5. 5. Docker存储
    1. 5.1. overlay2
    2. 5.2. volume
    3. 5.3. bind mount
  6. 6. Dockerfile的介绍与书写
    1. 6.1. nginx镜像构建
  7. 7. Docker数据卷容器与备份
  8. 8. docker资源配额
    1. 8.1. CPU资源配额
    2. 8.2. 内存资源配额
    3. 8.3. IO资源配额
  9. 9. docker的结束运行资源释放