Docker(完整实验版)

news2024/12/29 14:20:16

目录

一 Docker

1.1 Docker简介

1.1.1 什么是docker?

1.1.2 docker在企业中的应用场景

1.1.3 docker与虚拟化的对比

1.1.4 docker的优势

1.2 部署docker

1.2.1 配置软件仓库 

二 Docker的基本操作

2.1 Docker镜像管理

2.1.1 搜索镜像

2.1.2 拉取镜像

2.1.3 查看镜像信息

2.1.4 导出镜像

2.1.5 删除镜像

2.2 容器的常用操作

2.2.1 启动容器

2.2.2 查看容器运行信息

2.2.3 停止和运行容器

2.2.4 删除容器

2.2.5 容器内容提交

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

2.2.7 查询容器内部日志

三 docker镜像构建

3.1 docker镜像结构

3.2 镜像运行的基本原理

3.3 镜像获得方式

3.4 镜像构建

3.4.1 构建参数

3.4.2 Dockerfile实例

四 docker 镜像仓库的管理

4.1 docker仓库

4.2 docker hub

4.2.1 docker hub的使用方法

4.3 搭建docker的私有仓库

4.3.1 搭建简单的Registry仓库

4.3.2 为Registry提加密传输

4.3.3为仓库建立登陆认证

4.4 部署harbor

五 Docker 网络

5.1 docker原生bridge网路

5.2 docker原生网络host

5.3 docker 原生网络none

5.4 docker的自定义网络

5.4.1 自定义桥接网络

5.4.2 让不同的自定义网络互通

5.4.3 joined容器网络

5.5. 容器内外网的访问

5.6 docker跨主机网络

5.6.1 CNM (Container Network Model)

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

六 Docker 数据卷管理及优化

6.1 为什么要用数据卷

6.2 bind mount 数据卷

6.3 docker managed 数据卷

6.4 数据卷容器

6.5 bind mount 数据卷和docker managed 数据卷的对比

七 Docker 的安全优化

7.1 Docker的资源限制

7.1.1.限制cpu使用

7.1.2 限制内存使用

7.1.3 限制docker的磁盘io

7.2 Docker的安全加固

7.2.1 容器特权

7.2.2 容器特权的白名单

八 容器编排工具Docker Compose

8.1 Docker Compose 概述

8.2 Docker Compose 的常用命令参数

8.3 Docker Compose 的yml文件

8.4 企业示例


一 Docker

1.1 Docker简介

1.1.1 什么是docker?

Docker是管理容器的引擎,为应用打包、部署平台,而非单纯的虚拟化技术 它具有以下几个重要特点和优势:

1. 轻量级虚拟化:

  • Docker 容器相较于传统的虚拟机更加轻量和高效,能够快速启动和停止,节省系统资源。例如,启动一个 Docker 容器可能只需要几秒钟,而启动一个虚拟机则可能需要几分钟。

2. 一致性

  • 确保应用程序在不同的环境中(如开发、测试、生产)具有一致的运行表现。无论在本地还是云端,应用的运行环境都能保持相同,减少了因环境差异导致的问题。

3. 可移植性

  • 可以轻松地将 Docker 容器从一个平台迁移到另一个平台,无需担心依赖和环境配置的差异。比如,在本地开发的容器可以无缝部署到云服务器上。

4. 高效的资源利用

  • 多个 Docker容器可以共享主机的操作系统内核,从而更有效地利用系统资源。

5. 易于部署和扩展

  • 能够快速部署新的应用实例,并且可以根据需求轻松地进行水平扩展。总之,Docker 极大地简化了应用程序的开发、部署和管理流程,提高了开发效率和运维的便利性。它在现代软件开发和云计算领域得到了广泛的应用。

1.1.2 docker在企业中的应用场景

  • 在企业中docker作为业务的最小载体而被广泛应用
  • 通过docker企业可以更效率的部署应用并更节省资源

1.1.3 docker与虚拟化的对比

虚拟机docker容器
操作系统宿主机上运行虚拟机OS共享宿主机OS
存储镜像较大(GB)镜像小(MB)
性能操作系统额外的cpu、内存消耗几乎无性能损耗
移植性笨重、与虚拟化技术耦合度高轻量、灵活迁移
隔离性完全隔离安全隔离
部署慢、分钟级快速、秒级
运行速度一般几十个单机支持上千容器

1.1.4 docker的优势

一、轻量级和高效性

  • 资源占用少
  • 快速启动和停止

二、可移植性和一致性

  • 跨平台部署
  • 环境一致性

三、简化开发和部署流程

  • 开发环境一致性
  • 持续集成和持续部署(CI/CD)

四、隔离性和安全性

  • 进程隔离
  • 安全沙箱

五、弹性和扩展性

  • 快速扩展
  • 动态调整资源

1.2 部署docker

容器工作方法

官方站点:https://docs.docker.com/

1.2.1 配置软件仓库 

虚拟机环境 redhat9

#配置软件仓库
[root@docker-node1 ~]# vim /etc/yum.repos.d/docker-ce.repo 
[docker]
name=docker-ce
baseurl=https://mirrors.aliyun.com/docker-ce/linux/rhel/9/x86_64/stable/
gpgcheck=0

#安装docker-ce并启动服务
[root@k8s ~]# tar zxf docker.tar.gz 
[root@k8s ~]# dnf install *.rpm -y

[root@docker-node1 ~]# systemctl enable --now docker
Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.

#加速器
1. https://3tax6oij.mirror.aliyuncs.com
2. https://docker.m.daocloud.io

[root@k8s docker]# vim /etc/docker/daemon.json
{
  "registry-mirrors": ["https://docker.m.daocloud.io"]
}

[root@k8s ~]# systemctl daemon-reload 
[root@k8s ~]# systemctl restart docker


#读取镜像
[root@docker-node1 ~]# docker load -i busybox-latest.tar.gz 
d51af96cf93e: Loading layer  4.495MB/4.495MB
Loaded image: busybox:latest


#运行容器
[root@docker-node1 ~]# docker run -d --rm --name game2 -p 80:80 timinglee/game2048:latest
376f05756eaec07badec71ae04fec4e499fe60d5433bbf8b41d0830aa6707f50

在rhel7中 需要激活内核网络

vim /etc/sysctl.d/docker.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1

sysctl --system
systemctl restart docker

二 Docker的基本操作

2.1 Docker镜像管理

2.1.1 搜索镜像

#以nginx为例
[root@docker-node1 ~]# docker search nginx
参数说明
NAME镜像名称
DESCRIPTION镜像说明
STARS点赞数量
OFFICIAL是否是官方的

2.1.2 拉取镜像

#从镜像仓库中拉取镜像
[root@docker-node1 ~]# docker pull busybox
[root@docker-node1 ~]# docker pull nginx:1.26-alpine        #alpine 版本:nginx镜像的最小安装发型版本


#查看本地镜像
[root@docker-node1 ~]# docker images

2.1.3 查看镜像信息

[root@docker-node1 ~]# docker image inspect nginx

2.1.4 导出镜像

#保存镜像
[root@docker-node1 ~]# docker image save nginx:latest -o nginx-latest.tar.gz
[root@docker-node1 ~]# docker image save nginx:latest nginx:1.26-alpine -o nginx.tag.gz

#保存所有镜像
[root@docker-node1 ~]# docker save `docker images | awk 'NR>1{print $1":"$2}'` -
o images.tar.gz
  • -o:指定导出镜像的位置
  • 可以同时导出多个镜像到一个文件中
  • 指定.tar.gz 可以导出并压缩

2.1.5 删除镜像

[root@docker-node1 ~]# docker rmi nginx:latest
[root@docker-node1 ~]# docker rmi `docker images | awk 'NR>1{print $1":"$2}'`

#删除所有镜像
docker rm -f $(docker ps -aq)

2.2 容器的常用操作

2.2.1 启动容器

[root@docker-node1 ~]# docker run -d --name nginx -p 80:80 nginx:latest
[root@docker-node1 ~]# docker run -it --name nginx -p 80:80 nginx:latest
#进入到容器中,按<ctrl>+<d>退出并停止容器,#按<ctrl>+<pq>退出但
不停止容器

#重新进入容器
[root@docker-node1 ~]# docker attach nginx

#在容器中执行命令
[root@docker ~]# docker exec -it test ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

-d                       #后台运行
-i                        #交互式运行
-t                       #打开一个终端
--name              #指定容器名称
-p                      #端口映射 -p 80:8080 把容器8080端口映射到本机80端口
--rm                  #容器停止自动删除容器
--network          #指定容器使用的网络

2.2.2 查看容器运行信息

[root@docker-node1 ~]# docker ps                 #查看当前运行容器
[root@docker-node1 ~]# docker ps -a              #查看所有容器
[root@docker-node1 ~]# docker inspect busybox    #查看容器运行的详细信息

2.2.3 停止和运行容器

[root@docker-node1 ~]# docker stop busybox     #停止容器
[root@docker-node1 ~]# docker kill busybox     #杀死容器,可以使用信号
[root@docker-node1 ~]# docker start busybox    #开启停止的容器

2.2.4 删除容器

[root@docker-node1 ~]# docker rm centos7         #删除停止的容器
[root@docker-node1 ~]# docker rm -f busybox      #删除运行的容器
[root@docker-node1 ~]# docker container prune -f #删除所有停止的容器

2.2.5 容器内容提交

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

[root@docker-node1 docker]# docker run -it --name test busybox
/ # touch leefile                            #在容器中建立文件
/ # ls
bin      etc      leefile  lib64    root     tmp      var
dev      home     lib      proc     sys      usr
/ # 

[root@docker-node1 docker]# docker rm test         #删掉容器后
test

[root@docker-node1 docker]# docker run -it --name test busybox        #删掉容器后开启新的容器文件不存在
/ # ls
bin    dev    etc    home   lib    lib64  proc   root   sys    tmp    usr    var
/ # 

[root@docker-node1 ~]# docker commit -m "add leefile" test busybox:v1
sha256:648560550edc2b23a2176009ad9751db745c89df0f46d169f1aea249f9387e8f
[root@docker-node1 ~]# docker images 
REPOSITORY           TAG           IMAGE ID       CREATED         SIZE
busybox              v1            648560550edc   6 seconds ago   4.26MB
nginx                1.26-alpine   9703b2608a98   12 days ago     43.3MB
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


[root@docker-node1 ~]# docker image history busybox:v1 
IMAGE          CREATED          CREATED BY                          SIZE      COMMENT
648560550edc   34 seconds ago   sh                                  3B        add leefile
65ad0d468eb1   15 months ago    BusyBox 1.36.1 (glibc), Debian 12   4.26MB    
Note:此方法不利于企业审计,所以不推荐使用,在企业中我们多用Dockerfile来构建镜像

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

#把容器中的文件复制到本机
[root@docker-node1 ~]# docker cp test2:/leefile /mnt 
Successfully copied 1.54kB to /mnt

#把本机文件复制到容器中
[root@docker-node1 ~]# docker cp /etc/fstab test2:/fstab     

2.2.7 查询容器内部日志

[root@docker-node1 ~]# docker logs

三 docker镜像构建

3.1 docker镜像结构

  • 共享宿主机的kernel
  • base镜像提供的是最小的Linux发行版
  • 同一docker主机支持运行多种Linux发行版
  • 采用分层结构的最大好处是:共享资源

3.2 镜像运行的基本原理

  • Copy-on-Write 可写容器层
  • 容器层以下所有镜像层都是只读的
  • docker从上往下依次查找文件
  • 容器层保存镜像变化的部分,并不会对镜像本身进行任何修改
  • 一个镜像最多127层

3.3 镜像获得方式

  • 基本镜像通常由软件官方提供
  • 企业镜像可以用官方镜像+Dockerfile来生成
  • 系统关于镜像的获取动作有两种:
    • docker pull 镜像地址
    • docker load –i 本地镜像包

3.4 镜像构建

3.4.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@docker-node1 ~]# mkdir docker/
[root@docker-node1 ~]# cd docker/
[root@docker-node1 docker]# touch file 
[root@docker-node1 docker]# vim Dockerfile 
[root@docker-node1 docker]# cat Dockerfile 
FROM busybox:latest				#指定使用的基础镜像
MAINTAINER howe@exam.com		#指定作者信息
COPY file /						#复制当前目录文件到容器指定位置,leefile必须在当前目录中

[root@docker-node1 docker]# docker build -t example:v1 .		#构建镜像

[root@docker-node1 docker]# docker build -t example:v1 .^C
[root@docker-node1 docker]# touch file{1..3}
[root@docker-node1 docker]# tar zcf file.gz file*
[root@docker-node1 docker]# vim Dockerfile 
[root@docker-node1 docker]# cat Dockerfile 
FROM busybox:latest
MAINTAINER howe@exam.com
COPY file /
ADD file.gz /

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

[root@docker-node1 docker]# docker run -it --rm --name test example:v2 
/ # ls
bin    etc    file1  file3  lib    proc   sys    usr
dev    file   file2  home   lib64  root   tmp    var


#CMD1
[root@docker-node1 docker]# cat Dockerfile 
FROM busybox:latest
MAINTAINER howe@exam.com
ENV NAME howe
CMD echo $NAME

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

[root@docker-node1 docker]# docker run -it --rm --name test example:v3
howe

#CMD2
[root@docker-node1 docker]# cat Dockerfile 
FROM busybox:latest
MAINTAINER howe@exam.com
ENV NAME howe
#CMD echo $NAME
CMD ["/bin/echo", "$NAME"]
#CMD ["/bin/sh", "-c", "/bin/echo $NAME"]

[root@docker-node1 docker]# docker run -it --rm --name test example:v3
$NAME
[root@docker-node1 docker]# docker rmi example:v3 

#CMD3
[root@docker-node1 docker]# cat Dockerfile 
FROM busybox:latest
MAINTAINER howe@exam.com
ENV NAME howe
#CMD echo $NAME
#CMD ["/bin/echo", "$NAME"]
CMD ["/bin/sh", "-c", "/bin/echo $NAME"]


[root@docker-node1 docker]# docker run -it --rm --name test example:v3
howe


#
[root@docker-node1 docker]# cat Dockerfile 
FROM busybox:latest
MAINTAINER howe@exam.com
ENV NAME howe
ENTRYPOINT echo $NAME

[root@docker-node1 docker]# docker run -it --rm --name test example:v4
howe
[root@docker-node1 docker]# docker run -it --rm --name test example:v4 sh
howe


#
[root@docker-node1 docker]# cat Dockerfile 
FROM busybox:latest
MAINTAINER howe@exam.com
ENV NAME howe
EXPOSE 80 443
VOLUME /var/www/html
WORKDIR /var/www/html
RUN touch file

[root@docker-node1 docker]# docker run -it --rm --name test example:v5 
/var/www/html # 

3.4.2 Dockerfile实例

建立构建目录,编写构建文件

[root@docker-node1 docker]# cp ~/nginx-1.23.tar.gz .

[root@docker-node1 ~]# docker load -i /mnt/centos-7.tar.gz 
Loaded image: centos:7

[root@docker-node1 docker]# vim Dockerfile 
[root@docker-node1 docker]# cat Dockerfile 
FROM centos:7
ADD nginx-1.23.tar.gz /mnt
WORKDIR /mnt/nginx-1.23
RUN yum install -y gcc make pcre-devel openssl-devel
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc
RUN ./configure --with-http_ssl_module --with-http_stub_status_module
RUN make
RUN make install
EXPOSE 80
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]

通过dockerfile生成镜像 

#通过dockerfile生成镜像
[root@docker-node1 docker]# docker build -t webserver:v1 .
-------------------------------------------------------------
#解决yum install报错
ERROR: failed to solve: process "/bin/sh -c yum install gcc make pcre-devel openssl-devel" did not complete successfully: exit code: 1

1.添加新sr1并挂载到centos镜像

2.下载web服务
[root@docker-node1 docker]# dnf install httpd -y
更改web端口
[root@docker-node1 docker]# vim /etc/httpd/conf/httpd.conf 
[root@docker-node1 docker]# systemctl restart httpd
[root@docker-node1 docker]# 
[root@docker-node1 docker]# mkdir -p /var/www/html/rhel7.9
[root@docker-node1 docker]# mount /dev/sr1 /var/www/html/rhel7.9/
mount: /var/www/html/rhel7.9: WARNING: source write-protected, mounted read-only.

#查看容器IP
[root@docker-node1 docker]# docker inspect centos
 "IPAddress": "172.17.0.2",


[root@docker-node1 yum.repos.d]# docker run -it --name centos centos:7
[root@4b97ad6eb719 /]# ls
anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
[root@4b97ad6eb719 /]# cd /etc/yum.repos.d/
[root@4b97ad6eb719 yum.repos.d]# ls
CentOS-Base.repo  CentOS-Debuginfo.repo  CentOS-Sources.repo  CentOS-fasttrack.repo
CentOS-CR.repo    CentOS-Media.repo      CentOS-Vault.repo    CentOS-x86_64-kernel.repo
[root@4b97ad6eb719 yum.repos.d]# rm -rf *
[root@4b97ad6eb719 yum.repos.d]# vi centos7.repo
[root@4b97ad6eb719 yum.repos.d]# cat centos7.repo 
[centos7]
name=centos7
baseurl=http://172.17.0.1:8888/rhel7.9
gpgcheck=0

#提交
[root@docker-node1 docker]# docker commit -m "add repo" centos centos:repo
sha256:8629c14342c7fc149b23f5fe6c23b2b93d67bba025503f49fac82b9de7c4ec70
[root@docker-node1 docker]#  docker images 
REPOSITORY                      TAG           IMAGE ID       CREATED          SIZE
centos                          repo          8629c14342c7   21 seconds ago   204MB


[root@4b97ad6eb719 yum.repos.d]# exit
exit
[root@docker-node1 yum.repos.d]# docker rm centos
centos

[root@docker-node1 docker]# vim Dockerfile
FROM centos:repo
ADD nginx-1.23.tar.gz /mnt
WORKDIR /mnt/nginx-1.23
RUN yum install gcc make pcre-devel openssl-devel -y
RUN sed -i 's/CFLAGS="$CFLAGS -g"/#CFLAGS="$CFLAGS -g"/g' auto/cc/gcc
RUN ./configure --preifx=/usr/local/nginx --with-http_ssl_module --with-http_stub_status_module
RUN make
RUN make install
EXPOSE 80 443 
VOLUME ["/usr/local/nginx/html"]
CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]

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


四 docker 镜像仓库的管理

4.1 docker仓库

Docker 仓库(Docker Registry) 是用于存储和分发 Docker 镜像的集中式存储库。

它就像是一个大型的镜像仓库,开发者可以将自己创建的 Docker 镜像推送到仓库中,也可以从仓库中拉取所需的镜像。

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

  • 公共仓库,如 Docker Hub,任何人都可以访问和使用其中的镜像。许多常用的软件和应用都有在 Docker Hub 上提供的镜像,方便用户直接获取和使用。
    • 例如,您想要部署一个 Nginx 服务器,就可以从 Docker Hub 上拉取 Nginx 的镜像。
  • 私有仓库则是由组织或个人自己搭建和管理的,用于存储内部使用的、不希望公开的镜像。
    • 比如,一家企业为其特定的业务应用创建了定制化的镜像,并将其存储在自己的私有仓库中,以保证安全性和控制访问权限。

通过 Docker 仓库,开发者能够方便地共享和复用镜像,加速应用的开发和部署过程

4.2 docker hub

4.2.1 docker hub的使用方法

#登陆官方仓库
[root@docker-node1 ~]# docker login

#登陆信息保存位置
[root@docker-node1 ~]# vim .docker/config.json 

4.3 搭建docker的私有仓库

为什么搭建私有仓库?

docker hub虽然方便,但是还是有限制

  • 需要internet连接,速度慢
  • 所有人都可以访问
  • 由于安全原因企业不允许将镜像放到外网

4.3.1 搭建简单的Registry仓库

1.下载Registry镜像
[root@docker ~]# docker pull registry

2.开启Registry
[root@docker ~]# docker run -d -p 5000:5000 --restart=always --name registry 
registry

3.上传镜像到仓库中
#给要上传的经镜像打标签
[root@docker-node1 ~]# docker tag busybox:latest 172.25.250.100:5000/busybox:latest

#如果速度慢可以用docker加速器
[root@docker-node1 ~]# cat /etc/docker/daemon.json 
{
   "insecure-registries" : ["http://172.25.250.100:5000"]
}

[root@docker-node1 ~]# systemctl daemon-reload 
[root@docker-node1 ~]# systemctl start docker


#docker在上传的过程中默认使用https,但是我们并没有建立https认证需要的认证文件所以会报错
[root@docker-node1 ~]# docker push 172.25.250.100:5000/busybox:latest 
The push refers to repository [172.25.250.100:5000/busybox]
d51af96cf93e: Pushed 
latest: digest: sha256:28e01ab32c9dbcbaae96cf0d5b472f22e231d9e603811857b295e61197e40a9b size: 527


4.查看镜像上传
[root@docker-node1 ~]# curl 172.25.250.100:5000/v2/_catalog
{"repositories":["busybox"]}

4.3.2 为Registry提加密传输

#生成认证key和证书
[root@docker-node1 ~]# openssl req -newkey rsa:4096 \
-nodes -sha256 -keyout certs/exam.com.key \
-addext "subjectAltName = DNS:reg.exam.com" \		#指定备用名称
-x509 -days 365 -out certs/exam.com.crt

#启动registry仓库
[root@docker-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/exam.com.crt \
> -e REGISTRY_HTTP_TLS_KEY=/certs/exam.com.key registry

测试:
[root@docker-node1 ~]# docker push reg.exam.com/busybox:latest
The push refers to repository [reg.exam.com/busybox]
An image does not exist locally with the tag: reg.exam.com/busybox

#为客户端建立证书
[root@docker-node1 ~]# mkdir /etc/docker/certs.d/reg.exam.com/ -p
[root@docker-node1 ~]# cp /root/certs/exam.com.crt /etc/docker/certs.d/reg.exam.com/ca.crt
[root@docker-node1 ~]# systemctl restart docker

#标签问题
[root@docker-node1 ~]# docker push reg.exam.com/busybox:latest
The push refers to repository [reg.exam.com/busybox]
An image does not exist locally with the tag: reg.exam.com/busybox

[root@docker-node1 ~]# docker tag busybox reg.exam.com/busybox:latest
[root@docker-node1 ~]# docker push reg.exam.com/busybox:latest

#DNS问题
[root@docker-node1 ~]# docker push reg.exam.com/busybox:latest
The push refers to repository [reg.exam.com/busybox]
Get "https://reg.exam.com/v2/": dial tcp: lookup reg.exam.com on 114.114.114.114:53: no such host

[root@docker-node1 ~]# vim /etc/hosts


The push refers to repository [reg.exam.com/busybox]
d51af96cf93e: Pushed 
latest: digest: sha256:28e01ab32c9dbcbaae96cf0d5b472f22e231d9e603811857b295e61197e40a9b size: 527
[root@docker-node1 ~]# 

#测试
[root@docker-node1 ~]# curl -k https://reg.exam.com/v2/_catalog
{"repositories":["busybox"]}

4.3.3为仓库建立登陆认证

#安装建立认证文件的工具包
[root@docker-node1 ~]# dnf install httpd-tools -y

#建立认证文件
[root@docker-node1 ~]# mkdir auth
[root@docker-node1 ~]# htpasswd -Bc auth/htpasswd howe
New password: redhat	#密码
Re-type new password: 
Adding password for user howe

#添加认证到registry容器中
[root@docker-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/exam.com.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/exam.com.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@docker-node1 certs]# curl -k https://reg.exam.com/v2/_catalog -u howe:redhat
{"repositories":["busybox"]}

#登陆测试
[root@docker-node1 ~]# docker login reg.exam.com
Username: howe
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

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


4.4 部署harbor

#安装harbor
[root@docker-node1 ~]# tar zxf harbor-offline-installer-v2.5.4.tgz
[root@docker-node1 ~]# cd harbor/
[root@docker-node1 harbor]# ls
common.sh  harbor.v2.5.4.tar.gz  harbor.yml.tmpl  install.sh  LICENSE  prepare
[root@docker-node1 harbor]# cp harbor.yml.tmpl harbor.yml

#建立认证并登录 见上
[root@docker-node1 ~]# htpasswd -Bc auth/htpasswd howe

#创建加密密钥
[root@k8s ~]# openssl req -newkey rsa:4096 \
-nodes -sha256 -keyout certs/exam.com.key \
-addext "subjectAltName = DNS:reg.exam.com" \
-x509 -days 365 -out certs/exam.com.crt

[root@k8s ~]# mkdir /etc/docker/certs.d/reg.exam.com/ -p
[root@k8s ~]# cp /root/certs/exam.com.crt /etc/docker/certs.d/reg.exam.com/ca.crt
[root@k8s ~]# systemctl restart docker

#修改配置文件
[root@docker-node1 harbor]# vim harbor.yml
 5 hostname: reg.exam.com
 17   certificate: /data/certs/exam.com.crt
 18   private_key: /data/certs/exam.com.key
 34 harbor_admin_password: redhat
[root@docker-node1 harbor]# mkdir /data

[root@docker-node1 data]# cp /root/certs /data/certs -r

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

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

#下载web服务
[root@k8s harbor]# dnf install httpd -y

#为了方便可以更改web端口
[root@docker-node1 harbor]# vim /etc/httpd/conf/httpd.conf
...
47 Listen 8888
...
[root@docker-node1 harbor]# systemctl restart httpd

#登录docker
[root@k8s harbor]# docker login reg.exam.com
Username: admin
Password: 

网页打开 reg.exam.com/8888

接下来上传镜像看看

#确保登录admin
[root@docker-node1 harbor]# docker login reg.exam.com
Authenticating with existing credentials...
Stored credentials invalid or expired
Username (howe): admin
Password: redhat
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@docker-node1 ~]# docker tag busybox:latest reg.exam.com/superhowe/busybox:latest 
[root@docker-node1 ~]# docker push reg.exam.com/superhowe/busybox:latest 
The push refers to repository 

#上传镜像
[reg.exam.com/superhowe/busybox]
d51af96cf93e: Pushed 
latest: digest: sha256:28e01ab32c9dbcbaae96cf0d5b472f22e231d9e603811857b295e61197e40a9b size: 527


五 Docker 网络

docker安装后会自动创建3种网络:bridge、host、none

5.1 docker原生bridge网路

#更改内核参数
[root@docker-node1 ~]# grubby --update-kernel ALL --args iptables=true
[root@docker-node1 ~]# reboot

#查看防火墙策略
[root@docker-node1 ~]# iptables -nL

#bridge
[root@docker-node1 harbor]# docker run -it --name webserver --network bridge busybox
/ # ifconfig 

5.2 docker原生网络host

host网络模式需要在容器创建时指定 --network=host

host模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性

[root@docker-node1 ~]# docker run -d --name web -p 80:80 nginx:1.23
a1b8d4fa9c9bfd870c4997d295efb10ff155e50a4a1942d9c99fabe32a02de55

[root@docker-node1 ~]# ifconfig 

5.3 docker 原生网络none

none模式是指禁用网络功能,只有lo接口,在容器创建时使用

[root@docker-node1 ~]# docker run -it --name test --rm --network none busybox

5.4 docker的自定义网络

自定义网络模式,docker提供了三种自定义网络驱动:

  • bridge
  • overlay
  • macvlan

bridge驱动类似默认的bridge网络模式,但增加了一些新的功能,overlay和macvlan是用于创建跨主机网络,建议使用自定义的网络来控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址

5.4.1 自定义桥接网络

在建立自定以网络时,默认使用桥接模式

[root@docker-node1 ~]# docker network create my_net1

[root@docker-node1 ~]# docker network ls
2644d485a93e   my_net1                     bridge    local

桥接默认是单调递增

[root@docker-node1 ~]# ifconfig

桥接也支持自定义子网和网关

[root@docker-node1 ~]# docker network create my_net2 --subnet 172.25.0.0/24 --gateway 172.25.0.2

[root@docker-node1 ~]# docker network inspect my_net2 

注意:不同的自定义网络是不能通讯的

#在rhel7中使用的是iptables进行网络隔离,在rhel9中使用nftpables

[root@docker ~]# nft list ruleset可以看到网络隔离策略

5.4.2 让不同的自定义网络互通

[root@docker-node1 ~]# docker run -d --name web1 --network my_net1 nginx
[root@docker-node1 ~]# docker run -it --name test --network my_net2 busybox
/ # ifconfig
eth0     Link encap:Ethernet HWaddr 02:42:C0:A8:00:01
         inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
         RX packets:36 errors:0 dropped:0 overruns:0 frame:0
         TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:0
         RX bytes:5244 (5.1 KiB) TX bytes:0 (0.0 B)
lo       Link encap:Local Loopback
         inet addr:127.0.0.1 Mask:255.0.0.0
         inet6 addr: ::1/128 Scope:Host
         UP LOOPBACK RUNNING MTU:65536 Metric:1
         RX packets:0 errors:0 dropped:0 overruns:0 frame:0
         TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:1000
         RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
/ # ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2): 56 data bytes    #此时ping不通

[root@docker ~]# docker network connect my_net1 test
#在上面test容器中加入网络eth1
/ # ifconfig
eth0     Link encap:Ethernet HWaddr 02:42:C0:A8:00:01
         inet addr:192.168.0.1 Bcast:192.168.0.255 Mask:255.255.255.0
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
         RX packets:45 errors:0 dropped:0 overruns:0 frame:0
         TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:0
         RX bytes:5879 (5.7 KiB) TX bytes:602 (602.0 B)
eth1     Link encap:Ethernet HWaddr 02:42:AC:12:00:03
         inet addr:172.18.0.3 Bcast:172.18.255.255 Mask:255.255.0.0
         UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
         RX packets:15 errors:0 dropped:0 overruns:0 frame:0
         TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:0
         RX bytes:2016 (1.9 KiB) TX bytes:0 (0.0 B)
lo       Link encap:Local Loopback
         inet addr:127.0.0.1 Mask:255.0.0.0
         inet6 addr: ::1/128 Scope:Host
         UP LOOPBACK RUNNING MTU:65536 Metric:1
         RX packets:4 errors:0 dropped:0 overruns:0 frame:0
         TX packets:4 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:1000
         RX bytes:212 (212.0 B) TX bytes:212 (212.0 B)

5.4.3 joined容器网络

Joined容器一种较为特别的网络模式,•在容器创建时使用--network=container:vm1指定。(vm1指定的是运行的容器名)

处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用localhost高效快速通信。

[root@docker-node1 ~]# docker run -it --rm --name test --network mynet1 busybox
/ # ifconfig 
eth0      Link encap:Ethernet  HWaddr 02:42:AC:12:00:02  
          inet addr:172.18.0.2  Bcast:172.18.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:17 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2330 (2.2 KiB)  TX bytes:0 (0.0 B)
 
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
 
/ # 
 

#设置和test共用一个网卡
[root@docker-node1 ~]# docker run -it --name test1 --network container:test busybox  
/ # ifconfig 
eth0      Link encap:Ethernet  HWaddr 02:42:AC:12:00:02  
          inet addr:172.18.0.2  Bcast:172.18.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:19 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:2470 (2.4 KiB)  TX bytes:0 (0.0 B)
 
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)
 
5.4.3.1 joined网络示例演示

利用容器部署phpmyadmin管理mysql

#读取镜像
[root@docker-node1 ~]# docker load -i mysql-5.7.tar.gz
[root@docker-node1 ~]# docker load -i phpmyadmin-latest.tar.gz 

#运行phpmysqladmin
[root@docker ~]# docker run -d --name mysqladmin --network my_net1 \
-e PMA_ARBITRARY=1 \             #在web页面中可以手动输入数据库地址和端口
-p 80:80 phpmyadmin:latest

#运行数据库
[root@docker ~]# docker run -d --name mysql \
-e MYSQL_ROOT_PASSWORD='redhat' \               #设定数据库密码
--network container:mysqladmin \                #把数据库容器添加到phpmyadmin容器中
mysql:5.7

5.5. 容器内外网的访问

5.6 docker跨主机网络

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

  • 跨主机网络解决方案
    • docker原生的overlay和macvlan
    • 第三方的flannel、weave、calico
  • 众多网络方案是如何与docker集成在一起的
    • libnetwork docker容器网络库
    • CNM (Container Network Model)这个模型对容器网络进行了抽象

5.6.1 CNM (Container Network Model)

CNM分三类组件

  • Sandbox:容器网络栈,包含容器接口、dns、路由表。(namespace)
  • Endpoint:作用是将sandbox接入network (veth pair)
  • Network:包含一组endpoint,同一network的endpoint可以通信

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

macvlan网络方式

  • Linux kernel提供的一种网卡虚拟化技术。
  • 无需Linux bridge,直接使用物理接口,性能极好
  • 容器的接口直接与主机网卡连接,无需NAT或端口映射。
  • macvlan会独占主机网卡,但可以使用vlan子接口实现多macvlan网络
  • vlan可以将物理二层网络划分为4094个逻辑网络,彼此隔离,vlan id取值为1~4094

macvlan网络间的隔离和连通

  • macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的
  • 可以在三层上通过网关将macvlan网络连通起来
  • docker本身不做任何限制,像传统vlan网络那样管理即可

示例:

#在两台docker主机上各添加一块网卡,打开网卡混杂模式
[root@docker-node1 ~]# ip link set eth1 promisc on
[root@docker-node1 ~]# ip link set up eth1
[root@docker-node1 ~]# ifconfig eth1
eth1: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST>  mtu 1500
        ether 00:0c:29:ce:7a:46  txqueuelen 1000  (Ethernet)
        RX packets 75  bytes 4896 (4.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        
#添加macvlan网路
[root@docker-node1 ~]# docker network create \
> -d macvlan \
> --subnet 1.1.1.0/24 \
> --gateway 1.1.1.1 \
> -o parent=eth1 macvlan1
88995f57ffef146a45e2ceff0e22d73ab3b38385e485e93976f14ee0f260fd4b

[root@docker-node1 ~]# docker run -it --name busybox --network macvlan1 --ip 1.1.1.100 --rm busybox/ # 

/ # ping 1.1.1.200
PING 1.1.1.200 (1.1.1.200): 56 data bytes
64 bytes from 1.1.1.200: seq=0 ttl=64 time=1.038 ms
64 bytes from 1.1.1.200: seq=1 ttl=64 time=0.298 ms
64 bytes from 1.1.1.200: seq=2 ttl=64 time=0.354 ms
^C
--- 1.1.1.200 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.298/0.563/1.038 ms
/ # 


#node2
[root@docker-node2 ~]# docker load -i busybox-latest.tar.gz 
d51af96cf93e: Loading layer  4.495MB/4.495MB
Loaded image: busybox:latest

[root@docker-node2 ~]# docker run -it --name busybox --network macvlan1 --ip 1.1.1.200 --rm busybox/ # 

/ # ping 1.1.1.100
PING 1.1.1.100 (1.1.1.100): 56 data bytes
64 bytes from 1.1.1.100: seq=0 ttl=64 time=0.756 ms
^C
--- 1.1.1.100 ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 0.756/0.756/0.756 ms

5.7 docker的webUI工具(图形化)

[root@docker-node2 ~]# tar zxf 1panel-v1.10.13-lts-linux-amd64
[root@docker-node2 ~]# cd 1panel-v1.10.13-lts-linux-amd64/
[root@docker-node2 1panel-v1.10.13-lts-linux-amd64]# sh install.sh 

 ██╗    ██████╗  █████╗ ███╗   ██╗███████╗██╗     
███║    ██╔══██╗██╔══██╗████╗  ██║██╔════╝██║     
╚██║    ██████╔╝███████║██╔██╗ ██║█████╗  ██║     
 ██║    ██╔═══╝ ██╔══██║██║╚██╗██║██╔══╝  ██║     
 ██║    ██║     ██║  ██║██║ ╚████║███████╗███████╗
 ╚═╝    ╚═╝     ╚═╝  ╚═╝╚═╝  ╚═══╝╚══════╝╚══════╝
[1Panel Log]: ======================= 开始安装 ======================= 
设置 1Panel 安装目录(默认为/opt):
[1Panel Log]: 您选择的安装路径为 /opt 
[1Panel Log]: 检测到 Docker 已安装,跳过安装步骤 
[1Panel Log]: 启动 Docker  
设置 1Panel 端口(默认为26080):8888
[1Panel Log]: 您设置的端口为:8888 
[1Panel Log]: 防火墙未开启,忽略端口开放 
设置 1Panel 安全入口(默认为a9d91009c9):      
[1Panel Log]: 您设置的面板安全入口为:a9d91009c9 
设置 1Panel 面板用户(默认为e2578b9005):
[1Panel Log]: 您设置的面板用户为:e2578b9005 
[1Panel Log]: 设置 1Panel 面板密码(默认为fa68dcaaa1):
[1Panel Log]: 配置 1Panel Service 
Created symlink /etc/systemd/system/multi-user.target.wants/1panel.service → /etc/systemd/system/1panel.service.
[1Panel Log]: 启动 1Panel 服务 
[1Panel Log]: 1Panel 服务启动成功! 
[1Panel Log]:  
[1Panel Log]: =================感谢您的耐心等待,安装已经完成================== 
[1Panel Log]:  
[1Panel Log]: 请用浏览器访问面板: 
[1Panel Log]: 外网地址: http://111.19.7.122:8888/a9d91009c9 
[1Panel Log]: 内网地址: http://172.25.250.200:8888/a9d91009c9 
[1Panel Log]: 面板用户: e2578b9005 
[1Panel Log]: 面板密码: wozhongyini 
[1Panel Log]:  
[1Panel Log]: 项目官网: https://1panel.cn 
[1Panel Log]: 项目文档: https://1panel.cn/docs 
[1Panel Log]: 代码仓库: https://github.com/1Panel-dev/1Panel 
[1Panel Log]:  
[1Panel Log]: 如果使用的是云服务器,请至安全组开放 8888 端口 
[1Panel Log]:  
[1Panel Log]: 为了您的服务器安全,在您离开此界面后您将无法再看到您的密码,请务必牢记您的密码。 
[1Panel Log]:  
[1Panel Log]: ================================================================

#查看登录用户名和密码
1pctl user-info


六 Docker 数据卷管理及优化

Docker 数据卷是一个可供容器使用的特殊目录,它绕过了容器的文件系统,直接将数据存储在宿主机上

这样可以实现以下几个重要的目的:

  • 数据持久化:即使容器被删除或重新创建,数据卷中的数据仍然存在,不会丢失。
  • 数据共享:多个容器可以同时挂载同一个数据卷,实现数据的共享和交互。
  • 独立于容器生命周期:数据卷的生命周期独立于容器,不受容器的启动、停止和删除的影响

6.1 为什么要用数据卷

docker分层文件系统

  • 性能差
  • 生命周期与容器相同

docker数据卷

  • mount到主机中,绕开分层文件系统
  • 和主机磁盘性能相同,容器删除后依然保留
  • 仅限本地磁盘,不能随容器迁移

docker提供了两种卷:

  • bind mount
  • docker managed volume

6.2 bind mount 数据卷

  • 是将主机上的目录或文件mount到容器里。
  • 使用直观高效,易于理解。
  • 使用 -v 选项指定路径
  • 格式 :-v选项指定的路径,如果不存在,挂载时会自动创建
[root@docker-node1 ~]# docker run -it --rm \
> -v /tmp/data1:/data1 \
> -v /tmp/data1:/data2:ro \
> -v /etc/passwd:/data/passwd:ro busybox
/ # tail -n 3 /data/passwd 
tcpdump:x:72:72::/:/sbin/nologin
redhat:x:1000:1000:redhat:/home/redhat:/bin/bash
apache:x:48:48:Apache:/usr/share/httpd:/sbin/nologin
/ # touch /data1/file1
/ # touch /data2/file1 
touch: /data2/file1: Read-only file system

6.3 docker managed 数据卷

  • bind mount必须指定host文件系统路径,限制了移植性
  • docker managed volume 不需要指定mount源,docker自动为容器创建数据卷目录
  • 默认创建的数据卷目录都在 /var/lib/docker/volumes 中
  • 如果挂载时指向容器内已有的目录,原有数据会被复制到volume中
[root@docker-node1 ~]# docker load -i mysql-5.7.tar.gz 

[root@docker-node1 ~]# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD='redhat' mysql:5.7 
7336f76f86b3ca811610f1fd63cd60ae5b6abf7bf653d1afeae8c6c96dde65a5

[root@docker-node1 volumes]# ls -l /var/lib/docker/volumes/
drwx-----x 3 root root     19 Aug 30 11:49 39e99109425ea3322d99b73c5672e6414eca041bbafcdee3c8476d74874f788e

[root@docker-node1 volumes]# touch 39e99109425ea3322d99b73c5672e6414eca041bbafcdee3c8476d74874f788e/_data/file

[root@docker-node1 volumes]# docker exec -it mysql bash
bash-4.2# cd /var/lib/mysql
bash-4.2# ls
auto.cnf    client-cert.pem  ib_buffer_pool  ibdata1  mysql.sock	  public_key.pem   sys
ca-key.pem  client-key.pem   ib_logfile0     ibtmp1   performance_schema  server-cert.pem
ca.pem	    file	     ib_logfile1     mysql    private_key.pem	  server-key.pem
bash-4.2# pwd
/var/lib/mysql

#清理未使用的 Docker 数据卷

#建立数据卷
[root@docker-node1 ~]# docker volume create vol1
vol1
[root@docker-node1 ~]# ls -l /var/lib/docker/volumes/vol1/_data/
total 0

#查看卷
[root@docker-node1 ~]# docker volume ls
local     vol1

#使用建立的数据卷
[root@docker-node1 ~]# docker run -d --name web1 -p 80:80 -v vol1:/usr/share/nginx/html nginx
0ae5ae62f4c2d360731cb2106c7d6c9fadc28af491a05a406c7c1e5380576023
[root@docker-node1 ~]# cd /var/lib/docker/volumes/vol1/_data/
[root@docker-node1 _data]# ls
50x.html  index.html
[root@docker-node1 _data]# echo vol1 > index.html 
[root@docker-node1 _data]# curl 172.25.250.100
vol1

6.4 数据卷容器

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

#建立数据卷容器
[root@docker-node1 ~]# docker run -d --name datavol \
> -v /tmp/data1/:/data1:rw \
> -v /tmp/data2/:/data2:ro \
> -v /etc/resolv.conf:/etc/hosts busybox

#2.使用数据卷容器
[root@docker-node1 ~]# docker run -it --name test --rm --volumes-from datavol busybox
/ # ls
bin    data1  data2  dev    etc    home   lib    lib64  proc   root   sys    tmp    usr    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
search exam.com

# Based on host file: '/etc/resolv.conf' (legacy)
# Overrides: []
/ # touch data1/file1 
/ # touch data2/file1 
touch: data2/file1: Read-only file system
/ # 

6.5 bind mount 数据卷和docker managed 数据卷的对比

#备份数据卷
[root@docker-node1 ~]# docker run --volumes-from datavol \
> -v `pwd`:/backup busybox \
> tar zcf /backup/data1.tar.gz /data1

#数据恢复
[root@docker-node1 ~]# docker run --volumes-from datavol \
> -v `pwd`:/backup busybox \
> tar zcf /backup/data1.tar.gz /data1
tar: removing leading '/' from member names
[root@docker-node1 ~]# docker run -it --name test -v vol1:/data1 -v `pwd`:/backup busybox /bin/sh -c "tar zxf /backup/data1.tar.gz;/bin/sh"
/ # ls
backup  data1   etc     lib     proc    sys     usr
bin     dev     home    lib64   root    tmp     var
/ # cd data1/
/data1 # ls
50x.html    file1       index.html

七 Docker 的安全优化

Docker容器的安全性,很大程度上依赖于Linux系统自身

评估Docker的安全性时,主要考虑以下几个方面:

  • Linux内核的命名空间机制提供的容器隔离安全 
  • Linux控制组机制对容器资源的控制能力安全
  • Linux内核的能力机制所带来的操作权限安全 
  • 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-node1 ~]# mount -t cgroup
[root@docker-node1 ~]# mount -t cgroup2
cgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)


grubby --update-kernel=/boot/vmlinuz-$(uname -r) \
--args="systemd.unified_cgroup_hierarchy=0 systemd.legacy_systemd_cgroup_controller"
reboot


#1 命名空间隔离的安全
[root@docker-node1 ~]# docker run -d --name web nginx
b40927e1e0d62f7f7dcd2870a11ef7983d8436d6ba0ecb2ff0d92e533e9f6d3c
[root@docker-node1 ~]# docker inspect web | grep Pid
            "Pid": 4669,
            "PidMode": "",
            "PidsLimit": null,
[root@docker-node1 ~]# cd /proc/4669/ns/
[root@docker-node1 ns]# ls
cgroup  ipc  mnt  net  pid  pid_for_children  time  time_for_children  user  uts
[root@docker-node1 ns]# ls -d /sys/fs/cgroup/memory/docker/b40927e1e0d62f7f7dcd2870a11ef7983d8436d6ba0ecb2ff0d92e533e9f6d3c/
/sys/fs/cgroup/memory/docker/b40927e1e0d62f7f7dcd2870a11ef7983d8436d6ba0ecb2ff0d92e533e9f6d3c/
[root@docker-node1 ns]# 

2 控制组资源控制的安全
[root@docker-node1 ~]# docker run -it --name test busybox
/ # free -m
              total        used        free      shared  buff/cache   available
Mem:           1743         396         834           6         513        1194
Swap:          4096           0        4096
/ # exit
[root@docker-node1 ~]# free -m
               total        used        free      shared  buff/cache   available
Mem:            1743         512         870           6         514        1231
Swap:           4095           0        4095

7.1 Docker的资源限制

Linux Cgroups 的全称是 Linux Control Group。

  • 是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。
  • 对进程进行优先级设置、审计,以及将进程挂起和恢复等操作。

Linux Cgroups 给用户暴露出来的操作接口是文件系统

  • 它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。
  • 执行此命令查看:mount -t cgroup
[root@docker-node1 ~]# mount -t cgroup

7.1.1.限制cpu使用

[root@docker-node1 ~]# docker load -i ubuntu-latest.tar.gz 
f36fd4bb7334: Loading layer  80.56MB/80.56MB
Loaded image: ubuntu:latest

[root@docker-node1 ~]# docker run -it --rm --name test \
> --cpu-period 100000 \
> --cpu-quota 20000 ubuntu

root@59bb8bdc0225:/# dd if=/dev/zero of=/dev/null &
[1] 9
root@59bb8bdc0225:/# top
top - 07:13:26 up 20 min,  0 user,  load average: 0.97, 0.51, 0.21
Tasks:   3 total,   2 running,   1 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.7 us,  2.0 sy,  0.0 ni, 96.9 id,  0.0 wa,  0.2 hi,  0.2 si,  0.0 st 
MiB Mem :   1743.5 total,    668.4 free,    550.4 used,    682.0 buff/cache     
MiB Swap:   4096.0 total,   4096.0 free,      0.0 used.   1193.1 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                    
      9 root      20   0    2736   1408   1408 R  19.7   0.1   0:09.68 dd                         
      1 root      20   0    4588   3712   3200 S   0.0   0.2   0:00.01 bash                       
     10 root      20   0    8848   5120   3072 R   0.0   0.3   0:00.00 top
     
#在cgroup中查看docker的资源限制

2.限制cpu的优先级
#关闭cpu的核心,当cpu都不空闲下才会出现争抢的情况,为了实验效果我们可以关闭一个cpu核心
[root@docker-node1 ~]# echo 0 > /sys/devices/system/cpu/cpu1/online 

[root@docker-node1 ~]# cat /proc/cpuinfo 

[root@docker-node1 ~]# docker run -it --rm --cpu-shares 100 ubuntu
root@5ecafc581a63:/# dd if=/dev/zero of=/dev/null &
[1] 9
root@5ecafc581a63:/# top

7.1.2 限制内存使用

#安装依赖性
libcgroup-0.41-19.el8.x86_64.rpm
libcgroup-tools-0.41-19.el8.x86_64.rpm

#开启容器并限制容器使用内存大小
[root@docker-node1 ~]# docker run -d --name test --memory 200M --memory-swap 200M nginx
6010d0618fb82d8687b3d15179537a3fadc746bce745f816514f59c7122d1166

#查看容器内存使用限制
[root@docker-node1 ~]# cd /sys/fs/cgroup/memory/docker/6010d0618fb82d8687b3d15179537a3fadc746bce745f816514f59c7122d1166/
[root@docker-node1 6010d0618fb82d8687b3d15179537a3fadc746bce745f816514f59c7122d1166]# cat memory.limit_in_bytes 
209715200
[root@docker-node1 6010d0618fb82d8687b3d15179537a3fadc746bce745f816514f59c7122d1166]# cat memory.memsw.limit_in_bytes 
209715200

#测试容器内存限制,在容器中我们测试内存限制效果不是很明显,可以利用工具模拟容器在内存中写入数据
#在系统中/dev/shm这个目录被挂在到内存中
[root@docker-node1 ~]# docker run -d --name test --memory 200M --memory-swap 200M nginx
415ee962d70e40bdac774b2869d5e4d6faa13479bd74608e7b1618e9d46327ee

[root@docker-node1 ~]# cgexec -g memory:docker/415ee962d70e40bdac774b2869d5e4d6faa13479bd74608e7b1618e9d46327ee 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.53283 s, 295 MB/s
[root@docker-node1 ~]# cgexec -g memory:docker/415ee962d70e40bdac774b2869d5e4d6faa13479bd74608e7b1618e9d46327ee dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=120
120+0 records in
120+0 records out
125829120 bytes (126 MB, 120 MiB) copied, 0.0695907 s, 1.8 GB/s
[root@docker-node1 ~]# cgexec -g memory:docker/415ee962d70e40bdac774b2869d5e4d6faa13479bd74608e7b1618e9d46327ee dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=200
Killed
[root@docker-node1 ~]# 

也可以自建控制器

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

[root@docker-node1 ~]# rm -rf /dev/shm/bigfile 
[root@docker-node1 ~]# echo 209715200 > /sys/fs/cgroup/memory/x1/memory.memsw.limit_in_bytes 

[root@docker-node1 ~]# rm -rf /dev/shm/bigfile 
[root@docker-node1 ~]# echo 209715200 > /sys/fs/cgroup/memory/x1/memory.memsw.limit_in_bytes 
[root@docker-node1 ~]# cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=200
Killed
[root@docker-node1 ~]# cgexec -g memory:x1 dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=199
Killed

7.1.3 限制docker的磁盘io

[root@docker-node1 ~]# docker run -it --rm \
--device-write-bps \			#指定容器使用磁盘io的速率
/dev/nvme0n1:30M \				#/dev/nvme0n1是指定系统的磁盘,30M即每秒30M数据
ubuntu

root@149e8aba1b2f:/# dd if=/dev/zero of=bigfile	#开启容器后会发现速度和设定不匹配,是因为系统的缓存机制
^C1576748+0 records in
1576748+0 records out
807294976 bytes (807 MB, 770 MiB) copied, 5.85982 s, 138 MB/s

root@149e8aba1b2f:/# 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.0558805 s, 1.9 GB/s

root@149e8aba1b2f:/# dd if=/dev/zero of=bigfile bs=1M count=100 oflag=direct #设定dd命令直接写入磁盘
100+0 records in
100+0 records out
104857600 bytes (105 MB, 100 MiB) copied, 3.33922 s, 31.4 MB/s

7.2 Docker的安全加固

7.2.1 容器特权

[root@docker-node1 ~]# docker run --rm -it --privileged busybox
/ # id root
uid=0(root) gid=0(root) groups=0(root),10(wheel)
/ # ip a a 172.25.250.111/24 dev eth0
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
70: eth0@if71: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet 172.25.250.111/24 scope global eth0
       valid_lft forever preferred_lft forever
/ # fdisk -l
Disk /dev/nvme0n1: 20 GB, 21474836480 bytes, 41943040 sectors
82241 cylinders, 255 heads, 2 sectors/track
Units: sectors of 1 * 512 = 512 bytes

Device       Boot StartCHS    EndCHS        StartLBA     EndLBA    Sectors  Size Id Type
/dev/nvme0n1p1 *  4,4,1       1023,254,2        2048    2099199    2097152 1024M 83 Linux
/dev/nvme0n1p2    1023,254,2  1023,254,2     2099200   41943039   39843840 18.9G 8e Linux LVM
Disk /dev/dm-0: 15 GB, 16101933056 bytes, 31449088 sectors
1957 cylinders, 255 heads, 63 sectors/track
Units: sectors of 1 * 512 = 512 bytes

Disk /dev/dm-0 doesn't contain a valid partition table
Disk /dev/dm-1: 4096 MB, 4294967296 bytes, 8388608 sectors
522 cylinders, 255 heads, 63 sectors/track
Units: sectors of 1 * 512 = 512 bytes

Disk /dev/dm-1 doesn't contain a valid partition table

7.2.2 容器特权的白名单

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

#限制容器对网络有root权限
[root@docker-node1 ~]# docker run --rm -it --cap-add NET_ADMIN busybox
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
72: eth0@if73: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ip a a 1.1.1.1/24 dev eth0		#网络可以设定
/ # fdisk -l						#无法管理磁盘

/ # 

八 容器编排工具Docker Compose

8.1 Docker Compose 概述

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

主要功能

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)容器是服务的具体实例,每个服务可以有一个或多个容器。容器是基于服务定义的镜像创建的运行实例

8.2 Docker Compose 的常用命令参数

[root@docker-node1 ~]# vim docker/docker-compose.yml 

services:
  web:
    image: nginx
    ports:
      - "80:80"

  db: 
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: redhat

#服务管理
启动
[root@docker-node1 ~]# cd docker/
[root@docker-node1 docker]# docker compose up -d
[+] Running 2/2
 ✔ Container docker-db-1   Running                                                             0.0s 
 ✔ Container docker-web-1  Started                                                             0.4s
 
 [root@docker-node1 ~]# docker compose -f docker/docker-compose.yml up -d
[+] Running 2/0
 ✔ Container docker-db-1   Running                                                             0.0s 
 ✔ Container docker-web-1  Running                                                             0.0s

1. docker-compose up 

  • 启动配置文件中定义的所有服务。
  • 可以使用 -d 参数在后台启动服务。
  • 可以使用-f 来指定yml文件
  • 例如: docker-compose up -d

2. docker-compose down

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

#docker-compose down
停止并删除配置文件中定义的所有服务以及相关的网络和存储卷
[root@docker-node1 ~]# docker compose -f docker/docker-compose.yml down 
[+] Running 3/3
 ? Container docker-db-1   Removed                                                             1.1s 
 ? Container docker-web-1  Removed                                                             0.1s 
 ? Network docker_default  Removed                                                             0.1s

3. docker-compose start

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

docker-compose start
启动已经存在的服务,但不会创建新的服务
[root@docker-node1 docker]# docker compose start 
[+] Running 2/2
 ✔ Container docker-web-1  Started                                                             0.4s 
 ✔ Container docker-db-1   Started                                                             0.3s

4. docker-compose stop

停止正在运行的服务

docker-compose stop
停止正在运行的服务
[root@docker-node1 docker]# docker compose stop
[+] Stopping 2/2
 ✔ Container docker-web-1  Stopped                                                             0.2s 
 ✔ Container docker-db-1   Stopped                                                            10.1s

5. docker-compose restart

重启服务

二、服务状态查看

1. docker-compose ps

#服务状态查看
[root@docker-node1 ~]# docker compose -f docker/docker-compose.yml ps
NAME           IMAGE       COMMAND                  SERVICE   CREATED         STATUS              PORTS
docker-db-1    mysql:5.7   "docker-entrypoint.s."   db        3 minutes ago   Up 3 minutes        3306/tcp, 33060/tcp
docker-web-1   nginx       "/docker-entrypoint.¡."   web       3 minutes ago   Up About a minute   0.0.0.0:80->80/tcp, :::80->80/tcp

2. docker-compose logs

查看服务的日志输出。可以指定服务名称来查看特定服务的日志

[root@docker-node1 docker]# docker compose logs db

三、构建和重新构建服务

[root@docker-node1 ~]# mkdir test
[root@docker-node1 ~]# cd test/
[root@docker-node1 test]# vim Dockerfile

[root@docker-node1 ~]# cd docker/
[root@docker-node1 docker]# ls
howe.Dockerfile
[root@docker-node1 docker]# vim howe.Dockerfile 

8.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 端口。

services:
 web:
   image: superhowe/mario
   container_name: game #指定容器名称
    restart: always   #docekr容器自动启动
   expose:
   - 1234 #指定容器暴露那些端口,些端口仅对链接的服务
可见,不会映射到主机的端口
   ports:
      - "80:8080"

4. 环境变量(environment)

        为容器设置环境变量,可以在容器内部的应用程序中使用。例如, VAR1: value1 设置环境变 量 VAR1 的值为 value1

services:
  web:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: redhat

5. 存储卷(volumes):
        将主机上的目录或文件挂载到容器中,以实现数据持久化或共享。

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

services:
  web:
    image: busybox
    command: ["/bin/sh","-c","sleep 100000"]
    container_name: busybox1
    volumes: 
      - /etc/passwd:/tmp/passwd:ro        #只读挂在本地文件到指定位置

6. 网络(networks):

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

services:
  web:
    image: nginx
    container_name: webserver
    network_mode: bridge #使用本机自带bridge网络
services:
  test:
    image: busybox 
    container_name: webserver
    command: ["/bin/sh","-c","sleep10000000"]
 
  networks:
    - mynet1
    - mynet2
 
  networks:
    mynet1:
      driver: bridge
    mynet2:
      driver: bridge

7. 命令(command):

覆盖容器启动时默认执行的命令。例如, command: python app.py 指定容器启动时运行 python app.py 命令

services:
 web:
   image: busybox
   container_name: busybox
   #network_mode: mynet2
   command: ["/bin/sh","-c","sleep10000000"]

二、网络(networks)

定义 Docker Compose 应用程序中使用的网络。可以自定义网络名称和驱动程序等属性。默认情况下docker compose 在执行时会自动建立网路

services:
  test1:
    image: busybox:latest
    command: ["/bin/sh","-c","sleep 10000"]
    network_mode: default
    container_name: test

  test2:
    image: busybox:latest
    command: ["/bin/sh","-c","sleep 100000"]
    container_name: test2
    networks:
      - mynet1
      - mynet2

networks:
  default:
    external: true
    name: bridge

  mynet1:
    driver: brige

  mynet2:
    ipam:
      driver: default
      config:
        - subnet: 172.26.0.0/24
          gateway: 172.26.0.2
         

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

三、存储卷(volumes)

定义 Docker Compose 应用程序中使用的存储卷。可以自定义卷名称和存储位置等属性

services:
  test1:
    image: busybox:latest
    command: ["/bin/sh","-c","sleep 10000"]
    network_mode: default
    container_name: test

  test2:
    image: busybox:latest
    command: ["/bin/sh","-c","sleep 100000"]
    container_name: test2
    networks:
      - mynet1
      - mynet2
    volumes:
      - data:/data			#挂在data卷

networks:
  default:
    external: true
    name: bridge

  mynet1:
    driver: bridge

  mynet2:
    ipam:
      driver: default
      config:
        - subnet: 172.26.0.0/24
          gateway: 172.26.0.2

  volumes:
    data:
      name: howe		#指定建立卷的名字


#检测语法错误
docker compose config 
docker compose config -q #不打印错误

8.4 企业示例

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

[root@docker-node2 ~]# yum install haproxy -y --downloadonly --downloaddir=/mnt
[root@docker-node2 test]# cd /mnt/
[root@docker-node2 mnt]# ls
haproxy-2.4.22-3.el9_3.x86_64.rpm  hgfs
[root@docker-node2 mnt]# rpm2cpio haproxy-2.4.22-3.el9_3.x86_64.rpm | cpio -id
13488 blocks
[root@docker-node2 mnt]# 
[root@docker-node2 mnt]# ls
etc  haproxy-2.4.22-3.el9_3.x86_64.rpm  hgfs  usr  var
[root@docker-node2 mnt]# 
[root@docker-node2 mnt]# cd etc/
[root@docker-node2 etc]# ls
haproxy  logrotate.d  sysconfig
[root@docker-node2 mnt]# 
[root@docker-node2 etc]# cd haproxy/
[root@docker-node2 haproxy]# ls
conf.d  haproxy.cfg

[root@docker-node2 haproxy]# mkdir /var//lib/docker/volumes/conf
[root@docker-node2 haproxy]# cp haproxy.cfg /var/lib/docker/volumes/conf/
[root@docker-node2 haproxy]# cd /var/lib/docker/volumes/conf/
[root@docker-node2 conf]# ls
haproxy.cfg
[root@docker-node2 conf]# vim haproxy.cfg 
...
listen webcluter
  bind *:80
  balance roundrobin
  server web1 webserver1:80 check inter 3 fall 3 rise 5
  server web2 webserver2:80 check inter 3 fall 3 rise 5
...

[root@docker-node2 ~]# cd test/
[root@docker-node2 test]# ls
docker-compose.yml
[root@docker-node2 test]# vim docker-compose.yml 
[root@docker-node2 test]# cat docker-compose.yml 
services:
  web1:
    image: nginx:latest
    container_name: webserver1
    restart: always
    expose:
      - 80
    volumes:
      - data_web1:/usr/share/nginx/html
    networks:
      - internel
 
  web2:
    image: nginx:latest
    container_name: webserver2
    restart: always
    expose:
      - 80
    volumes:
      - data_web2:/usr/share/nginx/html
    networks:
      - internel
 
  haproxy:
    image: haproxy:2.3
    restart: always
    container_name: haproxy
    ports:
      - "80:80"
    volumes:
      - /var/lib/docker/volumes/conf/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg
 
    networks:
      - internel
      - extrnal
 
networks:
  internel:
    driver: bridge
 
  extrnal:
    driver: bridge
 
volumes:
  data_web1:
    name: data_web1
 
  data_web2:
    name: data_web2

[root@docker-node2 test]# docker compose -f docker-compose.yml up -d
[+] Running 5/5
✔ Network test_mynet1 Created
0.1s
✔ Network test_mynet2 Created
0.1s
✔ Container haproxy Started
0.8s
✔ Container web1 Started
0.7s
✔ Container web2 Started
0.6s

[root@docker-node2 test]# docker compose -f haproxy.yml up -d
[+] Running 7/7
 ✔ Network test_internel  Created                                                                                                                                     0.1s 
 ✔ Network test_extrnal   Created                                                                                                                                     0.1s 
 ✔ Volume "data_web2"     Created                                                                                                                                     0.0s 
 ✔ Volume "data_web1"     Created                                                                                                                                     0.0s 
 ✔ Container haproxy      Started                                                                                                                                     1.2s 
 ✔ Container webserver1   Started                                                                                                                                     1.2s 
 ✔ Container webserver2   Started                                                                                                                                     1.1s 
[root@docker-node2 test]# docker ps
CONTAINER ID   IMAGE          COMMAND                  CREATED         STATUS         PORTS                               NAMES
7158668dd70f   nginx:latest   "/docker-entrypoint.…"   7 seconds ago   Up 6 seconds   80/tcp                              webserver2
8aa9a99597df   haproxy:2.3    "docker-entrypoint.s…"   7 seconds ago   Up 6 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   haproxy
d5f6b242b8e1   nginx:latest   "/docker-entrypoint.…"   7 seconds ago   Up 6 seconds   80/tcp                              webserver1


#写入内容并测试:
[root@docker-node2 test]# echo webserver1 > /var/lib/docker/volumes/data_web1/_data/index.html
[root@docker-node2 test]# echo webserver2 > /var/lib/docker/volumes/data_web2/_data/index.html

[root@docker-node2 test]# curl 172.25.250.200
webserver2
[root@docker-node2 test]# curl 172.25.250.200
webserver1
[root@docker-node2 test]# curl 172.25.250.200
webserver2
[root@docker-node2 test]# curl 172.25.250.200
webserver1

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2107597.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【串的相关概念】

1.前情回顾&#xff1a; 2.串的定义 注意这里的字符是任意字符&#xff1a;包括特殊字符和空格 2.1串的相关术语 2.2分析如下&#xff1a; 子串与主串 可以类比 子集与集合的关系 且空串也是子串的一种 注意空格串与空串的区别 位置是从1开始设定的&#xff08;第一个位置开始…

【java入门】关键字、标识符与变量初识

&#x1f680; 个人简介&#xff1a;某大型国企资深软件开发工程师&#xff0c;信息系统项目管理师、CSDN优质创作者、阿里云专家博主&#xff0c;华为云云享专家&#xff0c;分享前端后端相关技术与工作常见问题~ &#x1f49f; 作 者&#xff1a;码喽的自我修养&#x1f9…

Java 入门指南:Java 并发编程 —— 并发容器 PriorityBlockingQueue

BlockingQueue BlockingQueue 是Java并发包&#xff08;java.util.concurrent&#xff09;中提供的一个阻塞队列接口&#xff0c;它继承自 Queue 接口。 BlockingQueue 中的元素采用 FIFO 的原则&#xff0c;支持多线程环境并发访问&#xff0c;提供了阻塞读取和写入的操作&a…

「C++」类和对象(2)

欢迎大家来到小鸥的类和对象第二篇博客~ 目录 类的默认成员函数 构造函数 构造函数的特点&#xff1a; 析构函数 析构函数的特点&#xff1a; 拷贝构造函数 拷贝构造的特点&#xff1a; 结语&#xff1a; 本篇会着重讲解类和对象中的难点&#xff1a;类的默认成员函数 …

Ubuntu环境的MySql下载安装

下载压缩包 此文章下载的mysql版本位5.7.29 sudo wget https://downloads.mysql.com/archives/get/p/23/file/mysql-server_5.7.29-1ubuntu18.04_amd64.deb-bundle.tar解压缩 sudo tar -xvf mysql-server_5.7.29-1ubuntu18.04_amd64.deb-bundle.tar命令解释 -x&#xff1a;…

鸿蒙Next-拉起支付宝的三种方式——教程

鸿蒙Next-拉起支付宝的三种方式——教程 鸿蒙Next系统即将上线&#xff0c;应用市场逐渐丰富、很多APP都准备接入支付宝做支付功能&#xff0c;目前来说有三种方式拉起支付宝&#xff1a;通过支付宝SDK拉起、使用OpenLink拉起、传入支付宝包名使用startAbility拉起。以上的三种…

走心机做不锈钢哪个牌子好

不锈钢是现代生活中不可或缺的材料&#xff0c;它广泛应用于厨房用具、家具、建筑等领域。在市场上&#xff0c;有许多不锈钢需要加工零件供消费者选择&#xff0c;那么在选择不锈钢加工零件时制品时&#xff0c;应该如何选择数控走心机&#xff0c;找到最好的品牌呢&#xff1…

CodeSys中动态切换3D模型

文章目录 需求研究结果 需求 在前面的【CodeSys开发3d机械臂显示控件】中&#xff0c;我们已经实现了一个可以显示3d模型的控件。但是这个控件是和使用的3d模型绑定死的&#xff0c;在安装这个控件时就已经将模型文件于控件一起安装到codesys中。 假如我想在不同的工程中&…

Numpy中type()、ndim、shape、size、dtype、astype的用法

目录 numpy基础介绍示例分析及总结&#xff1a;itemsize、nbytes函数 numpy基础介绍 Numpy 补充了Python语言所欠缺的数值计算能力,是其它数据分析及机器学习库的底层库。因其完全标准C语言实现&#xff0c;运行效率充分优化。最重要一点是开源免费。numpy的核心是矩阵&#x…

思维导图怎么画好看又简单?5个软件帮助你快速进行思维导图绘制

思维导图怎么画好看又简单&#xff1f;5个软件帮助你快速进行思维导图绘制 思维导图是一种有效的思维整理和展示工具&#xff0c;可以帮助你将复杂的想法进行可视化&#xff0c;提升工作和学习效率。为了让思维导图既好看又简单&#xff0c;选择合适的软件能够大大提高绘制效率…

UE中Camera Clip截面修改

UE中Camera无法修改远截面&#xff08;FarClipingPlane)&#xff0c;只可修改近截面&#xff08;NearClipingPlane&#xff09;&#xff1a; 至于为什么无法修改远截面&#xff0c;看下代码&#xff0c;尝试继承UE的CameraComponent打印出相机投影矩阵&#xff1a; #include …

python编程知识(实现数据加密和解密)

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

在模板中使用 Django 会话

在 Django 中使用会话&#xff08;session&#xff09;可以让你在用户访问网站的过程中存储和访问临时数据。我们可以利用会话在速度计算器的例子中存储和显示上次计算的结果。 1、问题背景 在 Django 中&#xff0c;可以使用会话来存储用户数据。在某些情况下&#xff0c;我们…

双绞线如何抑制传导干扰

一&#xff0e;案例简介 产品去做CE认证时&#xff0c;被告知传导抗扰未通过&#xff0c;网络会断连。 剖开网线外皮&#xff0c;发现内部是散装的&#xff0c;非双绞线。因此换成双绞线网线&#xff0c;复测&#xff0c;传导抗扰通过了。 图1 非双绞线和双绞线示意图 为什么…

经销商数据对接方案:借助轻易云数据集成平台实现高效互联

在现在很多品牌方的实际需求中&#xff0c;品牌商与经销商之间的渠道博弈日益激烈。品牌商渴望掌握经销商的销量和库存数据&#xff0c;以便更好地规划生产和库存&#xff0c;提升品牌影响力&#xff1b;经销商则期望在避免库存积压的同时抢占市场&#xff0c;加速资金周转以获…

活动预告|“AI+Security”系列第3期:AI安全智能体,重塑安全团队工作范式

由安全极客、Wisemodel社区、InForSec网络安全研究国际学术论坛和海升集团联合主办的 “AISecurity”系列第3期&#xff1a; AI 安全智能体&#xff0c;重塑安全团队工作范式 线下活动 将于2024年9月11日下午14:00 在中关村智造大街G座路演厅 正式举行 欢迎扫描海报中二…

Javaweb(前端)

目录 Web开发 Web前端 HTMLCSS 盒子模型 JavaScript js引入方式 js基础语法 js函数 js对象&#xff08;JSONBOMDOM&#xff09; js事件监听 Vue ​编辑Vue快速入门 Vue常用指令 Vue生命周期 Ajax 原生Ajax Axios YApi&#xff08;应用网页&#xff09; 前端工程…

打造一流的研发型企业--- 金发科技研发驱动力初探

2006年3月29日&#xff0c;国家发改委副主任欧新黔亲自为金发科技颁发了“中国改性塑料行业第一位”、“中国合成材料制造业十强”、“中国石油化工全行业百强”三块铜牌证书&#xff0c;金发科技终于成为名符其实的行业“老大”。公司产品销售额增长迅速&#xff0c; 2006年完…

Java健康养老智慧相伴养老护理小程序系统源码代办陪诊陪护更安心

健康养老&#xff0c;智慧相伴 —— 养老护理小程序&#xff0c;代办陪诊陪护更安心 &#x1f308;【开篇&#xff1a;智慧养老&#xff0c;新时代的温馨守护】&#x1f308; 在这个快节奏的时代&#xff0c;我们总希望能给予家人更多的关爱与陪伴&#xff0c;尤其是家中的长…