docker容器技术

一、docker安装

[root@docker ~]# mkdir docker

[root@docker ~]# cd docker/

[root@docker docker]# tar zxf docker.tar.gz

[root@docker docker]# yum  --allowerasing install *.rpm -y

[root@docker docker]# vim /usr/lib/systemd/system/docker.service

[root@docker ~]# systemctl enable --now docker

二、Docker的基本操作

1、 Docker镜像管理

#搜索镜像

[root@docker ~]# docker search nginx

#加载本地镜像

[root@docker docker]# docker load -i nginx-1.23.tar.gz

#拉取镜像

[root@docker docker]# docker pull nginx:1.23

#查看本地镜像

[root@docker docker]# docker images

REPOSITORY        TAG       IMAGE ID       CREATED         SIZE

nginx             1.23      a7be6198544f   15 months ago   142MB

busybox           latest    65ad0d468eb1   15 months ago   4.26MB

timinglee/mario   latest    9a35a9e43e8c   8 years ago     198MB

#查看镜像信息

[root@docker docker]# docker image inspect nginx:1.23

#保存镜像

[root@docker docker]# docker image save nginx:1.23 -o nginx-1.23.tar.gz

#保存所有镜像

[root@docker docker]# docker save `docker images | awk 'NR>1{print $1":"$2}'` -o images.tar.gz

#删除镜像

[root@docker docker]# docker rmi nginx:1.23

2、容器常用操作

启动容器

#启动容器

[root@docker docker]# docker run -d --name mario -p 80:8080 timinglee/mario

[root@docker docker]# docker run -it --name busybox -p 80:8080 busybox:latest

#进入到容器中,按<ctrl>+<d>退出并停止容器,#按<ctrl>+<pq>退出但

不停止容器

/ #

#重新进入容器

[root@docker docker]# docker attach busybox

/ #

#在容器中执行命令

[root@docker docker]# docker exec -it busybox ifconfig

容器启动时的命令参数

-d #后台运行

-i #交互式运行

-t #打开一个终端

--name #指定容器名称

-p #端口映射 -p 80:8080 把容器8080端口映射到本机80端口

--rm #容器停止自动删除容器

--network #指定容器使用的网络

查看容器运行信息

#查看当前正在运行的容器信息

[root@docker docker]# docker ps

CONTAINER ID   IMAGE            COMMAND   CREATED          STATUS          PORTS                                   NAMES

3509fb8a151d   busybox:latest   "sh"      12 minutes ago   Up 12 minutes   0.0.0.0:80->8080/tcp, :::80->8080/tcp   busybox

#查看所有容器的运行信息

[root@docker docker]# docker ps -a

停止和运行容器

#停止容器

[root@docker docker]# docker stop busybox

#杀死容器,可以使用信号

[root@docker docker]# docker kill busybox

#开启停止的容器

[root@docker docker]# docker start busybox

删除容器

#删除停止的容器

[root@docker docker]# docker rm busybox

#删除运行的容器

[root@docker docker]# docker rm -f busybox

#删除所有停止的容器

[root@docker docker]# docker container prune -f

容器内容提交

默认情况下,容器被删除后,在容器中的所有操作都会被清理,包括要保存的文件。如果想永久保存,那么我们需要把动作提交,提交后会生成新的镜像,当我们在运行新镜像后即可看到我们提交的内容。

#在容器中建立文件

[root@docker docker]# docker attach busybox

/ # touch dufile

#删除容器

[root@docker docker]# docker rm -f busybox

#删掉容器后开启新的容器文件不存在

[root@docker docker]# docker run -it --name busybox busybox:latest

/ # ls

bin    dev    etc    home   lib    lib64  proc   root   sys    tmp    usr    var

#内容提交

[root@docker docker]# docker commit -m "add dufile" busybox busybox:latest

[root@docker docker]# docker image history busybox:latest

系统中的文件和容器中的文件传输

#把容器中的文件复制到本机

[root@docker docker]# docker cp busybox:/dufile /mnt

#把本机文件复制到容器中

[root@docker docker]# docker cp /etc/fstab busybox:/fstab

查询容器内部日志

[root@docker docker]# docker logs busybox

三、docker镜像构建

1、构建参数

参数示例及用法

#FROM、LABEL KEY、RUN

[root@docker docker]# vim Dockerfile

[root@docker docker]# docker build -t example:v1 .

#ADD

[root@docker docker]# touch dufile{1..3}

[root@docker docker]# tar zcf dufile.gz dufile*

[root@docker docker]# vim Dockerfile

[root@docker docker]# docker build -t example:v2 .

[root@docker docker]# docker run -it --rm example:v2

/ # ls

#ENV、CMD

[root@docker docker]# vim Dockerfile

[root@docker docker]# docker build -t example:v3 .

[root@docker docker]# docker run -it --rm example:v3

du

#ENTRYPOINT

[root@docker docker]# vim Dockerfile

[root@docker docker]# docker rm -f example:v3

[root@docker docker]# docker build -t example:v3 .

[root@docker docker]# docker run -it --rm example:v3 sh

du.org

#EXPOSE、VOLUME、VOLUME

[root@docker docker]# vim Dockerfile

[root@docker docker]# docker build -t example:v4 .

[root@docker docker]# docker run -it --rm example:v4

/var/www/html #

2、Dockerfile实例

#删除之前的镜像

[root@docker docker]# docker rmi example:v{1..4}

#加载centos镜像

[root@docker docker]# docker load -i centos-7.tar.gz

#编写构建文件

[root@docker docker]# vim Dockerfile

[root@docker docker]# docker build -t webserver:v1 .

解决centos报错问题

#下载httpd

[root@docker docker]# yum install httpd -y

[root@docker docker]# vim /etc/httpd/conf/httpd.conf

[root@docker docker]# systemctl start httpd

在虚拟机上添加rhel7.9的镜像

[root@docker docker]# mkdir /var/www/html/rhel7.9

[root@docker docker]# mount /dev/sr1 /var/www/html/rhel7.9/

浏览器访问

#运行centos容器

[root@docker docker]# docker run -it --name centos centos:7

#配置centos本地软件源

[root@c1d9f9f446c6 /]# cd /etc/yum.repos.d/

[root@c1d9f9f446c6 yum.repos.d]# rm -fr *

[root@c1d9f9f446c6 yum.repos.d]# vi centos7.repo

[root@docker ~]# docker commit -m "add repo" centos centos:repo

[root@docker docker]# vim Dockerfile

#生成镜像

[root@docker docker]# docker build -t nginx:v1 .

#测试镜像可用性

[root@docker ~]# docker images nginx:v1

REPOSITORY   TAG       IMAGE ID       CREATED          SIZE

nginx        v1        7704b7860028   29 minutes ago   356MB

3、镜像优化

缩减镜像层

[root@docker ~]# cd docker/

[root@docker docker]# vim Dockerfile

[root@docker docker]# docker build -t nginx:v2 .

[root@docker docker]# docker images nginx

多阶段构建

[root@docker docker]# vim Dockerfile

[root@docker docker]# docker build -t nginx:v3 .

[root@docker docker]# docker images nginx

使用最精简镜像

[root@docker docker]# docker load -i debian11.tar.gz

[root@docker docker]# docker load -i nginx-1.23.tar.gz

[root@docker docker]# vim Dockerfile

[root@docker docker]# docker build -t nginx:v4 .

[root@docker docker]# docker images nginx

四、docker 镜像仓库的管理

1、什么是docker仓库

Docker 仓库(Docker Registry) 是用于存储和分发 Docker 镜像的集中式存储库。 它就像是一个大型的镜像仓库,开发者可以将自己创建的 Docker 镜像推送到仓库中,也可以从仓库中拉 取所需的镜像。

Docker 仓库可以分为公共仓库和私有仓库:

公共仓库,如 Docker Hub,任何人都可以访问和使用其中的镜像。许多常用的软件和应用都有在 Docker Hub 上提供的镜像,方便用户直接获取和使用。

私有仓库则是由组织或个人自己搭建和管理的,用于存储内部使用的、不希望公开的镜像。

2、docker hub

Docker Hub 是 Docker 官方提供的一个公共的镜像仓库服务。

官网:https://hub.docker.com/

Docker Hub 是 Docker 官方提供的一个公共的镜像仓库服务。

它是 Docker 生态系统中最知名和广泛使用的镜像仓库之一,拥有大量的官方和社区贡献的镜像。 以下是 Docker Hub 的一些关键特点和优势:

1. 丰富的镜像资源:涵盖了各种常见的操作系统、编程语言运行时、数据库、Web 服务器等众多应用 的镜像。

例如,您可以轻松找到 Ubuntu、CentOS 等操作系统的镜像,以及 MySQL、Redis 等数据库 的镜像。

2. 官方支持:提供了由 Docker 官方维护的一些重要镜像,确保其质量和安全性。

3. 社区贡献:开发者们可以自由上传和分享他们创建的镜像,促进了知识和资源的共享。

4. 版本管理:对于每个镜像,通常都有多个版本可供选择,方便用户根据需求获取特定版本。

5. 便于搜索:用户可以通过关键词轻松搜索到所需的镜像。

3、docker仓库的工作原理

pull原理

镜像拉取分为以下几步:

1.docker客户端向index发送镜像拉取请求并完成与index的认证

2.index发送认证token和镜像位置给dockerclient

3.dockerclient携带token和根据index指引的镜像位置取连接registry

4.Registry会根据client持有的token跟index核实身份合法性

5.index确认此token合法性

6.Registry会根据client的请求传递镜像到客户端

push原理

镜像上传的步骤:

1.client向index发送上传请求并完成用户认证

2.index会发放token给client来证明client的合法性

3.client携带index提供的token连接Registry

4.Registry向index确认token的合法性

5.index证实token的合法性

6.Registry开始接收客户端上传过来的镜像

4、搭建docker的私有仓库

搭建简单的Registry仓库

下载Registry镜像

[root@docker docker]# docker load -i registry.tag.gz

#开启Registry

[root@docker docker]# docker run -d -p 5000:5000 --restart=always registry

以http方式上传镜像到仓库中

#给要上传的镜像打标签

[root@docker docker]# docker tag nginx:v1 172.25.254.100:5000/nginx:v1

#docker在上传的过程中默认使用https,但是我们并没有建立https认证需要的认证文件所以会报错

[root@docker docker]# docker push 172.25.254.100:5000/nginx:v1

The push refers to repository [172.25.254.100:5000/nginx]

Get "https://172.25.254.100:5000/v2/": http: server gave HTTP response to HTTPS client

#配置非加密端口

[root@docker docker]# vim /etc/docker/daemon.json

[root@docker docker]# systemctl restart docker

#上传镜像

[root@docker docker]# docker push 172.25.254.100:5000/nginx:v1

#查看镜像上传

[root@docker docker]# curl 172.25.254.100:5000/v2/_catalog

{"repositories":["nginx"]}

为Registry提供加密传输

[root@docker docker]# rm -fr /etc/docker/daemon.json

[root@docker docker]# mkdir /certs

[root@docker docker]# systemctl restart docker

[root@docker docker]# vim /etc/hosts

#生成认证key和证书

[root@docker docker]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout /certs/du.org.key -addext "subjectAltName = DNS:reg.du.org" -x509 -days 365 -out /certs/du.org.crt

#启动registry仓库

[root@docker docker]# docker run -d -p 443:443 --restart=always -v /opt/registry:/var/lib/registry -v /certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/du.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/du.org.key registry

#为客户端建立证书

[root@docker docker]# mkdir /etc/docker/certs.d/reg.du.org/ -p

[root@docker docker]# cp /certs/du.org.crt /etc/docker/certs.d/reg.du.org/ca.crt

[root@docker docker]# systemctl restart docker

#测试

[root@docker docker]# docker tag nginx:v2 reg.du.org/nginx:v2

[root@docker docker]# docker push reg.du.org/nginx:v2

为仓库建立登陆认证

#安装建立认证文件的工具包

[root@docker docker]# yum install httpd-tools -y

#建立认证文件

[root@docker docker]# mkdir /auth

#-B 强制使用最安全加密方式, 默认用md5加密

[root@docker docker]# htpasswd -Bc /auth/htpasswd du

#添加认证到registry容器中

[root@docker docker]# docker run -d -p 443:443 --restart=always -v /opt/registry:/var/lib/registry -v /certs:/certs -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/du.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/du.org.key -v /auth:/auth -e "REGISTRY_AUTH=htpasswd" -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd registry

[root@docker docker]# curl -k https://reg.du.org/v2/_catalog -u du:dyjxzq525717      {"repositories":["nginx"]}

#未登陆情况下不能上传镜像

#当仓库开启认证后必须登陆仓库才能进行镜像上传

[root@docker docker]# docker login reg.du.org

[root@docker docker]# docker push reg.du.org/nginx:v2

构建企业级私有仓库

#部署harbor

[root@docker docker]# tar zxf harbor-offline-installer-v2.5.4.tgz

[root@docker docker]# cd harbor/

[root@docker harbor]# cp harbor.yml.tmpl harbor.yml

[root@docker harbor]# mkdir -p /data/certs/

[root@docker harbor]# cp /certs/ /data/certs/

[root@docker harbor]# vim harbor.yml

[root@docker harbor]# ./install.sh --with-chartmuseum

[root@docker harbor]# docker compose up -d

#在windows的hosts文件中添加域名

#浏览器访问域名

#上传镜像

[root@docker harbor]# docker login reg.du.org

[root@docker harbor]# docker tag nginx:v3 reg.du.org/du/nginx.v3

[root@docker harbor]# docker push reg.du.org/du/nginx.v3

#查看上传的镜像

五、Docker 网络

1、docker的自定义网络

自定义桥接网络时,默认使用桥接模式

docker引擎在分配ip时时根据容器启动顺序分配,谁先启动谁用,是动态变更的。多容器互访用ip很显然不是很靠谱,多容器访问一般使用容器的名字访问更加稳定。docker原生网络是不支持dns解析的,自定义网络中内嵌了dns。

[root@docker docker]# grubby --update-kernel ALL --args iptables=true

[root@docker docker]# reboot

#不使用自定义网络不能用容器名字进行访问

[root@docker docker]# docker run -d --name test busybox:latest

[root@docker docker]# docker run -it --name test1 busybox:latest

#创建自定义网络后可以使用容器名字访问

[root@docker docker]# docker network create mynet1

[root@docker docker]# docker run -d --network mynet1 --name test2 busybox:latest

[root@docker docker]# docker run -it --network mynet1 --name test3 busybox:latest

#不同的自定义网络是不能通讯的

[root@docker docker]# docker network create mynet2

[root@docker docker]# docker run -it --network mynet2 --name test4 busybox:latest

2、joined容器网络

Joined容器一种较为特别的网络模式,•在容器创建时使用--network=container:vm1指定。(vm1指定 的是运行的容器名) 处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通 信。

joined网络示例演示

利用容器部署phpmyadmin管理mysql

[root@docker docker]# docker load -i phpmyadmin-latest.tar.gz

[root@docker docker]# docker load -i mysql-5.7.tar.gz

[root@docker docker]# docker run -d --name mysqladmin --network mynet1 -e PMA_ARBITRARY=1 -p 80:80 phpmyadmin:latest

[root@docker docker]# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD='123456' --network container:mysqladmin mysql:5.7

#浏览器访问172.25.254.100:80

开启的phpmyadmin容器中是没有数据库的,这里填写的localhost:3306是因为mysql容器和phpmyadmin容器公用一个网络站。

3、容器内外网的访问

容器访问外网

在rhel7中,docker访问外网是通过iptables添加地址伪装策略来完成容器网文外网

在rhel7之后的版本中通过nftables添加地址伪装来访问外网

外网访问docker容器

端口映射 -p 本机端口:容器端口来暴漏端口从而达到访问效果

#通过docker-proxy对数据包进行内转

#通过dnat策略来完成浏览内转

4、docker跨主机网络

在生产环境中,我们的容器不可能都在同一个系统中,所以需要容器具备跨主机通信的能力

跨主机网络解决方案:

docker原生的overlay和macvlan

第三方的flannel、weave、calico

众多网络方案是如何与docker集成在一起的:

libnetwork docker容器网络库

CNM (Container Network Model)这个模型对容器网络进行了抽象

CNM (Container Network Model)

CNM分三类组件 Sandbox:

容器网络栈,包含容器接口、dns、路由表。(namespace)

Endpoint:作用是将sandbox接入network (veth pair)

Network:包含一组endpoint,同一network的endpoint可以通信

macvlan网络方式实现跨主机通信

实现方式

1.在两台docker主机上各添加一块网卡,使用仅主机模式

2、打开网卡混杂模式

[root@docker ~]# ip link set eth1 promisc on

[root@docker ~]# ip link set up eth1

3、添加macvlan网路

以docker为例

[root@docker ~]# docker network create -d macvlan --subnet 1.1.1.0/24 --gateway 1.1.1.1 -o parent=eth1 macvlan1

4、测试

#在docker中

docker run -it --name busybox --network macvlan1 --ip 1.1.1.100 --rm busybox:latest

#在docker1中

[root@docker1 docker]# docker run -it --name busybox --network macvlan1 --ip 1.1.1.20  0 --rm busybox:latest

/ # ping 1.1.1.100

六、Docker 数据卷管理及优化

Docker 数据卷是一个可供容器使用的特殊目录,它绕过了容器的文件系统,直接将数据存储在宿主机 上。 这样可以实现以下几个重要的目的:

数据持久化:即使容器被删除或重新创建,数据卷中的数据仍然存在,不会丢失。

数据共享:多个容器可以同时挂载同一个数据卷,实现数据的共享和交互。

独立于容器生命周期:数据卷的生命周期独立于容器,不受容器的启动、停止和删除的影响。

1、bind mount 数据卷

是将主机上的目录或文件mount到容器里。

使用直观高效,易于理解。

使用 -v 选项指定路径,格式 : -v选项指定的路径,如果不存在,挂载时会自动创建。

[root@docker ~]# docker run -it --rm -v /tmp/date1:/date1 -v /tmp/date1:/date2:ro -v /etc/passwd:/date/passwd:ro busybox:latest

/ # touch /date1/dufile1

/ # touch /date2/dufile1

touch: /date2/dufile1: Read-only file system

2、docker managed 数据卷

bind mount必须指定host文件系统路径,限制了移植性 。

docker managed volume 不需要指定mount源,docker自动为容器创建数据卷目录 。

默认创建的数据卷目录都在 /var/lib/docker/volumes 中 。

如果挂载时指向容器内已有的目录,原有数据会被复制到volume中。

[root@docker ~]# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD='123456' mysql:5.7

[root@docker ~]# ls -l /var/lib/docker/volumes/

#清理未使用的 Docker 数据

[root@docker ~]# docker volume prune

#建立数据卷

[root@docker ~]# docker volume create mysql1

#查看卷

[root@docker ~]# docker volume ls

DRIVER    VOLUME NAME

local     e76cb8dfd47a629569c6ef25f52e162a35bda0c4269971d3494220e8b848ca87

local     mysql1

#使用建立的数据卷

[root@docker ~]# docker run -d --name web1 -p 80:80 -v mysql1:/usr/share/nginx/html nginx:v4

981cd77de4419e18078d0d3cca1146e847f8bc187e874d1cbeafef1acfbb74a2

[root@docker ~]# ls -l /var/lib/docker/volumes/mysql1/_data/

total 8

-rw-r--r--. 1 root root 497 Mar 28  2023 50x.html

-rw-r--r--. 1 root root 615 Mar 28  2023 index.html

[root@docker ~]# echo mysql1 > /var/lib/docker/volumes/mysql1/_data/index.html

[root@docker ~]# curl 172.25.254.100

mysql1

3、数据卷容器(Data Volume Container)

数据卷容器(Data Volume Container)是 Docker 中一种特殊的容器,主要用于方便地在多个容器之间 共享数据卷。

#建立数据卷容器

[root@docker ~]# docker run -d --name test -v /tmp/date1:/date1:rw -v /tmp/date2:/date2:ro -v /etc/resolv.conf:/etc/hosts busybox:latest

#使用数据卷容器

[root@docker ~]# docker run -it --name test1 --rm --volumes-from test busybox:latest

/ # ls

bin    date2  etc    lib    proc   sys    usr

date1  dev    home   lib64  root   tmp    var

/ # cat /etc/resolv.conf

# Generated by Docker Engine.

# This file can be edited; Docker Engine will not make further changes once it

# has been modified.

nameserver 114.114.114.114

# Based on host file: '/etc/resolv.conf' (legacy)

# Overrides: []

/ # touch date1/dufile1

/ # touch date2/dufile1

touch: date2/dufile1: Read-only file system

/ #

4、bind mount 数据卷和docker managed 数据卷的对比

相同点: 两者都是 host 文件系统中的某个路径

不同点:

5、备份与迁移数据卷

#建立容器并指定使用卷到要备份的容器

[root@docker ~]# docker run -it --name test2 --volumes-from test -v `pwd`:/backup busybox:latest tar zcf /backup/date1.tar.gz /date1

#数据恢复

[root@docker ~]# docker run -it --name test3 -v test:/date1 -v `pwd`:/backup busybox:latest /bin/sh -c "tar zxf /backup/date1.tar.gz;/bin/sh"

#查看数据迁移情况

七、Docker 的安全优化

#在rhel9中默认使用cgroup-v2 但是cgroup-v2中不利于观察docker的资源限制情况,所以推荐使用 cgroup-v1

[root@docker ~]# grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="systemd.unified_cgroup_hierarchy=0 systemd.legacy_systemd_cgroup_controller"

[root@docker ~]# reboot

1、Docker的资源限制

限制cpu使用

1.限制cpu的使用量

[root@docker docker]# docker run -it --rm --name test --cpu-period 100000 --cpu-quota 20000 ubuntu:latest

root@dc8f7941c2e6:/# dd if=/dev/zero of=/dev/null &

[1] 9

root@dc8f7941c2e6:/# top

2.限制cpu的优先级

#关闭cpu的核心,当cpu都不空闲下才会出现争抢的情况,为了实验效果我们可以关闭一个cpu核心

[root@docker docker]# echo 0 > /sys/devices/system/cpu/cpu1/online

[root@docker docker]# cat /proc/cpuinfo

#开启容器并限制资源

[root@docker docker]# docker run -it --rm --cpu-shares 10 ubuntu:latest

root@5c29a88b3643:/# dd if=/dev/zero of=/dev/null &

[1] 8

root@5c29a88b3643:/# top

#开启另外一个容器不限制cpu的优先级

[root@docker docker]# docker run -it ubuntu:latest

root@c1e686bf6dad:/# dd if=/dev/zero of=/dev/null &

[1] 9

root@c1e686bf6dad:/# top

限制内存使用

#开启容器并限制容器使用内存大小

[root@docker docker]# docker run -d --name test --memory 200M --memory-swap 200M nginx:v4

d98001589801ccf9cc0395d5fff3c04deb9271fcfc3105882966aa873dbe1fec

[root@docker docker]# cd /sys/fs/cgroup/memory/docker/d98001589801ccf9cc0395d5fff3c04deb9271fcfc3105882966aa873dbe1fec/

[root@docker d98001589801ccf9cc0395d5fff3c04deb9271fcfc3105882966aa873dbe1fec]# cat  memory.limit_in_bytes

209715200

[root@docker d98001589801ccf9cc0395d5fff3c04deb9271fcfc3105882966aa873dbe1fec]# cat  memory.memsw.limit_in_bytes

209715200

#测试容器内存限制,在容器中我们测试内存限制效果不是很明显,可以利用工具模拟容器在内存中写入数据

#因为在之前的配置中使用了centos容器,所有需要重新挂载

[root@docker ~]# umount /rhel9

[root@docker ~]# mount /dev/sr1 /rhel9/

mount: /rhel9: WARNING: source write-protected, mounted read-only.

#下载相关工具

[root@docker docker]# yum install lib*.rpm -y

#在系统中/dev/shm这个目录被挂在到内存中

[root@docker docker]# docker run -d --name test --rm --memory 200M --memory-swap 200M nginx:v4

0d52f8706894689be101bab68d4ad7aba0052d67fe2d999e0a0fcb264a347706

[root@docker docker]# cgexec -g memory:docker/0d52f8706894689be101bab68d4ad7aba0052d67fe2d999e0a0fcb264a347706 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=150

150+0 records in

150+0 records out

157286400 bytes (157 MB, 150 MiB) copied, 0.159417 s, 987 MB/s

[root@docker docker]# cgexec -g memory:docker/0d52f8706894689be101bab68d4ad7aba0052d67fe2d999e0a0fcb264a347706 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=180

180+0 records in

180+0 records out

188743680 bytes (189 MB, 180 MiB) copied, 0.0675011 s, 2.8 GB/s

[root@docker docker]# cgexec -g memory:docker/0d52f8706894689be101bab68d4ad7aba0052d67fe2d999e0a0fcb264a347706 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=200

Killed

#也可以自建控制器

[root@docker docker]# mkdir -p /sys/fs/cgroup/memory/x1/

#内存可用大小限制

[root@docker docker]# echo 209715200 > /sys/fs/cgroup/memory/x1/memory.limit_in_bytes

[root@docker docker]# cat /sys/fs/cgroup/memory/x1/tasks

[root@docker docker]# cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=100

100+0 records in

100+0 records out

104857600 bytes (105 MB, 100 MiB) copied, 0.0317737 s, 3.3 GB/s

[root@docker docker]# free -m

               total        used        free      shared  buff/cache   available

Mem:            1743         995         158         107         862         748

Swap:           2047          23        2024

[root@docker docker]# cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=300

300+0 records in

300+0 records out

314572800 bytes (315 MB, 300 MiB) copied, 0.236455 s, 1.3 GB/s

[root@docker docker]# free -m

               total        used        free      shared  buff/cache   available

Mem:            1743        1089          63         201         957         654

Swap:           2047         129        1918

[root@docker docker]# cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=300

300+0 records in

300+0 records out

314572800 bytes (315 MB, 300 MiB) copied, 0.236455 s, 1.3 GB/s

[root@docker docker]# free -m

               total        used        free      shared  buff/cache   available

Mem:            1743        1089          63         201         957         654

Swap:           2047         129        1918

[root@docker docker]# rm -fr /dev/shm/bigfile

[root@docker docker]# echo 209715200 > /sys/fs/cgroup/memory/x1/memory.memsw.limit_in_bytes

[root@docker docker]#  cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=200

Killed

[root@docker docker]# rm -fr /dev/shm/bigfile                                     [root@docker docker]#  cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=180

180+0 records in

180+0 records out

188743680 bytes (189 MB, 180 MiB) copied, 0.0497214 s, 3.8 GB/s

[root@docker docker]#  cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=190

190+0 records in

190+0 records out

199229440 bytes (199 MB, 190 MiB) copied, 0.0512029 s, 3.9 GB/s

[root@docker docker]#  cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=200

Killed

限制docker的磁盘io

#指定容器使用磁盘io的速率

[root@docker docker]# docker run -it --rm --device-write-bps /dev/nvme0n1:30M ubuntu

#开启容器后会发现速度和设定不匹配, 是因为系统的缓存机制

root@88b0b6e750cb:/# dd if=/dev/zero of=bigfile

dd: writing to 'bigfile': No space left on device

7934761+0 records in

7934760+0 records out

4062597120 bytes (4.1 GB, 3.8 GiB) copied, 9.26265 s, 439 MB/s

root@88b0b6e750cb:/# dd if=/dev/zero of=bigfile bs=1M count=100

100+0 records in

100+0 records out

104857600 bytes (105 MB, 100 MiB) copied, 0.0397345 s, 2.6 GB/s

#设定dd命令直接写入磁盘

root@88b0b6e750cb:/# dd if=/dev/zero of=bigfile bs=1M count=100 oflag=direct

100+0 records in

100+0 records out

104857600 bytes (105 MB, 100 MiB) copied, 2.55093 s, 41.1 MB/s

2、Docker的安全加固

Docker默认隔离性

在系统中运行容器,我们会发现资源并没有完全隔离开

#容器中内存使用情况

root@88b0b6e750cb:/# free -m

               total        used        free      shared  buff/cache   available

Mem:            1743        1011         468         201         625         731

Swap:           2047          70        1977

#系统内存使用情况

[root@docker docker]# free -m

               total        used        free      shared  buff/cache   available

Mem:            1743        1011         466         201         627         732

Swap:           2047          70        1977

虽然我们限制了容器的内容使用情况,但是查看到的信息依然是系统中内存的使用信息,并没有隔离开

解决Docker的默认隔离性

LXCFS 是一个为 LXC(Linux Containers)容器提供增强文件系统功能的工具。

主要功能

1. 资源可见性: LXCFS 可以使容器内的进程看到准确的 CPU、内存和磁盘 I/O 等资源使用信息。在没有 LXCFS 时,容器内看到的资源信息可能不准确,这会影响到在容器内运行的应用程序对资源的评估和管理。

2. 性能监控: 方便对容器内的资源使用情况进行监控和性能分析。通过提供准确的资源信息,管理员和开发 人员可以更好地了解容器化应用的性能瓶颈,并进行相应的优化。

#安装lxcfs

[root@docker docker]# dnf install lxc*.rpm -y

#运行lxcfs并解决容器隔离性

[root@docker docker]# lxcfs /var/lib/lxcfs &

[root@docker docker]# docker run -it -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

root@6bf8fdae7179:/# free -m

               total        used        free      shared  buff/cache   available

Mem:             256           1         253           0           0         254

Swap:            512           0         512

容器特权

在容器中默认情况下即使我是容器的超级用户也无法修改某些系统设定,比如网络。

[root@docker ~]# docker run --rm -it busybox:latest

/ # whoami

root

/ # ip a

/ # ip a a 172.25.254.120/24 dev eth0

ip: RTNETLINK answers: Operation not permitted

这是因为容器使用的很多资源都是和系统真实主机公用的,如果允许容器修改这些重要资源,系统的稳定性会变的非常差。但是由于某些需要求,容器需要控制一些默认控制不了的资源,如何解决此问题,这时我们就要设置容器特权。

[root@docker ~]# docker run --rm -it --privileged busybox:latest

/ # id root

uid=0(root) gid=0(root) groups=0(root),10(wheel)

/ # ip a a 172.25.254.120/24 dev eth0

/ # ip a

容器特权的白名单

--privileged=true 的权限非常大,接近于宿主机的权限,为了防止用户的滥用,需要增加限制,只提供 给容器必须的权限。此时Docker 提供了权限白名单的机制,使用--cap-add添加必要的权限

capabilities手册地址:http://man7.org/linux/man-pages/man7/capabilities.7.html

#限制容器对网络有root权限

[root@docker ~]# docker run --rm -it --cap-add NET_ADMIN busybox:latest

/ # ip a

#网络可以设定

/ # ip a a 172.25.254.130/24 dev eth0

/ # ip a

#无法管理磁盘

/ # fdisk -l

八、容器编排工具Docker Compose

1、Docker Compose 概述

Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。

其是官方的一个开源项目,托管到github上

网址:https://github.com/docker/compose

主要功能

1. 定义服务:

使用 YAML 格式的配置文件来定义一组相关的容器服务。每个服务可以指定镜像、端口映射、 环境变量、存储卷等参数。

例如,可以在配置文件中定义一个 Web 服务和一个数据库服务,以及它们之间的连接关系。

2. 一键启动和停止:

通过一个简单的命令,可以启动或停止整个应用程序所包含的所有容器。这大大简化了多容器 应用的部署和管理过程。

例如,使用 docker-compose up 命令可以启动配置文件中定义的所有服务,使用 dockercompose down 命令可以停止并删除这些服务。

3. 服务编排:

可以定义容器之间的依赖关系,确保服务按照正确的顺序启动和停止。例如,可以指定数据库 服务必须在 Web 服务之前启动。

支持网络配置,使不同服务的容器可以相互通信。可以定义一个自定义的网络,将所有相关的 容器连接到这个网络上。

4. 环境变量管理:

可以在配置文件中定义环境变量,并在容器启动时传递给容器。这使得在不同环境(如开发、 测试和生产环境)中使用不同的配置变得更加容易。

例如,可以定义一个数据库连接字符串的环境变量,在不同环境中可以设置不同的值。

工作原理

1. 读取配置文件:

Docker Compose 读取 YAML 配置文件,解析其中定义的服务和参数。

2. 创建容器:

根据配置文件中的定义,Docker Compose 调用 Docker 引擎创建相应的容器。它会下载所需 的镜像(如果本地没有),并设置容器的各种参数。

3. 管理容器生命周期:

Docker Compose 监控容器的状态,并在需要时启动、停止、重启容器。

它还可以处理容器的故障恢复,例如自动重启失败的容器。

Docker Compose 中的管理层

1. 服务 (service) 一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。

2. 项目 (project) 由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。

3. 容器(container)容器是服务的具体实例,每个服务可以有一个或多个容器。容器是基于服务定义 的镜像创建的运行实例。

2、Docker Compose 的常用命令参数

#设置vim编辑器相关参数,保证格式正确

[root@docker ~]# vim ~/.vimrc

#编写yml文件

[root@docker ~]# cd docker/

[root@docker docker]# mkdir test

[root@docker docker]# cd test/

[root@docker test]# vim docker-compose.yml

服务管理

1. docker-compose up :

启动配置文件中定义的所有服务。

可以使用 -d 参数在后台启动服务。

可以使用-f 来指定yml文件

例如: docker-compose up -d 。

[root@docker test]# docker compose up -d

2.docker-compose stop :

停止正在运行的服务

[root@docker test]# docker compose stop

3.docker-compose start :

启动已经存在的服务,但不会创建新的服务。

 [root@docker test]# docker compose start

4.docker-compose restart :

重启服务。

[root@docker test]# docker compose restart

5.docker-compose down :

停止并删除配置文件中定义的所有服务以及相关的网络和存储卷。

[root@docker test]# docker compose down

服务状态查看

1. docker-compose ps :

列出正在运行的服务以及它们的状态,包括容器 ID、名称、端口映射等信息。

[root@docker test]# docker compose ps

2. docker-compose logs : 查看服务的日志输出。可以指定服务名称来查看特定服务的日志。

[root@docker test]# docker compose logs db

构建和重新构建服务

1. docker-compose build :

构建配置文件中定义的服务的镜像。可以指定服务名称来只构建特定的服务。

[root@docker test]# vim Dockerfile

[root@docker test]# vim du.Dockerfile

#移除没有关联到任何服务的容器

[root@docker test]# docker compose up -d --remove-orphans

#构建 services中的test1

[root@docker test]# docker compose -f du.Dockerfile build test1

#构建 services中的所有

[root@docker test]# docker rmi test1

[root@docker test]# docker compose -f du.Dockerfile build

2. docker-compose up --build :

启动服务并在启动前重新构建镜像。

[root@docker test]# docker rmi test1 test2

[root@docker test]# docker compose -f du.Dockerfile up -- build

其他操作

1. docker-compose exec : 在正在运行的服务容器中执行命令。

[root@docker test]# vim test.yml

[root@docker test]# docker compose -f test.yml up -d

[root@docker test]# docker compose -f test.yml exec test sh

/ #

2. docker-compose pull :

拉取配置文件中定义的服务所使用的镜像。

[root@docker test]# docker compose -f test.yml pull

3. docker-compose config : 验证并查看解析后的 Compose 文件内容

#配置正确时会显示文件内容

[root@docker test]# docker compose -f test.yml config

#加上参数-q在配置正确时会隐藏文件内容

[root@docker test]# docker compose -f test.yml config -q

#配置错误时会进行提示

[root@docker test]# docker compose -f test.yml config

yaml: line 1: did not find expected key

3、Docker Compose 的yml文件

Docker Compose 的 YAML 文件用于定义和配置多容器应用程序的各个服务。以下是一个基本的 Docker Compose YAML 文件结构及内容解释:

服务(services)

1. 服务名称(service1_name/service2_name 等):

每个服务在配置文件中都有一个唯一的名称,用于在命令行和其他部分引用该服务。

services:

    web:

        # 服务1的配置

    mysql:

        # 服务2的配置

2. 镜像(image):

指定服务所使用的 Docker 镜像名称和标签。例如, image: nginx:latest 表示使用 nginx 镜像的最新版本。

services:

    web:

        images:nginx

    mysql:

        images:mysql:5.7

3. 端口映射(ports):

将容器内部的端口映射到主机的端口,以便外部可以访问容器内的服务。

例如, - "8080:80" 表示将主机的 8080 端口映射到容器内部的 80 端口。

4. 环境变量(environment):

为容器设置环境变量,可以在容器内部的应用程序中使用。

例如, VAR1: value1 设置环境变 量 VAR1 的值为 value1

services:

    web:

        images:mysql:5.7

        environment: MYSQL_ROOT_PASSWORD: du

5. 存储卷(volumes):

将主机上的目录或文件挂载到容器中,以实现数据持久化或共享。

例如, - /host/data:/container/data 将主机上的 /host/data 目录挂载到容器内的 /container/data 路径。

6. 网络(networks):

将服务连接到特定的网络,以便不同服务的容器可以相互通信。

[root@docker test]# vim du.yml

[root@docker test]# docker compose -f du.yml up -d

7. 命令(command):

覆盖容器启动时默认执行的命令。

例如, command: python app.py 指定容器启动时运行 python app.py 命令

[root@docker test]# vim busybox.yml

services:

    web:

        image: busybox

        container_name: busybox

        command: ["/bin/sh","-c","sleep10000000"]

网络(networks)

定义 Docker Compose 应用程序中使用的网络。可以自定义网络名称和驱动程序等属性。

默认情况下docker compose 在执行时会自动建立网络

[root@docker test]# vim test.yml

[root@docker test]# docker compose -f test.yml up -d

[+] Running 5/5

 ✔ Network test_mynet2  Created                                              0.1s

 ✔ Network test_mynet1  Created                                              0.1s

 ✔ Container busybox2   Started                                              0.6s

 ✔ Container busybox3   Started                                              0.6s

 ✔ Container busybox1   Started                                              0.6s

存储卷(volumes)

定义 Docker Compose 应用程序中使用的存储卷。

可以自定义卷名称和存储位置等属性。

[root@docker test]# docker compose -f test.yml down

[root@docker test]# vim test.yml

[root@docker test]# docker compose -f test.yml up -d

[+] Running 2/2

 ✔ Volume "du"         Created                                               0.0s

 ✔ Container busybox1  Started                                               0.4s

4、企业示例

利用容器编排完成haproxy和nginx负载均衡架构实施

[root@docker docker]# docker load -i haproxy-2.3.tar.gz

[root@docker docker]# cd test/

[root@docker test]# yum install haproxy -y

[root@docker test]# yum install nginx -y

[root@docker docker]# mkdir -p web/html{1..2}

[root@docker docker]# echo web1 > web/html1/index.html

[root@docker docker]# echo web2 > web/html2/index.html

[root@docker test]# mkdir -p  /usr/local/etc/haproxy

[root@docker docker]# mkdir conf/haproxy -p

[root@docker docker]# cp /etc/haproxy/haproxy.cfg conf/haproxy/

[root@docker test]# vim /root/docker/conf/haproxy/haproxy.cfg

[root@docker test]# vim test.yml

[root@docker test]# docker compose -f test.yml up -d

[+] Running 5/5

 ✔ Network test_mynet1  Created                                              0.1s

 ✔ Network test_mynet2  Created                                              0.1s

 ✔ Container haproxy    Started                                              0.8s

 ✔ Container web2       Started                                              0.7s

 ✔ Container web1       Started                                              0.7s

[root@docker test]# curl 172.25.254.100

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值