目录
一、基础操作
二、构建镜像
1、参数示例及利用方法
2、Docker构建实例
3、镜像优化示例
三、docker镜像堆栈管理
1、docker hub
2、搭建私有堆栈
(1)、搭建简单无加密私有堆栈
(2)、搭建加密的私有堆栈
(3)、搭建用户认证的私有堆栈
3、构建企业级私有堆栈-harbor
四、docker的网络
1、dacker的原生网络
(1)、bridge
(2)、host
(3)、none
2、docker的自界说网络
3、不同的自界说网络之间的通信
(1)、容器用不同的网络栈
(2)、容器用雷同的网络战栈-joined网络
4、容器内外网的访问
(1)、容器访问外网
(2)、外网访问容器
5、容器的跨主机网络通信
五、docker的数据卷管理
1、bind mount数据卷
2、docker managed数据卷
编辑
3、数据卷容器
六、docker的安全优化
1、docker的资源限定
(1)、限定cpu的利用量
(2)、限定cpu的优先级
(3)、限定内存利用
(4)、限定docker的磁盘io
七、docker的安全加固
1、docker默认隔离性
2、解决默认隔离性问题
4、容器特权
5、容器白名单
八、容器编排工具Docker Compose
1、基础操作
2、构建和重新构建服务
3、其他操作
4、Docker Compose 的yml文件
(1)、服务
(2)、网络
(3)、存储卷
九、利用docker编排完成haproxy和nginx负载均衡架构
1、只下载haproxy,找出haproxy的设置文件,编辑设置文件
2、编辑docker compose容器编排文件
3、启动容器
4、检察是否启动
5、写入网页内容
6、测试
准备工作:
搭建当地网络源:
- cd /etc/yum.repos.d/
- vim docker-ce.repo
复制代码
一、基础操作
- #拉取镜像
- [root@decker-node1 ~]# docker pull nginx:1.26-alpine
- #查看本地镜像
- [root@decker-node1 ~]# docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- nginx latest 5ef79149e0ec 12 days ago 188MB
- busybox latest 65ad0d468eb1 15 months ago 4.26MB
- timinglee/game2048 latest 19299002fdbe 7 years ago 55.5MB
- timinglee/mario latest 9a35a9e43e8c 8 years ago 198MB
- #查看镜像(nginx)
- [root@decker-node1 ~]# docker image inspect nginx
- #保存镜像
- [root@decker-node1 ~]# docker image save nginx:latest -o nginx-latest.tar.gz
- [root@Docker-node1 ~]# docker ps #查看当前运行容器
- [root@Docker-node1 ~]# docker ps -a #查看所有容器
- [root@Docker-node1 ~]# docker inspect busybox #查看容器运行的详细信息
- [root@Docker-node1 ~]# docker stop busybox #停止容器
- [root@Docker-node1 ~]# docker kill busybox #杀死容器,可以使用信号
- [root@Docker-node1 ~]# docker start busybox #开启停止的容器
复制代码- [root@docker-node1 ~]# docker load -i game2048.tar.gz
- [root@docker-node1 ~]# docker load -i mario.tar.gz
- [root@docker-node1 ~]# docker images
- REPOSITORY TAG IMAGE ID CREATED SIZE
- timinglee/game2048 latest 19299002fdbe 7 years ago 55.5MB
- timinglee/mario latest 9a35a9e43e8c 8 years ago 198MB
- [root@docker-node1 ~]# docker run -d --rm --name game1 -p 80:8080 timinglee/mario
- [root@docker-node1 ~]# docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 475d1ada9324 timinglee/mario "python3 -m http.ser…" 2 minutes ago Up 2 minutes 0.0.0.0:80->8080/tcp, :::80->8080/tcp game1
- [root@docker-node1 ~]# docker rm -f game1
- game1
- [root@docker-node1 ~]# docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
复制代码
二、构建镜像
1、参数示例及利用方法
FROM 指定 base 镜像 eg : FROM busybox:version COPY 复制文件 eg : COPY file /file 大概 COPY [“file”,”/”] MAINTAINER 指定作者信息,比如邮箱 eg : MAINTAINER user@example.com 在最新版的 docker 中用 LABEL KEY="VALUE" 代替 ADD 功能和 copy 相似,指定压缩文件或 url eg: ADD test.tar /mnt 大概 eg : ADD http://ip/test.tar /mnt ENV 指定情况变量 eg : ENV FILENAME test EXPOSE 暴漏容器端口 eg : EXPOSE 80 VOLUME 申明数据卷,通常指数据挂载点 eg : VOLUME [“/var/www/html”] WORKDIR 切换路径 eg : WORKDIR /mnt RUN 在容器中运行的指令 eg: touch file CMD 在启动容器时自动运举措作可以被覆盖 eg : CMD echo $FILENAME 会调用 shell 解析 eg : CMD [“/bin/sh”,”-c”,“echo $FILENAME”] 不调用 shell 解析 ENTRYPOINT 和 CMD 功能和用法雷同,但动作不可被覆盖 - [root@decker-node1 ~]# cd docker/
- [root@decker-node1 docker]# touch dockerfile
- [root@decker-node1 docker]# vim dockerfile
- volume:
- docker inspect test #查看挂载点、宿主机的目录
复制代码
2、Docker构建实例
删除没有挂在成功的镜像:
- [root@decker-node1 docker]# docker rmi `docker images | awk '/none/{print $2}'`
- [root@decker-node1 docker]# docker rmi 04f578596280 931faa592f44
复制代码 加载centos7镜像:
- [root@decker-node1 docker]# docker load -i centos-7.tar.gz
复制代码 编写构建文件:
开始构建:
- root@decker-node1 docker]# docker build -t nginx:v1 .
复制代码 构建时出现报错:yum时间出现问题->原因是centos镜像的问题
- dnf install httpd -y
- #配置文件的端口改为8888
- systemctl restart httpd
复制代码 新加cdroom:
挂载当地软件堆栈sr1:
开启centos7容器:
- [root@decker-node1 ~]# docker run -it --name centos centos:7
复制代码 设置该容器的当地软件堆栈:
将设置好的容器提交镜像(centos的repo版本)
- [root@decker-node1 ~]# docker commit -m "add repo" centos centos:repo
复制代码 修改构建文件:
继承构建nginx镜像:
- [root@decker-node1 docker]# docker build -t busybox:v1 .
复制代码
可以看到nginx:vi版本有356MB,可以进行优化淘汰巨细。
3、镜像优化示例
缩减镜像层:
- [root@decker-node1 docker]# vim dockerfile
复制代码
可以看出nginx:v1版本变小了(292MB):
多阶段构建:
可以看出nginx:v2版本变小(210MB):
利用最精简镜像
加载nginx1.23镜像和最小精简镜像:
- [root@decker-node1 docker]# docker load -i nginx-1.23.tar.gz
- [root@decker-node1 docker]# docker load -i debian11.tar.gz
复制代码 编辑构建文件:
可以看到nginx:v3版本只有34.5MB:
三、docker镜像堆栈管理
1、docker hub
2、搭建私有堆栈
(1)、搭建简单无加密私有堆栈
下载镜像:
- [root@decker-node1 ~]# docker load -i registry.tag.gz
复制代码 开启容器:
- [root@decker-node1 ~]# docker run -d -p 5000:5000 --restart=always registry
复制代码 给要上传的镜像添加标签:
- [root@decker-node1 ~]# docker tag nginx:v2 172.25.254.100:5000/nginx:v2
复制代码 设置非加密端口:
daemon.json是 Docker 的设置文件,通常位于/etc/docker/目录下(不同系统可能有所不同)。
以下是一个示例的daemon.json文件内容及表明:
json
复制
{
"registry-mirrors": ["https://your-custom-mirror.com"],
"insecure-registries": ["your-insecure-registry:port"],
"max-concurrent-downloads": 10,
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
}
}
表明:
"registry-mirrors": 指定 Docker 镜像加速地址,可以进步拉取镜像的速度。
"insecure-registries": 指定不安全的私有镜像堆栈地址,如果你的私有堆栈没有利用 HTTPS,必要将其添加到这个列表中。
"max-concurrent-downloads": 设置同时下载的最大层数,可根据系统资源和网络情况调整。
"log-driver": 设置日志驱动,这里设置为json-file表示以 JSON 格式的文件记录日志。
"log-opts": 日志相关的选项,这里设置了单个日志文件最大为10m,最多保存3个日志文件。
你可以根据本身的需求对daemon.json进行设置。修改后,通常必要重启 Docker 服务使设置生效。
- [root@decker-node1 ~]# vim /etc/docker/daemon.json
- [root@decker-node1 ~]# systemctl restart docker
复制代码
上传:
- [root@decker-node1 ~]# docker push 172.25.254.100:5000/nginx:v2
复制代码
检察镜像上传:
- [root@decker-node1 docker]# curl 172.25.254.100:5000/v2/_catalog
复制代码
(2)、搭建加密的私有堆栈
天生认证证书和key
- #删除配置文件的非加密配置
- [root@decker-node1 ~]# vim /etc/docker/daemon.json
- [root@decker-node1 ~]# systemctl restart docker
- mk[root@decker-node1 ~]# mkdir certs
- #添加解析
- [root@decker-node1 ~]# vim /etc/hosts
- 172.25.254.100 decker-node1 reg.gaoyingjie.org
- #生成key和证书
- [root@decker-node1 ~]# openssl req -newkey rsa:4096 \
- > -nodes -sha256 -keyout certs/gaoyingjie.org.key \
- > -addext "subjectAltName = DNS:reg.gaoyingjie.org" \
- > -x509 -days 365 -out certs/gaoyingjie.org.crt
复制代码
让docker读取证书:
- [root@decker-node1 ~]# mkdir /etc/docker/certs.d/reg.gaoyingjie.org/ -p
- [root@decker-node1 ~]# cp /root/certs/gaoyingjie.org.crt /etc/docker/certs.d/reg.gaoyingjie.org/ca.crt
- [root@decker-node1 ~]# systemctl restart docker
复制代码 开启registry容器:
- [root@decker-node1 ~]# docker run -d -p 443:443 --restart=always --name registry \
- > --name registry -v /opt/registry:/var/lib/registry \
- > -v /root/certs:/certs \
- > -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
- > -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/gaoyingjie.org.crt \
- > -e REGISTRY_HTTP_TLS_KEY=/certs/gaoyingjie.org.key registry:latest
- #-v: 挂载目录,容器下有该目录
复制代码 添加tag标签:
- [root@decker-node1 docker]# docker tag busybox:latest reg.gaoyingjie.org/busybox:latest
复制代码
上传:
- [root@decker-node1 docker]# docker push reg.gaoyingjie.org/busybox:latest
复制代码 检察上传的镜像:
- [root@decker-node1 docker]# curl -k https://reg.gaoyingjie.org/v2/_catalog
复制代码
(3)、搭建用户认证的私有堆栈
表明:必要用户输入密码才气的上传到搭建的私有堆栈。
创建认证文件(利用md5加密):
- [root@decker-node1 ~]# mkdir auth
- [root@decker-node1 ~]# htpasswd -Bc auth/htpasswd gaoyingjie #-B:最强加密方式
- New password:
- Re-type new password:
- Adding password for user gaoyingjie
复制代码 开启容器, 添加认证到registry容器中: - [root@decker-node1 ~]# docker run -d -p 443:443 --restart=always --name registry --name registry -v /opt/registry:/var/lib/registry -v /root/certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/gaoyingjie.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/gaoyingjie.org.key -v /root/auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry
复制代码 登录私有堆栈:
- [root@decker-node1 ~]# docker login reg.gaoyingjie.org
- Authenticating with existing credentials...
- WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
- Configure a credential helper to remove this warning. See
- https://docs.docker.com/engine/reference/commandline/login/#credential-stores
- Login Succeeded
复制代码 上传镜像:
- [root@decker-node1 ~]# docker push reg.gaoyingjie.org/busybox:latest
复制代码 检察上传的镜像:
- curl -k https://172.25.254.100/v2/ catalog -ugaoyingjie:gaoyingjie
复制代码 若未登录私有堆栈:则表现上传失败。
3、构建企业级私有堆栈-harbor
在第2步的基础上摆设harbor
- [root@docker ~]# tar zxf harbor-offline-installer-v2.5.4.tgz
- [root@docker ~]# ls
- anaconda-ks.cfg certs harbor-offline-installer-v2.5.4.tgz
- auth harbor
- [root@docker ~]# cd harbor/
- [root@docker harbor]# cp harbor.yml.tmpl harbor.yml
- [root@docker harbor]# vim harbor.yml
复制代码
天生证书和key:
- [root@docker-harbor harbor]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/gaoyingjie.org.key -addext "subjectAltName = DNS:reg.gaoyingjie.org" -x509 -days 365 -out certs/gaoyingjie.org.crt
复制代码 将证书和key放入设置文件里指定目录:
- [root@decker-node1 harbor]# mkdir /data
- [root@decker-node1 harbor]# cp -r /root/certs/ /data/
- [root@decker-node1 harbor]# ls /data/
- certs
- #让docker读取证书
- [root@docker-harbor certs]# cp /root/certs/gaoyingjie.org.crt /etc/docker/certs.d/reg.gaoyingjie.org/ca.crt
复制代码 安装harbor:
- [root@decker-node1 harbor]# ./install.sh --with-chartmuseum
复制代码
启动harbor:
- [root@decker-node1 harbor]# docker compose stop
- [root@decker-node1 harbor]# docker compose up -d
复制代码 当地解析:
登录harbor:浏览器输入reg.gaoyingjie.org(堆栈名,也就是hostname)
新建项目:
上传镜像到堆栈新建项目newtest:
- #登录harbor私有仓库
- #先将之前的退出,如果没登陆过则不用
- [root@decker-node1 harbor]# docker logout reg.gaoyingjie.org
- Removing login credentials for reg.gaoyingjie.org
- #登录
- [root@decker-node1 harbor]# docker login reg.gaoyingjie.org
- Username: admin
- Password:
- WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
- Configure a credential helper to remove this warning. See
- https://docs.docker.com/engine/reference/commandline/login/#credential-stores
- Login Succeeded
复制代码 添加标签:
- [root@decker-node1 harbor]# docker tag nginx:v3 reg.gaoyingjie.org/newtest/nginx:v3
复制代码 上传镜像:
- [root@decker-node1 harbor]# docker push reg.gaoyingjie.org/newtest/nginx:v3
复制代码 可以看到已上传nginx
小tip:
- #一键加载镜像
- #所有的镜像文件在/root/images下
- [root@docker-harbor images]# for i in `ls /root/images`; do docker load -i $i; done
- #一键清除所有容器(慎重)
- [root@docker-harbor harbor]# docker container prune -f
- #一键添加标签
- [root@docker-harbor ~]# docker images | awk 'NR>1{system("docker tag "$1":"$2" reg.gaoyingjie.org/library/"$1":"$2)}'
- #一键push
- [root@docker-harbor ~]# docker images | awk '/reg.gaoyingjie.org/{system("docker push "$1":"$2)}'
- #一键删除某些镜像
- [root@k8s-master ~]# docker images | awk '/reg.timinglee.org/{system("docker rmi "$1":"$2)}'
复制代码 四、docker的网络
修改防火墙策略
- [root@decker-node1 ~]# grubby --update-kernel ALL --args iptables=true
- [root@decker-node1 ~]# reboot
复制代码
1、dacker的原生网络
(1)、bridge
(2)、host
(3)、none
2、docker的自界说网络
自界说桥接:原生的桥接模式是没有dns模块,所以要用自界说桥接,可以用容器名称通信。
容器的开启序次不同会导致ip不同,会导致容器之间通讯出现问题。
- [root@docker-node1 ~]# docker network create mynet1 -d bridge
- 7e2fe742ddd7221d316d60276be1078e28f09ae1b2b6ca1ec79f8df5ca31ceda
- [root@docker-node1 ~]# docker network ls
- NETWORK ID NAME DRIVER SCOPE
- ad53e07c3e80 bridge bridge local
- 12e886188af6 host host local
- 7e2fe742ddd7 mynet1 bridge local
- cf8dda13f1cb none null local
- [root@docker-node1 ~]# docker run -it --name test1 --network mynet1 busybox
- [root@docker-node1 ~]# docker run -it --name test2 --network mynet1 busybox
- #删除网络
- [root@docker-node1 ~]# docker network rm mynet1
- mynet1
- [root@docker-node1 ~]# docker network ls
- NETWORK ID NAME DRIVER SCOPE
- ad53e07c3e80 bridge bridge local
- 12e886188af6 host host local
- cf8dda13f1cb none null local
复制代码
可以看出,两个容器test1和test2处于同一网络,之间可以用ip通信,也可以用容器名通信。而传统的桥接模式是不能用容器名称通信的。
3、不同的自界说网络之间的通信
有两种情况:用雷同网络栈和不同网络栈
(1)、容器用不同的网络栈
- #创建两个自定义桥接网络
- [root@docker-node1 ~]# docker network create mynet1 -d bridge
- 2a79172a5fe1a4b433c3daf4bdefaabf89b0a656aa5e7a07c007ae6a05a7b078
- [root@docker-node1 ~]# docker network create mynet2 -d bridge
- a79928a1c7ec8d4037863138b02a5fb967254ee3a560388572b0b16fd6ae0745
复制代码
可以看到不同自界说网络是是不能通信的。
将一个容器参加网卡接入另一个网络中:
- #将test2接入mynet1网络中
- #所以test2容器有172.28.0.2(mynet1)和172.19.0.2(mynet2)两个ip
- [root@docker-node1 ~]# docker network connect mynet1 test2
复制代码
(2)、容器用雷同的网络战栈-joined网络
示例1:
- [root@docker-node1 ~]# docker run -d --name test1 --network mynet1 nginx
- 8d1ad6dd316d38816f509a8db9ab1c057d766e8c92b437b98b4c72578eb4700c
- #用mynet2的网络栈
- [root@docker-node1 ~]# docker run -d --name test2 --network container:test1 centos:7
- 7ae5ac441717042123b0ddf964a1918725dfc2070709200772d46a900c79b343
复制代码 镜像centos是没有web服务的,但是test1和test2用了同个网络栈,所以test2有wab服务:
示例2:
phpmyadmin和mysql两个容器共用一个网络栈,phpmyadmin通过回环接口就能管理mysql,更安全。
- [root@docker-node1 ~]# docker load -i mysql-5.7.tar.gz
- [root@docker-node1 ~]# docker load -i phpmyadmin-latest.tar.gz
- [root@docker-node1 ~]# docker network create mynet1 -d bridge
- #开启phpmyadmin容器
- [root@docker-node1 ~]# docker run -d --name mysqladmin --network mynet1 \
- > -e PMA_ARBITRARY=1 \
- > -p 80:80 phpmyadmin:latest
- #开启mysql容器
- [root@docker-node1 ~]# docker run -d --name mysql \
- > -e MYSQL_ROOT_PASSWORD='gyj' \
- > --network container:mysqladmin \
- > mysql:5.7
复制代码 登录:浏览器输入172.25.254.100
在mysql容器内实行命令:
- [root@docker-node1 ~]# docker exec -it mysql bash
- bash-4.2#
复制代码
也可以用phpmyadmin管理数据库。
4、容器内外网的访问
(1)、容器访问外网
(2)、外网访问容器
5、容器的跨主机网络通信
macvlan
在两台 docker 主机上各添加一块网卡,打开网卡混杂模式: - [root@docker-node1 ~]# ip link set eth1 promisc on
- [root@docker-node1 ~]# ip link set up eth1
复制代码
两主机添加macvlan网络:
- [root@docker-node2 ~]# docker network create -d macvlan --subnet 1.1.1.0/24 --gateway 1.1.1.1 -o parent=eth1 macvlan1
复制代码 开启容器:
- [root@docker-node1 ~]# docker run -it --name test1 --network macvlan1 --ip 1.1.1.100 --rm busybox
- [root@docker-node2 ~]# docker run -it --name test2 --network macvlan1 --ip 1.1.1.200 --rm busybox
复制代码 测试:开处于不同主机的两个容器是否可以通信
五、docker的数据卷管理
1、bind mount数据卷
- 是将主机上的目录或文件mount到容器里。
- 利用直观高效,易于明白。
- 利用 -v 选项指定路径。
- [root@docker-node1 ~]# docker run -it --rm -v /test1:/data1:rw -v /etc/passwd:/data2/passwd:ro busybox
复制代码
2、docker managed数据卷
- bind mount必须指定host文件系统路径,限定了移植性
- docker managed volume 不必要指定mount源,docker自动为容器创建数据卷目录
- 默认创建的数据卷目录都在 /var/lib/docker/volumes 中
- 如果挂载时指向容器内已有的目录,原有数据会被复制到volume中
- [root@docker-node1 ~]# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD='gyj' mysql:5.7[root@docker-node1 ~]#cd /var/lib/docker/volumes/09c6f145e4449d1cbdfd5118fdd869adb32573a4195c18dc22a6ac93f3c7596b/_data/[root@docker-node1 _data]# touch newfile#进入容器检察是否有newfile[root@docker-node1 ~]# docker exec -it mysql bash
- bash-4.2# cd /var/lib/mysqlbash-4.2# ls
复制代码
可以看到没有指定数据卷目录,默认在挂载到host的/var/lib/docker/volume/容器id/_data中,在此目录下新建文件,可以在容器内部的/var/lib/容器名/中看到新文件。
3、数据卷容器
数据卷容器( Data Volume Container )是 Docker 中一种特殊的容器,重要用于方便地在多个容器之间 共享数据卷。 - #建立数据卷容器
- [root@docker ~]# docker run -d --name datavol \
- -v /tmp/data1:/data1:rw \
- -v /tmp/data2:/data2:ro \
- -v /etc/resolv.conf:/etc/hosts busybox
- #使用数据卷容器
- [root@docker ~]# docker run -it --name test --rm --volumes-from datavol busybox
复制代码 六、docker的安全优化
- [root@docker-node1 ~]# docker run -d --name web nginx
- 516df6628241e9b4f3e802cbef696163ce681070d739b8ae716efe74708466c7
- [root@docker-node1 ~]# docker inspect web | grep Pid
- "Pid": 1898,
- "PidMode": "",
- "PidsLimit": null,
- [root@docker-node1 ~]# cd /proc/
- [root@docker-node1 proc]# cd 1898
- [root@docker-node1 1898]# cd ns
- [root@docker-node1 ns]# ls
- cgroup ipc mnt net pid pid_for_children time time_for_children user uts
- [root@docker-node1 ns]# cd /sys/fs/cgroup/
- [root@docker-node1 cgroup]# ls
- blkio cpu,cpuacct freezer misc net_prio rdma
- cpu cpuset hugetlb net_cls perf_event systemd
- cpuacct devices memory net_cls,net_prio pids
- [root@docker-node1 cgroup]# cd memory/
- [root@docker-node1 memory]# cd docker/
- [root@docker-node1 docker]# ls
- 516df6628241e9b4f3e802cbef696163ce681070d739b8ae716efe74708466c7
- cgroup.clone_children
- cgroup.event_control
- ***
- [root@docker-node1 docker]# cd 516df6628241e9b4f3e802cbef696163ce681070d739b8ae716efe74708466c7/
- [root@docker-node1 516df6628241e9b4f3e802cbef696163ce681070d739b8ae716efe74708466c7]# ls
- cgroup.clone_children memory.memsw.failcnt
- cgroup.event_control memory.memsw.limit_in_bytes
- cgroup.procs memory.memsw.max_usage_in_bytes
- memory.failcnt memory.memsw.usage_in_bytes
- memory.force_empty memory.move_charge_at_immigrate
- memory.kmem.failcnt memory.numa_stat
- memory.kmem.limit_in_bytes memory.oom_control
- memory.kmem.max_usage_in_bytes memory.pressure_level
- memory.kmem.slabinfo memory.soft_limit_in_bytes
- memory.kmem.tcp.failcnt memory.stat
- memory.kmem.tcp.limit_in_bytes memory.swappiness
- memory.kmem.tcp.max_usage_in_bytes memory.usage_in_bytes
- memory.kmem.tcp.usage_in_bytes memory.use_hierarchy
- memory.kmem.usage_in_bytes notify_on_release
- memory.limit_in_bytes tasks
- memory.max_usage_in_bytes
复制代码 1、docker的资源限定
(1)、限定cpu的利用量
- [root@docker-node1 ~]# docker run -it --rm --name test1 --cpu-period 100000 --cpu-quota 20000 ubuntu
- root@3c63c90f85ef:/# dd if=/dev/zero of=/dev/null &
- [1] 9
- root@3c63c90f85ef:/# top
- [root@docker-node1 ~]# docker run -it --rm --name test2 --cpu-period 100000 --cpu-quota 30000 ubuntu
- root@9ba159f17589:/# dd if=/dev/zero of=/dev/null &
- [1] 9
- root@9ba159f17589:/# top
复制代码
(2)、限定cpu的优先级
- [root@docker-node1 ~]# docker run -it --rm --name test1 --cpu-shares 100 ubuntu
- root@0d33e9d6b5a3:/# dd if=/dev/zero of=/dev/null &
- [1] 8
- root@0d33e9d6b5a3:/# top
- [root@docker-node1 ~]# docker run -it --rm --name test2 ubuntu
- dd if=/dev/zero of=/dev/null &root@c30ea1c45318:/# dd if=/dev/zero of=/dev/null &
- [1] 9
- root@c30ea1c45318:/# top
复制代码
(3)、限定内存利用
上传工具:
- libcgroup-0.41-19.el8.x86_64.rpm
- libcgroup-tools-0.41-19.el8.x86_64.rpm
- [root@docker-node1 ~]# dnf install *.rpm -y
复制代码 开启容器并限定内存:
- [root@docker-node1 ~]# docker run -d --rm --name test1 --memory 200M --memory-swap 200M nginx
- 9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616
- [root@docker-node1 ~]# cd /sys/fs/cgroup/
- [root@docker-node1 cgroup]# cgexec -g memory:docker/9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=150
复制代码
检察该容器id下的内存资源限定文件,可以看到200m的字节为 209715200,也可通过echo写入文件将内存限定从200mb改为300mb:
- [root@docker-node1 ~]#cd /sys/fs/cgroup/memory/docker/9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616/
- [root@docker-node1 9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616]#
- cat memory.memsw.limit_in_bytes
- 209715200
- [root@docker-node1 9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616]# echo 314572800 > memory.memsw.limit_in_bytes
- [root@docker-node1 9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616]# cgexec -g memory:docker/9dec367f92ee6874fb5a6e543d369b1f0aa81f2ae8dff875ae30e1f710a04616 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=300
复制代码
(4)、限定docker的磁盘io
- [root@docker-node1 ~]# docker run -it --rm --device-write-bps /dev/nvme0n1:30M ubuntu
- root@452768b7f1e0:/# dd if=/dev/zero of=bigfile
- root@452768b7f1e0:/# dd if=/dev/zero of=bigfile bs=1M count=100
- root@452768b7f1e0:/# dd if=/dev/zero of=bigfile bs=1M count=100 oflag=direct
复制代码
七、docker的安全加固
1、docker默认隔离性
可以看到虽然限定了容器200m的内存,但是内存资源并没有完全隔离。
2、解决默认隔离性问题
LXCFS 是一个为 LXC ( Linux Containers )容器提供加强文件系统功能的工具。 LXCFS 可以使容器内的进程看到正确的 CPU 、内存和磁盘 I/O 等资源利用信息。在没有 LXCFS 时,容器内看到的资源信息可能不正确,这会影响到在容器内运行的应用步伐对资源的评估和管理。 安装lxcfs
- [root@docker-node1 ~]# cd /mnt/
- [root@docker-node1 mnt]# ls
- hgfs lxc-libs-4.0.12-1.el9.x86_64.rpm
- lxcfs-5.0.4-1.el9.x86_64.rpm lxc-templates-4.0.12-1.el9.x86_64.rpm
- [root@docker-node1 mnt]# dnf install *.rpm
复制代码 运行lxcfs解决隔离性问题:
- [root@docker-node1 ~]# lxcfs /var/lib/lxcfs &
复制代码 开启容器并指定内存:
- docker run -it --name test -m 256m -v /var/lib/lxcfs/proc/cpuinfo:/proc/cpuinfo:rw -v /var/lib/lxcfs/proc/diskstats:/proc/diskstats:rw -v /var/lib/lxcfs/proc/meminfo:/proc/meminfo:rw -v /var/lib/lxcfs/proc/stat:/proc/stat:rw -v /var/lib/lxcfs/proc/swaps:/proc/swaps:rw -v /var/lib/lxcfs/proc/uptime:/proc/uptime:rw ubuntu
复制代码
可以看到指定的内存为256m,容器表现的内存就为256m。
4、容器特权
5、容器白名单
八、容器编排工具Docker Compose
编辑vim设置文件:
1、基础操作
- [root@docker-node1 ~]# mkdir test
- [root@docker-node1 test]# cd test/
- #编辑yml文件
- [root@docker-node1 test]# vim docker-compose.yml
- #启动服务
- [root@docker-node1 test]# docker compose up -d
- [+] Running 3/3
- ✔ Network test_default Created 0.2s
- ✔ Container test-web-1 Started 1.6s
- ✔ Container test-test-1 Started 1.5s
- [root@docker-node1 test]# docker ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 1b571c4c09aa nginx:latest "/docker-entrypoint.…" 10 seconds ago Up 9 seconds 80/tcp test-web-1
复制代码
- [root@docker-node1 test]# cp docker-compose.yml new-compose.yml
- [root@docker-node1 test]# rm -rf docker-compose.yml
- [root@docker-node1 test]# vim new-compose.yml
- #可以使用-f 来指定yml文件
- [root@docker-node1 test]# docker compose -f new-compose.yml up -d
- [+] Running 2/2
- ✔ Container test-test-1 Started 1.1s
- ✔ Container test-web-1 Started
- #停止正在运行的服务
- [root@docker-node1 test]# docker compose stop
- [+] Stopping 2/2
- ✔ Container test-web-1 Stopped 0.1s
- ✔ Container test-test-1 Stopped 0.0s
- #重启服务
- [root@docker test]# docker compose restart
- #停止并删除配置文件中定义的所有服务以及相关的网络和存储卷。
- [root@docker test]# docker compose down
- #查看状态
- [root@docker-node1 test]# docker compose ps
- NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
- test-web-1 nginx:latest "/docker-entrypoint.…" web About a minute ago Up 11 seconds 80/tcp
复制代码 2、构建和重新构建服务
编辑构建docker的文件:
- [root@docker-node1 test]# vim Dockerfile
- [root@docker-node1 test]# vim new.Dockerfile
复制代码
写重新构建的文件:在之前test1、test2的基础上重新构建
- [root@docker-node1 test]# vim docker-compose.yml
复制代码
构建生效:
- #build
- [root@docker-node1 test]# docker compose -f docker-compose.yml build#构建
- services中所有
- [root@docker test]# docker compose -f test.yml build test1 #构建
- services中的test1
复制代码 可以看到构建的新镜像:test1、test2
开启容器:可以看到旧的test1、test2构建时创建的文件
以上是构建好镜像后手动开启容器。
自动开启容器:
- # --build
- [root@docker test]# docker compose -f docker-compose.yml up -d #会去仓库拉去镜
- 像
- [root@docker test]# docker compose -f docker-compose.yml up --build #会先构建镜像后
- 启动容器
复制代码 可以看到自动开启容器:
3、其他操作
- [root@docker-node1 test]# vim docker-compose.yml
- [root@docker-node1 test]# vim docker-compose.yml
- [root@docker-node1 test]# docker compose -f docker-compose.yml up -d
- #在正在运行的服务容器中执行命令
- [root@docker-node1 test]# docker compose -f docker-compose.yml exec test1 sh
- / # touch newfile
- / # ls
- bin etc lib newfile root tmp var
- dev home lib64 proc sys usr
- / #
复制代码
拉取设置文件中界说的服务所利用的镜像。 - [root@docker test]# docker compose -f docker-compose.yml pull
- [+] Pulling 2/2
- ✔ test Pulled
- ✔ ec562eabd705 Pull complete
复制代码
验证并检察解析后的 Compose 文件内容 - [root@docker-node1 test]# docker compose config
- name: test
- services:
- test1:
- command:
- - /bin/sh
- - -c
- - sleep 3000
- container_name: busybox1
- image: busybox:latest
- networks:
- default: null
- restart: always
- networks:
- default:
- name: test_default
复制代码 4、Docker Compose 的yml文件
(1)、服务
- #服务名称(service1_name/service2_name 等):每个服务在配置文件中都有一个唯一的名称,用于在命令行和其他部分引用该服务。
- services:
- web:
- # 服务1的配置
- mysql:
- # 服务2的配置
复制代码- #镜像(image):
- #指定服务所使用的 Docker 镜像名称和标签。例如, image: nginx:latest 表示使用 nginx镜像的最新版本
- services:
- web:
- images:nginx
- mysql:
- images:mysql:5.7
复制代码- #将容器内部的端口映射到主机的端口,以便外部可以访问容器内的服务。例如, -"8080:80" 表示将主机的 8080 端口映射到容器内部的 80 端口。
- services:
- web:
- image: nginx:latest
- container_name: nginx1 #指定容器名称
- restart: always #docekr容器自动启动
- expose:
- - 1234 #指定容器暴露那些端口,些端口仅对链接的服务可见,不会映射到主机的端口
- ports:
- - "80:8080"
复制代码- #环境变量(environment):为容器设置环境变量,可以在容器内部的应用程序中使用。例如, VAR1: value1 设置环境变量 VAR1 的值为 value1
- services:
- web:
- image: mysql:5.7
- container_name: mysql1
- restart: always
- environment:
- MYSQL_ROOT_PASSWORD: gyj
复制代码- #存储卷(volumes):将主机上的目录或文件挂载到容器中,以实现数据持久化或共享。例如, -
- /host/data:/container/data 将主机上的 /host/data 目录挂载到容器内的/container/data 路径。
- services:
- test:
- image: busybox
- command: ["/bin/sh","-c","sleep 3000"]
- restart: always
- container_name: busybox1
- volumes:
- - /etc/passwd:/tmp/passwd:ro #只读挂在本地文件到指定位置
复制代码- #网络(networks):将服务连接到特定的网络,以便不同服务的容器可以相互通信
- services:
- web:
- image: nginx
- container_name: webserver
- network_mode: bridge #使用本机自带bridge网络
- services:
- test:
- image: busybox
- container_name: webserver
- command: ["/bin/sh","-c","sleep 10000"]
- #network_mode: mynet2
- networks:
- - mynet1
- - mynet2
- networks:
- mynet1:
- driver: bridge
- mynet2:
- driver: bridge
复制代码- #命令(command):覆盖容器启动时默认执行的命令。例如, command: python app.py 指定容器启动时运行
- python app.py 命令
- [root@docker test]# vim busybox.yml
- services:
- web:
- image: busybox
- container_name: busybox
- #network_mode: mynet2
- command: ["/bin/sh","-c","sleep10000000"]
复制代码 (2)、网络
- 界说 Docker Compose 应用步伐中利用的网络。可以自界说网络名称和驱动步伐等属性。
- 默认情况下docker compose 在实行时会自动创建网路
- services:
- test:
- image: busybox1
- command: ["/bin/sh","-c","sleep 3000"]
- restart: always
- network_mode: default
- container_name: busybox
- test1:
- image: busybox2
- command: ["/bin/sh","-c","sleep 3000"]
- restart: always
- container_name: busybox1
- networks:
- - mynet1
- test3:
- image: busybox3
- command: ["/bin/sh","-c","sleep 3000"]
- restart: always
- container_name: busybox1
- networks:
- - mynet1
- networks:
- mynet1:
- driver: bridge #使用桥接驱动,也可以使用macvlan用于跨主机连接
- default:
- external: true #不建立新的网络而使用外部资源
- name: bridge #指定外部资源网络名字
- mynet2:
- ipam:
- driver: default
- config:
- - subnet: 172.28.0.0/16
- gateway: 172.28.0.254
复制代码 (3)、存储卷
- services:
- test:
- image: busybox
- command: ["/bin/sh","-c","sleep 3000"]
- restart: always
- container_name: busybox1
- volumes:
- - data:/test #挂在data卷
- - /etc/passwd:/tmp/passwd:ro #只读挂在本地文件到指定位置
- volumes:
- data:
- name: timinglee #指定建立卷的名字
复制代码 九、利用docker编排完成haproxy和nginx负载均衡架构
1、只下载haproxy,找出haproxy的设置文件,编辑设置文件
- #只下载不安装haproxy
- [root@docker-node1 ~]# dnf install haproxy -y --downloadonly --downloaddir=/mnt
- #解压文件并输出为目录,-id:i是输出,d是目录
- [root@docker-node1 mnt]# rpm2cpio haproxy-2.4.22-1.el9.x86_64.rpm | cpio -id
复制代码
2、编辑docker compose容器编排文件
- [root@docker-node1 ~]# vim haproxy.yml
复制代码
3、启动容器
- [root@docker-node1 ~]# docker compose -f /root/haproxy.yml up -d
复制代码
4、检察是否启动
5、写入网页内容
从设置文件可以看到,在主机的/var/lib/docker/volumes/data_web目录下,有data_web1和data_web2,这两个文件挂载的是nginx容器的网站首发内容页,所以在data_web1、data_web2这两个目录下写入网站首页内容。
6、测试
haproxy用的是轮询调治算法
删除镜像、加速器、volume
ldd /usr/local/nginx/sbin/nginx nginx运行时必须调用的模块
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |