Docker容器技术详解

一、Docker简介及部署方法

1.1Docker简介

1.1.1什么是docker

Docker是管理容器的引擎,为应用打包、部署平台,而非单纯的虚拟化技术

docker的重要特点和优势:

1. 轻量级虚拟化Docker 容器相较于传统的虚拟机更加轻量和高效,能够快速启动和停止,节省系统资源。 例如,启动一个 Docker 容器可能只需要几秒钟,而启动一个虚拟机则可能需要几分钟。
2. 一致性确保应用程序在不同的环境中(如开发、测试、生产)具有一致的运行表现。 无论在本地还是云端,应用的运行环境都能保持相同,减少了因环境差异导致的问题。
3. 可移植性可以轻松地将 Docker 容器从一个平台迁移到另一个平台,无需担心依赖和环境配置的差 异。 比如,在本地开发的容器可以无缝部署到云服务器上。
4. 高效的资源利用多个 Docker 容器可以共享主机的操作系统内核,从而更有效地利用系统资 源。
5. 易于部署和扩展能够快速部署新的应用实例,并且可以根据需求轻松地进行水平扩展。

总之,Docker 极大地简化了应用程序的开发、部署和管理流程,提高了开发效率和运维的便利性。 它在现代软件开发和云计算领域得到了广泛的应用。 

1.1.2docker与虚拟化的对比

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

1.2部署docker

1.2.1容器的工作原理

镜像:容器的母盘

容器:真正运行的业务实例,靠镜像运行起来(在镜像中打开容器)。

仓库:存放镜像

工作原理:

当我们有容器就可以直接运行业务,如果没有就需要去仓库把镜像拉过来运行起来就是容器。

1.2.2部署一个容器

这里因为我们有压缩包所以直接安装的

获取包

[root@docker-node2 ~]# ls
anaconda-ks.cfg        Desktop        Documents  Music     Public     Videos
busybox-latest.tar.gz  docker.tar.gz  Downloads  Pictures  Templates
[root@docker-node2 ~]# tar zxf docker.tar.gz
[root@docker-node2 ~]# ls
[root@docker-node2 ~]# dnf install *.rpm -y --allowerasing——如果有冲突加上这个参数

1.2.2.1配置软件仓库

安装正常部署的话需要先配软件源,这里以企业7为例

]# cd /etc/yum.repos.d

]# vim docker.repo

[docker]

name=docker-ce

baseurl=https://mirrors.tuna.tsinghua.edu.cn/docker ce/linux/centos/7/x86_64/stable/ gpgcheck=0

[centos]

name=extras

baseurl=https://mirrors.tuna.tsinghua.edu.cn/centos/7/extras/x86_64

gpgcheck=0

1.2.2.2安装docker-ce并启动服务

#安装docker ]# yum install -y docker-ce

#编辑docker启动文件,设定其使用iptables的网络设定方式,默认使用nftables [root@docker ~]# vim /usr/lib/systemd/system/docker.service

ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=true

]# systemctl enable --now docker

]# docker info

1.2.2.3 激活内核网络选项

#在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.1Docker镜像管理

2.1.1搜索镜像

[root@docker-node1 ~]# docker search nginx 

2.1.2拉取镜像

[root@docker-node1 ~]# docker pull nginx 

2.1.3查看镜像信息

[root@Docker-node1 ~]# docker image inspect nginx:1.26-alpine

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


2.1.5删除镜像

[root@Docker-node1 ~]# docker rmi nginx:latest

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

2.1.6恢复镜像

[root@Docker-node1 ~]# docker load -i  nginx.latest.tar.gz

2.2容器的常用操作

2.2.1启动容器

参数说明

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

[root@Docker-node1 ~]# docker run -d --name mario -p 80:8080 timinglee/mario [root@Docker-node1 ~]# docker run -it --name centos7 centos:7

[root@3ba22e59734f /]# #进入到容器中,按+退出并停止容器,#按+退出但 不停止容器

#重新进入容器

[root@docker ~]# docker attach centos7

[root@3ba22e59734f /]#

#在容器中执行命令

[root@docker ~]# docker exec -it test ifconfig

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 run -it --name test busybox

/ # touch leefile——在容器中建立文件

[root@Docker-node1 ~]# docker rm test

[root@Docker-node1 ~]# docker run -it --name test busybox——删除容器后开启新的容器文件不存在

/ # ls

[root@Docker-node1 ~]# docker commit -m "add leefile" test busybox:v1 sha256:c8ff62b7480c951635acb6064acdfeb25282bd0c19cbffee0e51f3902cbfa4bd

可以看到有一个添加好文件的镜像

[root@Docker-node1 ~]# docker images

查看历史操作

[root@Docker-node1 ~]# docker image history busybox:v1

此方法不利于企业审计,所以不推荐使用,在企业中我们多用Dockerfile来构建镜像

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

[root@Docker-node1 ~]# docker cp test2:/leefile /mnt #把容器中的文件复制到本机,test2表示容器名

Successfully copied 1.54kB to /mnt

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

2.2.7 查询容器内部日志

[root@Docker-node1 ~]# docker logs web

三、Docker镜像构建

3.1docker镜像结构

共享宿主机的kernel

base镜像提供的是最小的Linux发行版

同一docker主机支持运行多种Linux发行版

采用分层结构的最大好处是:共享资源

3.2 镜像运行的基本原理

Copy-on-Write 可写容器层

容器层以下所有镜像层都是只读的

docker从上往下依次查找文件

容器层保存镜像变化的部分,并不会对镜像本身进行任何修改

一个镜像最多127层

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 443
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 jclfile
[root@docker-node1 docker]# vim Dockerfile

下面编辑文件中ADD 参数后再加一个 /,不然要报错

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

可以看到如果像以上文件中的那种写法会有两个警告

可以看到虽然有警告但还是可以运行

并且实行打印,但是CMD是可以被代替的,所以如果加一个sh就不会打印了

写法换成一下两条就可以看到没有警告

运行容器可以执行echo

如果将ENTRYPOINT注释打开,可以看到命令不可被覆盖

可以显示端口

通过这条命令可以看到该层镜像执行了哪些操作

[root@docker-node1 ~]# docker history example:v2
IMAGE          CREATED         CREATED BY                                     SIZE      COMMENT
94887e91180e   6 hours ago     EXPOSE map[443/tcp:{} 80/tcp:{}]               0B        buildkit.dockerfile.v0
<missing>      6 hours ago     ENTRYPOINT ["/bin/sh" "-c" "echo hello jcl"]   0B        buildkit.dockerfile.v0
<missing>      6 hours ago     ENV name=jcl                                   0B        buildkit.dockerfile.v0
<missing>      6 hours ago     ADD jclfile.gz / # buildkit                    0B        buildkit.dockerfile.v0
<missing>      6 hours ago     LABEL user=jcl                                 0B        buildkit.dockerfile.v0
<missing>      6 hours ago     COPY jclfile / # buildkit                      0B        buildkit.dockerfile.v0
<missing>      15 months ago   BusyBox 1.36.1 (glibc), Debian 12              4.26MB

编辑Dockerfile 重新构建镜像注释ENTRYPOINT参数

运行容器会发现file1 file2是通过ADD从宿主机上上传并解压出来的,jclfile是通过copy复制过来的

 VOLUME WORKDIR RUN参数 

查看容器具体信息可以看到有挂载点

[root@docker-node1 docker]# docker inspect  test

3.4.2Dockerfile实例

构建nginx镜像

将软件压缩包拖到mnt目录下

[root@docker-node1 mnt]# ll

total 373024

-rw-r--r--  1 root root 211699200 Aug 27 22:23 centos-7.tar.gz

-rw-r--r--  1 root root  22456832 Aug 27 22:23 debian11.tar.gz

drwxr-xr-x. 2 root root         6 Jul 31 15:22 hgfs

-rw-r--r--  1 root root 146568704 Aug 27 22:23 nginx-1.23.tar.gz

-rw-r--r--  1 root root   1244738 Aug 27 22:23 nginx-1.26.1.tar.gz

将系统镜像导入

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

174f56854903: Loading layer  211.7MB/211.7MB

挂载系统7镜像

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

[root@docker-node1 docker]# vim /etc/httpd/conf/httpd.conf——把端口改成8080防止端口冲突

[root@docker-node1 docker]# systemctl start httpd

[root@docker-node1 docker]# mkdir /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.

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

[root@804ff4f252a7 /]# ls

anaconda-post.log  dev  home  lib64  mnt  proc  run   srv  tmp  var

bin                etc  lib   media  opt  root  sbin  sys  usr

[root@docker-node1 ~]# docker inspect centos

[root@docker-node1 yum.repos.d]# docker run -it --name centos centos:7

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

[root@804ff4f252a7 yum.repos.d]# ls

CentOS-Base.repo       CentOS-Media.repo    CentOS-fasttrack.repo

CentOS-CR.repo         CentOS-Sources.repo  CentOS-x86_64-kernel.repo

CentOS-Debuginfo.repo  CentOS-Vault.repo

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

[root@804ff4f252a7 yum.repos.d]# ls

[root@804ff4f252a7 yum.repos.d]# vi rhel9.repo

[centos7]

name=centos7

baseurl=http://172.17.0.1:8080/rhel7.9

gpgcheck=0

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

sha256:6c2c6db9859754381fc7426aff152c55607d0a640dfa12316000cafc3b62a177

[root@docker-node1 rhel9]# docker images

REPOSITORY           TAG       IMAGE ID       CREATED          SIZE

centos               repo      6c2c6db98597   52 seconds ago   204MB

编辑构建文件

[root@docker-node1 docker]# mv /mnt/nginx-1.26.1.tar.gz .

[root@docker-node1 docker]# ls

Dockerfile  nginx-1.26.1.tar.gz

[root@docker-node1 ~]# cd docker/

[root@docker-node1 docker]# vim Dockerfile

FROM centos::repo——用centos7基础系统镜像

 ADD nginx-1.26.1.tar.gz /mnt——添加软件包在mnt下

 WORKDIR /mnt/nginx-1.26.1——切换工作目录

 RUN yum install -y gcc make pcre-devel openssl-devel——安装依赖

 RUN ./configure --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 nginx:v1 .

[root@docker-node1 docker]# docker images

REPOSITORY           TAG       IMAGE ID       CREATED          SIZE

nginx                v1        5085bb6de68f   22 seconds ago   356MB

3.5镜像优化方案

减少层或者多阶级建构或者使用最精简镜像

精简构建

[root@docker-node1 docker]# vim Dockerfile

FROM centos:repo

 ADD nginx-1.26.1.tar.gz /mnt

 WORKDIR /mnt/nginx-1.26.1

 RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && rm -fr /mnt/nginx-1.26

.1 && yum clean all

 EXPOSE 80 443

 VOLUME ["/usr/local/nginx/html"]

 CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]

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

多阶构建

[root@docker-node1 docker]# vim Dockerfile

 FROM centos:repo AS build

 ADD nginx-1.26.1.tar.gz /mnt

 WORKDIR /mnt/nginx-1.26.1

 RUN yum install -y gcc make pcre-devel openssl-devel && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && rm -fr /mnt/nginx-1.26.1 && yum clean all

 FROM centos:repo

 LABEl mail=jcl@strongjcl.org

 COPY --from=build /usr/local/nginx /usr/local/nginx

 EXPOSE 80 443

 VOLUME ["/usr/local/nginx/html"]

 CMD ["/usr/local/nginx/sbin/nginx", "-g", "daemon off;"]

构建会更快

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

[root@docker-node1 docker]# docker images

REPOSITORY           TAG       IMAGE ID       CREATED          SIZE

nginx                v3        b9671a0763e2   41 seconds ago   210MB

nginx                v2        96badad8af99   5 minutes ago    292MB

nginx                v1        5085bb6de68f   13 minutes ago   356MB

最小精简镜像安装

查看必须调度的模块

[root@docker-node1 ~]# docker run -d --name test nginx:v4

3f04bc27690cabc4ba7456ceabf2fe12fce2cc81dfeeafb69c6707069ed61a13

[root@docker-node1 ~]# docker ps

CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS          PORTS             NAMES

3f04bc27690c   nginx:v4   "/usr/local/nginx/sb…"   41 seconds ago   Up 41 seconds   80/tcp, 443/tcp   test

[root@docker-node1 ~]# docker exec -it test sh

sh-4.2# ldd /usr/local/nginx/sbin/nginx

        linux-vdso.so.1 =>  (0x00007ffdf73cd000)

        libdl.so.2 => /lib64/libdl.so.2 (0x00007fbb71b4f000)

        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fbb71933000)

        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007fbb716fc000)

        libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fbb7149a000)

        libssl.so.10 => /lib64/libssl.so.10 (0x00007fbb71228000)

        libcrypto.so.10 => /lib64/libcrypto.so.10 (0x00007fbb70dc5000)

        libz.so.1 => /lib64/libz.so.1 (0x00007fbb70baf000)

        libc.so.6 => /lib64/libc.so.6 (0x00007fbb707e1000)

        /lib64/ld-linux-x86-64.so.2 (0x00007fbb71d53000)

        libfreebl3.so => /lib64/libfreebl3.so (0x00007fbb705de000)

        libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007fbb70391000)

        libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007fbb700a8000)

        libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fbb6fea4000)

        libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007fbb6fc71000)

        libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007fbb6fa61000)

        libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fbb6f85d000)

        libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fbb6f643000)

        libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fbb6f41c000)

上传本地镜像

[root@docker-node1 ~]# docker load -i /mnt/debian11.tar.gz

[root@docker-node1 ~]# docker load -i /mnt/nginx-1.23.tar.gz

[root@docker-node1 docker]# vim Dockerfile

FROM nginx:latest as base

 RUN mkdir -p /opt/var/cache/nginx && \

 cp -a --parents /usr/lib/nginx /opt && \

 cp -a --parents /usr/share/nginx /opt && \

 cp -a --parents /var/log/nginx /opt && \

 cp -aL --parents /var/run /opt && \

 cp -a --parents /etc/nginx /opt && \

 cp -a --parents /etc/passwd /opt && \

 cp -a --parents /etc/group /opt && \

 cp -a --parents /usr/sbin/nginx /opt && \

 cp -a --parents /usr/sbin/nginx-debug /opt && \

 cp -a --parents /lib/x86_64-linux-gnu/ld-* /opt && \

 cp -a --parents /usr/lib/x86_64-linux-gnu/libpcre* /opt && \

 cp -a --parents /lib/x86_64-linux-gnu/libz.so.* /opt && \

 cp -a --parents /lib/x86_64-linux-gnu/libc* /opt && \

 cp -a --parents /lib/x86_64-linux-gnu/libdl* /opt && \

 cp -a --parents /lib/x86_64-linux-gnu/libpthread* /opt && \

 cp -a --parents /lib/x86_64-linux-gnu/libcrypt* /opt && \

 cp -a --parents /usr/lib/x86_64-linux-gnu/libssl.so.* /opt && \

 cp -a --parents /usr/lib/x86_64-linux-gnu/libcrypto.so.* /opt && \

 cp /usr/share/zoneinfo/${TIME_ZONE:-ROC} /opt/etc/localtime

 FROM gcr.io/distroless/base-debian11

COPY --from=base /opt /

 EXPOSE 80 443

ENTRYPOINT ["nginx", "-g", "daemon off;"]

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

[root@docker-node1 docker]# docker images

REPOSITORY                        TAG       IMAGE ID       CREATED          SIZE

nginx                             v4        cb1503f9fa44   6 seconds ago    34.5MB

nginx                             v3        8a71114560af   37 minutes ago   210MB

nginx                             v2        96badad8af99   42 minutes ago   292MB

nginx                             v1        5085bb6de68f   50 minutes ago   356MB

centos                            repo      6c2c6db98597   55 minutes ago   204MB

nginx                             latest    5ef79149e0ec   12 days ago      188MB

nginx                             1.23      a7be6198544f   15 months ago    142MB

busybox                           latest    65ad0d468eb1   15 months ago    4.26MB

centos                            7         eeb6ee3f44bd   2 years ago      204MB

timinglee/game2048                latest    19299002fdbe   7 years ago      55.5MB

timinglee/mario                   latest    9a35a9e43e8c   8 years ago      198MB

gcr.io/distroless/base-debian11   latest    2a6de77407bf   N/A              20.6MB

运行容器

[root@docker-node1 ~]# docker run --rm -d --name test nginx:v4

[root@docker-node1 ~]# docker ps -a

CONTAINER ID   IMAGE      COMMAND                  CREATED              STATUS                          PORTS     NAMES

a1e8fc10301f   nginx:v4   "nginx -g 'daemon of…"   About a minute ago   Exited (0) About a minute ago             test

四、镜像仓库的管理

4.1 什么是docker仓库

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

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

        公共仓库,如 Docker Hub,任何人都可以访问和使用其中的镜像。许多常用的软件和应用都有在 Docker Hub 上提供的镜像,方便用户直接获取和使用。例如,您想要部署一个 Nginx 服务器,就可以从 Docker Hub 上拉取 Nginx 的镜像。

        私有仓库则是由组织或个人自己搭建和管理的,用于存储内部使用的、不希望公开的镜像。 比如,一家企业为其特定的业务应用创建了定制化的镜像,并将其存储在自己的私有仓库中, 以保证安全性和控制访问权限。

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

4.2 docker hub

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

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

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

1. 丰富的镜像资源:涵盖了各种常见的操作系统、编程语言运行时、数据库、Web 服务器等众多应用 的镜像。 例如,您可以轻松找到 Ubuntu、CentOS 等操作系统的镜像,以及 MySQL、Redis 等数据库 的镜像。

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

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

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

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

4.3搭建docker的私有仓库

4.3.1搭建registry仓库

拉取和上传都需要用户认证,index是主要的角色

导入镜像

这里加载的都是本地镜像,需要的话文章开头获取

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

ce7f800efff9: Loading layer  7.644MB/7.644MB

30609d4f10dd: Loading layer  792.6kB/792.6kB

3b6a51496c9d: Loading layer  17.55MB/17.55MB

e704e9e3e9dc: Loading layer  3.584kB/3.584kB

f019f591461d: Loading layer  2.048kB/2.048kB

Loaded image: registry:latest

开启registry

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

0bdff94ec6f1aff6d2f39a2ec1b70ba4b4d47ca14ac1c6dc24667364108bd68b

查看容器开启信息

[root@docker-node1 ~]# docker ps

CONTAINER ID   IMAGE      COMMAND                  CREATED          STATUS                      PORTS                                       NAMES

0bdff94ec6f1   registry   "/entrypoint.sh /etc…"   12 seconds ago   Up 11 second            s   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp   crazy_hugle

设置非加密上传

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

{

        "insecure-registries" : ["http://172.25.254.100:5000"]

}

重启

[root@docker-node1 ~]# systemctl restart docker

给需要上传的镜像设置一个索引

[root@docker-node1 ~]# docker tag nginx:v4 172.25.254.100:5000/nginx:v4

[root@docker-node1 ~]# docker push 172.25.254.100:5000/nginx:v4

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

c713dc774b96: Pushed

6835249f577a: Pushed

24aacbf97031: Pushed

8451c71f8c1e: Pushed

2388d21e8e2b: Pushed

c048279a7d9f: Pushed

1a73b54f556b: Pushed

2a92d6ac9e4f: Pushed

bbb6cacb8c82: Pushed

ac805962e479: Pushed

af5aa97ebe6c: Pushed

4d049f83d9cf: Pushed

9ed498e122b2: Pushed

577c8ee06f39: Pushed

5342a2647e87: Pushed

v4: digest: sha256:c19522dcc528d9ee8c55875e3adaef451b5bfccee1ec2ce8a0aa27551975a252 size: 3445

查看是否上传成功

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

{"repositories":["nginx"]}

4.3.2为registry提加密传输 

加密传输

清空json文件重启

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

[root@docker-node1 ~]# systemctl restart docker

创建一个存放证书的目录

[root@docker-node1 ~]# mkdir certs

先给本机添加一个域名解析

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

172.25.254.100  docker-node1.jcl.org reg.jcl.org

生成认证key和证书

[root@docker-node1 ~]# openssl req -newkey rsa:4096 \

-nodes -sha256 -keyout certs/jcl.org.key \

-addext "subjectAltName = DNS:reg.jcl.org" \ ——指定备用名称和添加的域名要相同

-x509 -days 365 -out certs/jcl.org.crt

Country Name (2 letter code) [XX]:CN

State or Province Name (full name) []:Shichuan

Locality Name (eg, city) [Default City]:chengdu

Organization Name (eg, company) [Default Company Ltd]:docker

Organizational Unit Name (eg, section) []:registry

Common Name (eg, your name or your server's hostname) []:reg.jcl.org

Email Address []:

[root@docker-node1 ~]# ls certs/

jcl.org.crt  jcl.org.key

启动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/jcl.org.crt \

> -e REGISTRY_HTTP_TLS_KEY=/certs/jcl.org.key registry:latest

d25d163025213709c33a08ca9d3fc8a4d13bba3ba84b1cb9076912eab8a91d73

[root@docker-node1 ~]# docker ps

CONTAINER ID   IMAGE             COMMAND                  CREATED              STATUS              PORTS                                             NAMES

d25d16302521   registry:latest   "/entrypoint.sh /etc…"   About a minute ago   Up About a minute   0.0.0.0:443->443/tcp, :::443->443/tcp, 5000/tcp   registry

测试:

[root@docker-node1 ~]# docker tag nginx:v4 reg.jcl.org/nginx:v4——添加别名

[root@docker-node1 ~]# docker push reg.jcl.org/nginx:v4——docker客户端没有证书拉取失败

The push refers to repository [reg.jcl.org/nginx]

Get "https://reg.jcl.org/v2/": tls: failed to verify certificate: x509: certificate signed by unknown authority

为客户端建立证书

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

[root@docker-node1 ~]# cp /root/certs/jcl.org.crt /etc/docker/certs.d/reg.jcl.org/ca.crt

[root@docker-node1 ~]# ls /etc/docker/certs.d/reg.jcl.org/ca.crt

/etc/docker/certs.d/reg.jcl.org/ca.crt

再次拉取就可以啦

[root@docker-node1 ~]# docker push reg.jcl.org/nginx:v4                               The push refers to repository [reg.jcl.org/nginx]

c713dc774b96: Pushed

6835249f577a: Pushed

24aacbf97031: Pushed

8451c71f8c1e: Pushed

2388d21e8e2b: Pushed

4.3.3建立登录认证

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

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

建立认证文件

[root@docker-node1 ~]# mkdir auth

[root@docker-node1 ~]# htpasswd -Bc auth/htpasswd jcl——-B强制使用最安全的加密方式,默认用md5加密

New password:

Re-type new password:

Adding password for user jcl

[root@docker-node1 ~]# cat auth/htpasswd

jcl:$2y$05$usYpfYOckRzgDM.nktxdcuZzTuYL4GwUIzvs8i.MFADNVi6fAiQ1a

[root@docker-node1 ~]# htpasswd -B auth/.htpasswd zly——增加第二用户

New password:

Re-type new password:

Adding password for user zly

[root@docker-node1 ~]# docker ps -a

CONTAINER ID   IMAGE             COMMAND                  CREATED          STATUS          PORTS                                             NAMES

d25d16302521   registry:latest   "/entrypoint.sh /etc…"   15 minutes ago   Up 15 minutes   0.0.0.0:443->443/tcp, :::443->443/tcp, 5000/tcp   registry

[root@docker-node1 ~]# docker rm -f registry——将之前的同名容器删掉

registry

添加认证到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/jcl.org.crt  \

-e REGISTRY_HTTP_TLS_KEY=/certs/jcl.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:latest

0273a8d12b8048376383907fde6f22bf9a9be5db35c0cbca256087748ae55a06

测试:

[root@docker-node1 ~]# docker tag nginx:v3 reg.jcl.org/nginx:v3

这时直接上传会报错因为需要用户登录

[root@docker-node1 ~]# docker push reg.jcl.org/nginx:v3

The push refers to repository [reg.jcl.org/nginx]

e9cbde3d3c79: Preparing

eb115aa3ecc5: Preparing

174f56854903: Preparing

no basic auth credentials

登录用户

[root@docker-node1 ~]# docker login reg.jcl.org

再次上传就可以啦

[root@docker-node1 ~]# docker push reg.jcl.org/nginx:v3

查看信息也是需要指定用户登录

[root@docker-node1 ~]# curl -k https://172.25.254.100/v2/_catalog

{"errors":[{"code":"UNAUTHORIZED","message":"authentication required","detail":[{"Type":"registry","Class":"","Name":"catalog","Action":"*"}]}]}

[root@docker-node1 ~]# curl -k https://172.25.254.100/v2/_catalog -ujcl:jcl

{"repositories":["nginx"]}

4.4构建企业级私有仓库HARBOR

4.4.1部署harbor

[root@docker-node1 ~]# cd harbor/

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

[root@docker-node1 harbor]# ls

common.sh             harbor.yml       install.sh  prepare

harbor.v2.5.4.tar.gz  harbor.yml.tmpl  LICENSE

[root@docker-node1 harbor]# vim harbor.yml

hostname: reg.jcl.org

certificate: /data/certs/jcl.org.crt

private_key: /data/certs/jcl.org.key

harbor_admin_password: 123

[root@docker-node1 harbor]# mkdir  /data

这里的证书文件在上节安装registry生成的

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

[root@docker-node1 certs]# ll

total 8

-rw-r--r-- 1 root root 2078 Aug 28 15:17 jcl.org.crt

-rw------- 1 root root 3272 Aug 28 15:17 jcl.org.key

安装harbor

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

安装完测试访问一下

4.4.2管理仓库

新建一个项目名叫strongjcl

然后就可以登录进去上传镜像了

[root@docker-node1 harbor]# docker tag nginx:v4 reg.jcl.org/strongjcl/nginx:v4

[root@docker-node1 harbor]# docker logout reg.jcl.org

Removing login credentials for reg.jcl.org

[root@docker-node1 harbor]# docker login reg.jcl.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@docker-node1 harbor]# docker push reg.jcl.org/strongjcl/nginx:v4

然后就可以看到我们上传的镜像

五、Docker网络

5.1 docker原生bridge网路

将我们本机设置成iptables

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

[root@docker-node1 ~]# reboot

关闭harbor

[root@docker-node1 harbor]# docker compose down

[root@docker-node1 harbor]# docker network ls

5.2 docker原生网络host 

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

/ # ifconfig

docker0   Link encap:Ethernet  HWaddr 02:42:CB:68:D1:71

          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0

          UP BROADCAST MULTICAST  MTU:1500  Metric:1

5.3 docker 原生网络none 

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

/ # 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)

5.4 docker的自定义网络 

5.4.1自定义桥接

如果是默认的桥接网络,没有域名解析功能

[root@docker-node1 ~]# docker run -it --name test --network bridge

/ # ping test1

ping: bad address 'test1'

如果是自定义桥接网络的话

[root@docker-node1 ~]# docker network create mybridge -d bridge

7a97b6af4b63771526fe2b718d33318d69e87d6474dd819e7043c93d71d3cca5

[root@docker-node1 ~]# docker network ls

7a97b6af4b63   mybridge   bridge    local

[root@docker-node1 ~]# docker run -it --name test1 --network mybridge busybox

/ #

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

/ # ifconfig

eth0      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

测试可以ping通test1

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

创建不同网站的ip

[root@docker-node1 ~]# docker network create mynet1 -d bridge

busybox

20da3f406020a3ed75334ecf9354ee46b5fd83a013c3d63908545c3d80b5259f

[root@docker-node1 ~]# docker network create mynet2 -d bridge

8da3c1e2b92b3d0985b7c039f17aeef47701e23b5e7b7136fe4b8a1462dca4e1

[root@docker-node1 ~]# docker network ls

[root@docker-node1 ~]# iptables -t nat -nL

[root@docker-node1 ~]# docker run -it --name test1 --network mynet2 busybox

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

给test1容器再加一个网卡,ip为test上连接的ip就可以互通

[root@docker-node1 ~]# docker network connect mynet1 test1

5.4.3 joined容器网络 

joined网络示例演示

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

[root@docker-node1 ~]# docker run -it --name test1 --network container:test busybox

[root@docker-node1 ~]# docker rm -f test test1

test

test1

利用容器部署phpmyadmin管理mysql 

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

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

[root@docker-node1 ~]# docker run -d --name mysqladmin --network mynet1 \

> -e PMA_ARBITRARY=1 \

> -p 80:80 phpmyadmin:latest

bdd9f7da56ef9df2552a0e1aaaaddae037138ec7d8aa0ddfa0c5306f702084b5

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

11aad252fc67ba791dd1ad206d73c47bbebd7d2d4daafdac0f6a3ce458eceb7c

通过浏览器访问

添加数据

[root@docker-node1 ~]# docker exec -it mysql mysql -uroot -p123

5.5. 容器内外网的访问

5.5.1 容器访问外网

[root@docker ~]# iptables -t nat -nL

Chain PREROUTING (policy ACCEPT)

target     prot opt source              destination

Chain INPUT (policy ACCEPT)

target     prot opt source              destination

Chain OUTPUT (policy ACCEPT)

target     prot opt source              destination

Chain POSTROUTING (policy ACCEPT)

target     prot opt source              destination

MASQUERADE  6     --  172.17.0.2  172.17.0.2 tcp dpt:80

内网访问外网策略       

Chain DOCKER (0 references)        destination

target         prot opt source              

DNAT             6     --  0.0.0.0/0             0.0.0.0/0           tcp dpt:80

to:172.17.0.2:80

5.5.2 外网访问docker容器

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

[root@docker ~]# docker run -d --name webserver -p 80:80 nginx

[root@docker ~]# iptables -t nat -nL

Chain PREROUTING (policy ACCEPT)

target     prot opt source              destination

Chain INPUT (policy ACCEPT)

target     prot opt source              destination

Chain OUTPUT (policy ACCEPT)

target     prot opt source              destination

Chain POSTROUTING (policy ACCEPT)

target     prot opt source              destination

MASQUERADE  6     --  172.17.0.2  172.17.0.2 tcp dpt:80       

Chain DOCKER (0 references)        destination

target         prot opt source              

DNAT             6     --  0.0.0.0/0             0.0.0.0/0           tcp dpt:80

to:172.17.0.2:80

外网访问内网策略

5.6 docker跨主机网络

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

在两台docker主机上各添加一块网卡,打开网卡混杂模式:

eth1为仅主机模式

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

[root@docker-node1 ~]# ifconfig eth1

eth1: flags=4419<UP,BROADCAST,RUNNING,PROMISC,MULTICAST>#####后面内容忽略

添加macvlan网络

[root@docker-node1 ~]# docker network create -d macvlan \

> --subnet 4.4.4.0/24 \

> --gateway 4.4.4.4 \

> -o parent=eth1 mynet1

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

[root@docker-node2 ~]# docker run -it --rm --name test --network mynet1 --ip 4.4.4.2 busybox

在node2上ping node1

如果关掉node1上的容器就ping不通了

六、Docker 数据卷管理及优化

6.1 为什么要用数据卷

docker数据卷

        mount到主机中,绕开分层文件系统

        和主机磁盘性能相同,容器删除后依然保留

        仅限本地磁盘,不能随容器迁移

docker提供了两种卷:

        bind mount docker

        managed volume

6.2 bind mount 数据卷

bind mount

[root@docker-node1 ~]# mkdir /jcl

[root@docker-node1 /]# touch /jcl/jcl-file{1..5}

[root@docker-node1 /]# ls /jcl

jcl-file1  jcl-file2  jcl-file3  jcl-file4  jcl-file5

[root@docker-node1 /]# docker ps -a

CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

[root@docker-node1 /]# docker run -it --rm --name test -v /jcl:/data1:rw -v /etc/passwd:/data2/passwd busybox

/ # ls

bin    data2  etc    lib    proc   sys    usr

data1  dev    home   lib64  root   tmp    var

/ # ls data1

jcl-file1  jcl-file2  jcl-file3  jcl-file4  jcl-file5

/ # ls data2

passwd

/ # touch data1/jcl-file6

/ # [root@docker-node1 ls /jcl/

jcl-file1  jcl-file2  jcl-file3  jcl-file4  jcl-file5  jcl-file6

6.3 docker managed 数据卷

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

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

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

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

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

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

[root@docker volumes]# touch ad74662b8d6bb6fdcc6e82925ae9942b94bac5f9da4bd52b0a14ac451ae9ef75/_data/leefile

[root@docker volumes]# docker exec -it mysql bash

bash-4.2# cd /var/lib/mysql

bash-4.2# ls

清理未使用的数据卷,不可逆操作

[root@docker ~]# docker volume prune

建立数据卷

[root@docker ~]# docker volume create jcl1

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

查看卷

[root@docker ~]# docker volume ls

DRIVER   VOLUME NAME

local     jcl1

使用建立的数据卷

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

[root@docker _data]# cd /var/lib/docker/volumes/jcl1/_data

[root@docker _data]# echo jcl1 > index.html

[root@docker _data]# curl 172.25.254.100

jcl1

6.4 数据卷容器(Data Volume Container)

数据卷容器(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

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

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

不同点:

bind mountdocker managed volume
volume位置可任意指定/var/lib/docker/volumes/..
对已有的挂载点的影响隐藏并替换volume原有数据复制到volume
是否支持单个文件支持不支持只能是目录
权限控制可设置为只读,默认为读写权限无控制,均为读写权限
移植性移植性弱,与host path绑定移植性强。无需指定host目录

6.6 备份与迁移数据卷

备份数据卷

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

[root@docker ~]# docker run --volumes-from datavol \

-v `pwd`:/backup busybox \         #把当前目录挂在到容器中用于和容器交互保存要备份的容器

tar zcf /backup/data1.tar.gz /data1        #备份数据到本地

数据恢复

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

七、Docker 的安全优化

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

[root@docker-node1 /]# 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

540b22197db5814703eaa7630a1e03ce20d385cb8e23495f1c1fc565ef143379

[root@docker-node1 ~]# docker inspect web | grep Pid

            "Pid": 4049,

            "PidMode": "",

            "PidsLimit": null,

[root@docker-node1 ~]# cd /proc/4049/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/540b22197db5814703eaa7630a1e03ce20d385cb8e23495f1c1fc565ef143379

/sys/fs/cgroup/memory/docker/540b22197db5814703eaa7630a1e03ce20d385cb8e23495f1c1fc565ef143379

2、控制组资源控制的安全

控制组资源控制的安全

[root@docker-node1 ns]# docker run -it --name test busybox

/ # free -m

              total        used        free      shared  buff/cache   available

Mem:           1744         655         383          16         706         924

Swap:          2048           0        2048

[root@docker-node1 ~]# free -m

               total        used        free      shared  buff/cache   available

Mem:            1743         759         442          15         705         983

Swap:           2047           0        2047

3、内核能力机制

        能力机制(Capability)是Linux内核一个强大的特性,可以提供细粒度的权限访问控制。

        大部分情况下,容器并不需要“真正的”root权限,容器只需要少数的能力即可。

        默认情况下,Docker采用“白名单”机制,禁用“必需功能”之外的其他权限。

4、Docker服务端防护

        使用Docker容器的核心是Docker服务端,确保只有可信的用户才能访问到Docker服务。 2719

        将容器的root用户映射到本地主机上的非root用户,减轻容器和主机之间因权限提升而引起的安全 问题。

        允许Docker 服务端在非root权限下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。 这些子进程只允许在特定范围内进行操作。

7.1 Docker的资源限制

Linux Cgroups 的全称是 Linux Control Group。

        是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。

        对进程进行优先级设置、审计,以及将进程挂起和恢复等操作。

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

        它以文件和目录的方式组织在操作系统的 /sys/fs/cgroup 路径下。

        执行此命令查看:mount -t cgroup

[root@docker-node1 ~]# mount -t cgroup

cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,release_agent=/usr/lib/systemd/systemd-cgroups-agent,name=systemd)

cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)

cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)

cgroup on /sys/fs/cgroup/misc type cgroup (rw,nosuid,nodev,noexec,relatime,misc)

cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)

cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)

cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)

cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)

cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)

cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)

cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)

cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)

cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)

7.1.1.限制cpu使用

1.限制cpu的使用量

[root@docker-node1 ~]# docker run -it --rm --name test \

> --cpu-period 100000 \

> --cpu-quota 20000 ubuntu

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

[1] 9

root@cdc70ba47b4b:/# top

top - 08:16:12 up  1:12,  0 user,  load average: 0.01, 0.11, 0.08

Tasks:   3 total,   2 running,   1 sleeping,   0 stopped,   0 zombie

%Cpu(s):  7.0 us, 14.3 sy,  0.0 ni, 78.4 id,  0.0 wa,  0.3 hi,  0.0 si,  0.0 st

MiB Mem :   1743.7 total,    253.4 free,    846.6 used,    811.7 buff/cache

MiB Swap:   2048.0 total,   2048.0 free,      0.0 used.    897.1 avail Mem

查看

[root@docker-node1 docker]# cat /sys/fs/cgroup/cpu,cpuacct/docker/cdc70ba47b4b42deb190c3cba9ecd274e527c9b4692c43c76d3adec70a2c2e76/cpu.cfs_quota_us

20000

2.限制cpu的优先级

因为只有cpu都在被使用的状态下才会有cpu抢占的情况,所以我们要关掉其他内核或者只用一个内核

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

开启一个容器设置cpu优先级为100

[root@docker-node1 ~]# docker run -it --rm --cpu-shares 100 ubuntu

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

[1] 9

root@9a3d814aa39e:/# top

再开启一个容器不设置优先级默认为1024

[root@docker-node1 docker]# docker run -it --rm ubuntu

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

[1] 9

root@b02ef3a4cd83:/# top

可以看到第一个设置优先级的容器占用cpu的情况

7.1.2 限制内存使用

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

d7b9008fa3052db7c85d5fddd8bafc05d0940b7dd647f06d31532d5901f3604d

[root@docker-node1 docker]# cd /sys/fs/cgroup/memory/docker/d7b9008fa3052db7c85d5fddd8bafc05d0940b7dd647f06d31532d5901f3604d

[root@docker-node1 d7b9008fa3052db7c85d5fddd8bafc05d0940b7dd647f06d31532d5901f3604d]# cat memory.limit_in_bytes

209715200

[root@docker-node1 d7b9008fa3052db7c85d5fddd8bafc05d0940b7dd647f06d31532d5901f3604d]# cat memory.memsw.limit_in_bytes

209715200

[root@docker-node1 ~]# umount /rhel9

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

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

测试:

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

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

自建控制器

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

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

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

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

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

[root@docker-node1 ~]# 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.0882283 s, 1.2 GB/s

[root@docker-node1 ~]# free -m

               total        used        free      shared  buff/cache   available

Mem:            1743         942         175         114         899         801

Swap:           2047           1        2046

[root@docker-node1 ~]# 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.232134 s, 1.4 GB/s

[root@docker-node1 ~]# free -m

               total        used        free      shared  buff/cache   available

Mem:            1743        1042          75         204         989         701

Swap:           2047         112        1935

[root@docker-node1 ~]# rm -fr /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

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

[root@docker-node1 ~]# 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.0426276 s, 4.4 GB/s

[root@docker-node1 ~]# 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.0434641 s, 4.6 GB/s

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

Killed

7.1.3 限制docker的磁盘io

查看系统指定的磁盘目录

[root@docker-node1 ~]# fdisk -l

[root@docker-node1 ~]# docker run -it --rm \

> --device-write-bps \

> /dev/nvme0n1:30M \

> ubuntu

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

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

8779305+0 records in

8779304+0 records out

4495003648 bytes (4.5 GB, 4.2 GiB) copied, 9.86951 s, 455 MB/s

root@c393116572d9:/# 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.0368539 s, 2.8 GB/s

root@c393116572d9:/# 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, 2.53646 s, 41.3 MB/s

7.2 Docker的安全加固

7.2.1 解决Docker的默认隔离性

[root@docker-node1 ~]# cd /mnt

[root@docker-node1 mnt]# ls

centos-7.tar.gz  lxcfs-5.0.4-1.el9.x86_64.rpm           nginx-1.23.tar.gz

debian11.tar.gz  lxc-libs-4.0.12-1.el9.x86_64.rpm

hgfs             lxc-templates-4.0.12-1.el9.x86_64.rpm

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

运行lxcfs并解决容器隔离性

[root@docker-node1 mnt]# lxcfs /var/lib/lxcfs &

[root@docker-node1 mnt]#  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@037417559d41:/# free -m

7.2.2 容器特权

可以看到没有添加特权的时候是不能添加ip的

添加特权后就可以为eth0添加ip

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

但同时也可以为磁盘分区,会更改我们真实宿主机的设置

7.2.3 容器特权的白名单

所以为了避免这个情况我们可以单独为某个操作增加特权

[root@docker-node1 ~]# docker run --rm -it --name test --cap-add NET_ADMIN busybox

八 、容器编排工具Docker Compose

8.1 Docker Compose 概述

Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。 其是官方的一个开源项目,托管到github上

主要功能

1. 定义服务: 使用 YAML 格式的配置文件来定义一组相关的容器服务。每个服务可以指定镜像、端口映射、 环境变量、存储卷等参数。 例如,可以在配置文件中定义一个 Web 服务和一个数据库服务,以及它们之间的连接关系。

2. 一键启动和停止: 通过一个简单的命令,可以启动或停止整个应用程序所包含的所有容器。这大大简化了多容器 应用的部署和管理过程。 例如,使用 docker-compose up 命令可以启动配置文件中定义的所有服务,使用 compose down 命令可以停止并删除这些服务。

3. 服务编排: docker 可以定义容器之间的依赖关系,确保服务按照正确的顺序启动和停止。例如,可以指定数据库 服务必须在 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 的常用命令参数

1、服务管理

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

set ts=2 sw=2 ai et

[root@docker-node1 ~]# mkdir test

[root@docker-node1 ~]# cd test

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

services:

  web:

    image: nginx:latest

    ports:

    - "80:80"

  testnode:

    image: busybox:latest

    command: ["/bin/sh","-c","sleep 100000"]

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

[root@docker-node1 test]# docker compose ps

stop和down的区别就是前者不会删除容器,后者要删除

[root@docker-node1 test]# docker compose stop

[root@docker-node1 test]# docker compose start

[root@docker-node1 test]# docker compose down

[root@docker-node1 test]# docker compose ps

如果不是默认的命名方式则需要-f指定识别的文件名

且执行命令只能在yml脚本所在目录下执行

[root@docker-node1 test]# mv docker-compose.yml jcl.yml

[root@docker-node1 test]# ls

jcl.yml

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

no configuration file provided: not found

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

2、服务状态查看

[root@docker-node1 test]# docker compose -f jcl.yml ps

[root@docker-node1 test]# docker compose -f jcl.yml logs web

3、构建和重新构建服务

[root@docker-node1 test]# cd /root/docker

[root@docker-node1 docker]# vim Dockerfile

[root@docker-node1 docker]# cp Dockerfile Dockerfile.bak

[root@docker-node1 docker]# rm -f Dockerfile

[root@docker-node1 docker]# vim Dockerfile

FROM busybox:latest

RUN touch /jcl-file1

[root@docker-node1 docker]# vim jcl

FROM busybox:latest

RUN touch /jcl-file2

[root@docker-node1 docker]# cd /root/test

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

services:

  test1:

    image: test1 #构建镜像的名字

    build:

      context: /root/docker #构建文件所在目录

      dockerfile: Dockerfile

    command: ["/bin/sh","-c","sleep 100000"]

    container_name: jcl1 #指定容器名字

  test2:

    image: test2

    build:

      context: /root/docker

      dockerfile: jcl

    command: ["/bin/sh","-c","sleep 100000"]

    container_name: jcl2

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

[root@docker-node1 test]# docker compose ps

也可以将构建镜像和启动容器分离开运行

[root@docker-node1 test]# docker compose down

[+] Running 3/3

 ✔ Container jcl1        Removed                                              10.2s

 ✔ Container jcl2        Removed                                              10.1s

 ✔ Network test_default  Removed                                               0.1s

[root@docker-node1 test]# docker images

REPOSITORY                        TAG       IMAGE ID       CREATED              SIZE

test1                             latest    41d7dea7a0b0   About a minute ago   4.26MB

test2                             latest    c65476399bd3   About a minute ago   4.26MB

[root@docker-node1 test]# docker rmi test1 test2

Untagged: test1:latest

Deleted: sha256:41d7dea7a0b02ed545634715aafeaa1373dc37cca894b231c28fce3d237f1a93

Untagged: test2:latest

先构建镜像

[root@docker-node1 test]# docker compose build

[root@docker-node1 test]# docker compose build test1

也可以单独只构建一个

[root@docker-node1 test]# docker compose build test2

再启动容器

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

[+] Running 3/3

 ✔ Network test_default  Created                                               0.1s

 ✔ Container jcl1        Started                                               0.6s

 ✔ Container jcl2        Started         

4、其他操作

在容器运行时执行命令

[root@docker-node1 test]# docker compose exec -it test1 /bin/sh

从仓库中拉取镜像

[root@docker-node1 test]# docker compose pull

验证yml文件是否有错,没有会进行内容的打印

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

添加-q表示没有问题就不打印

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

8.3 Docker Compose 的yml文件

8.3.1设置端口

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

services:

  test1:

    image: nginx

    container_name: web

    expose:

     - 1234

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

[+] Running 2/2

 ✔ Network test_default  Created                                               0.1s

 ✔ Container web         Started                                               0.3s

[root@docker-node1 test]# docker ps

CONTAINER ID   IMAGE       COMMAND                  CREATED         STATUS         PORTS                 NAMES

8f826496c749   nginx       "/docker-entrypoint.…"   9 seconds ago   Up 9 seconds   80/tcp, 1234/tcp      web

8.3.2设置映射端口

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

services:

  test1:

    image: nginx

    container_name: web

    ports:

     - "80:80"

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

[+] Running 1/1

 ✔ Container web  Started                                                      0.4s

[root@docker-node1 test]# docker ps

CONTAINER ID   IMAGE       COMMAND                  CREATED          STATUS          PORTS                               NAMES

40d0ce48632f   nginx       "/docker-entrypoint.…"   18 seconds ago   Up 17 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp   web

8.3.3给某些需要环境变量的镜像设置环境变量

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

services:

  test1:

    image: mysql:5.7

    environment:

      MYSQL_ROOT_PASSWORD: jcl

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

[+] Running 2/2

 ✔ Container web           Recreated                                           0.1s

 ✔ Container test-test1-1  Started               

[root@docker-node1 test]# docker inspect test-test1-1

8.3.4 设置数据卷

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

services:

  test1:

    image: mysql:5.7

    environment:

      MYSQL_ROOT_PASSWORD: jcl

    volumes:

      - /opt/mysql_data:/var/lib/mysql

[root@docker-node1 test]# docker compose down

[+] Running 2/1

 ✔ Container test-test1-1  Removed                                             1.2s

 ✔ Network test_default    Removed                                             0.1s

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

[+] Running 2/2

 ✔ Network test_default    Created                                             0.1s

 ✔ Container test-test1-1  Started                                             0.3s

三种方式查看

[root@docker-node1 test]# df

[root@docker-node1 ~]# docker inspect test-test1-1

[root@docker-node1 ~]# cd /opt/mysql_data/

[root@docker-node1 mysql_data]# ls

8.3.5网络

如果不设定的话会自动设定默认网络

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

[+] Running 2/2

 ✔ Network test_default    Created                                             0.1s

 ✔ Container test-test1-1  Started                                             0.3s

[root@docker-node1 test]# docker network ls

NETWORK ID     NAME           DRIVER    SCOPE

82ce7d690915   bridge         bridge    local

9dd9ecaef455   host           host      local

85484fc21f25   none           null      local

0683d3b78932   test_default   bridge    local

设定原生网络

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

services:

  test1:

    image: busybox:latest

    container_name: jcl

    command: ["/bin/sh","-c","sleep 100000"]

    network_mode: bridge

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

[+] Running 1/1

 ✔ Container jcl  Started                                                      0.3s

[root@docker-node1 test]# docker network ls

NETWORK ID     NAME           DRIVER    SCOPE

82ce7d690915   bridge         bridge    local

创建网络设定

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

services:

  test1:

    image: busybox:latest

    container_name: jcl

    command: ["/bin/sh","-c","sleep 100000"]

    networks:

      - mynet1

      - mynet2

networks:

  mynet1:

    driver: bridge

  mynet2:

    driver: macvlan

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

[root@docker-node1 test]# docker exec -it jcl sh

8.3.6指定ip和网关

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

services:

  test1:

    image: busybox:latest

    container_name: jcl

    command: ["/bin/sh","-c","sleep 100000"]

    networks:

      - mynet1

      - mynet2

  test2:

    image: busybox:latest

    container_name: jcl1

    command: ["/bin/sh","-c","sleep 100000"]

    network_mode: default

networks:

  default:

    external: true

    name: bridge

  mynet1:

    driver: bridge

  mynet2:

    ipam:

      driver: default

      config:

        - subnet: 172.26.0.0/24

          gateway: 172.26.0.254

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

[+] Running 2/2

 ✔ Container jcl1  Started                                                     0.4s

 ✔ Container jcl   Running 

[root@docker-node1 test]# docker network ls

NETWORK ID     NAME           DRIVER    SCOPE

82ce7d690915   bridge         bridge    local

9dd9ecaef455   host           host      local

85484fc21f25   none           null      local

0683d3b78932   test_default   bridge    local

d2c2a93a7039   test_mynet1    bridge    local

a5f129c20888   test_mynet2    macvlan   local

[root@docker-node1 test]# docker exec -it jcl sh

8.3.7 设定数据卷

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

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

[+] Running 3/3

 ✔ Volume "jcl"    Created                                                     0.0s

 ✔ Container jcl1  Started                                                    10.4s

 ✔ Container jcl   Running     

[root@docker-node1 test]# docker exec -it jcl1 sh

将容器停掉也可以看到数据卷在本地上

[root@docker-node1 test]# docker compose down

 8.4 企业示例

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

haproxy详细讲解请移步

先安装一个haproxy在宿主机上,编辑配置文件

[root@docker-node1 _data]# dnf install haproxy -y --downloadonly --downloaddir=/mnt

[root@docker-node1 mnt]# rpm2cpio haproxy-2.4.17-3.el9.x86_64.rpm | cpio -id

将配置文件复制复制到doker目录下

[root@docker-node1 haproxy]# cp haproxy.cfg /var/lib/docker/volumes/conf/

加载镜像在doker仓库中

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

43b3c4e3001c: Loading layer  83.87MB/83.87MB

87b571ab9f2c: Loading layer  48.64kB/48.64kB

85ff335ffae2: Loading layer  18.99MB/18.99MB

432ae7833e27: Loading layer  3.584kB/3.584kB

95d92b3c450e: Loading layer  1.536kB/1.536kB

Loaded image: haproxy:2.3

查看haproxy镜像的配置文件目录

[root@docker-node1 ~]# docker inspect haproxy:2.3

[root@docker-node1 haproxy]# vim /root/test/haproxy.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 ——表示将宿主机上的nginx发布文件挂载到容器中的目录下

    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——挂载haproxy的配置文件

    networks:

      - internel

      - extrnal

networks:

  internel:

    driver: bridge

  extrnal:

    driver: bridge

volumes:

  data_web1:

    name: data_web1

  data_web2:

    name: data_web2

开启服务

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

查看容器是否运行起来

[root@docker-node1 test]# docker compose ps

NAME         IMAGE          COMMAND                  SERVICE   CREATED          STATUS          PORTS

haproxy      haproxy:2.3    "docker-entrypoint.s…"   haproxy   11 seconds ago   Up 10 seconds   0.0.0.0:80->80/tcp, :::80->80/tcp

webserver1   nginx:latest   "/docker-entrypoint.…"   web1      11 seconds ago   Up 10 seconds   80/tcp

webserver2   nginx:latest   "/docker-entrypoint.…"   web2      11 seconds ago   Up 10 seconds   80/tcp

添加内容在nginx默认的发布文件中

[root@docker-node1 test]# echo webserver1 > /var/lib/docker/volumes/data_web1/_data/index.html

[root@docker-node1 test]# echo webserver2 > /var/lib/docker/volumes/data_web2/_data/index.html

测试访问172.25.254.100

  • 21
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值