docker-ce容器技术重习

docker在企业中的应用场景

  • 在企业中docker作为业务的最小载体而被广泛应用

  • 通过docker企业可以更效率的部署应用并更节省资源

IaaS(Infrastructure as a Service),即基础设施即服务

PaaS是(Platform as a Service)即指平台即服务

SaaS(Software as a Service)软件运营服务

docker与虚拟化的对比

配置软件仓库并安装docker-ce

利用阿里云部署软件仓库

docker-node1 ~]# cat > /etc/yum.repos.d/docker.repo << EOF

[docker]

name = docker

baseurl = https://mirrors.aliyun.com/docker-ce/linux/rhel/9.6/x86_64/stable/

gpgcheck = 0

EOF

# dnf makecache

# dnf search docker

# dnf install docker-ce -y

# vim /lib/systemd/system/docker.service

# echo br_netfilter > /etc/modules-load.d/docker_mod.conf

# modprobe -a br_netfilter

# cat > /etc/sysctl.d/docker.conf <<EOF

net.bridge.bridge-nf-call-iptables = 1

net.bridge.bridge-nf-call-ip6tables = 1

net.ipv4.ip_forward = 1

EOF

# sysctl --system

# systemctl enable --now docker

配置docker加速器

# cat > /etc/docker/daemon.json <<EOF

{

"registry-mirrors": ["https://docker.1ms.run"]

}

EOF

# systemctl restart docker

# docker info

docker常用命令

# docker images 镜像查看

# docker search nginx 搜索镜像

# docker pull busybox 下载镜像

# docker history busybox:latest 查看镜像提交历史

# docker images

# docker save -o game2048-latest.tar timinglee/game2048:latest 导出镜像

# docker rmi timinglee/mario:latest 删除镜像

# docker load -i game2048-latest.tar 导入镜像

# docker run -d --name web nginx:1.26 运行镜像

# docker ps 查看运行容器

# docker ps -a 查看所有容器

# docker run -it --name busybox busybox:latest 交互模式运行容器

交互运行容器默认退出后会停止

# docker ps -a

# docker start busybox 运行停止的容器

# docker ps -a

退出交互容器不对其停止

# docker inspect busybox 查看容器信息

容器控制

# docker stop busybox #停止容器

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

# docker start busybox #开启停止的容器

在已经运行的容器中执行指定命令

# docker exec busybox touch /root/haha #非交互

# docker exec busybox ls /root

# docker exec -it web /bin/bash #交互的

容器删除

内容提交

# docker run -it --name test busybox:latest

# docker commit -m "add file" test busybox-file:latest

文件在镜像中的复制

# docker cp test:/root/file /mnt

容器镜像构建

常用到的参数

COPY 复制文件 eg:COPY file /file 或者 COPY ["file","/"]

MAINTAINER 指定作者信息,比如邮箱 eg:MAINTAINER user@example.com<br />在最新版的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功能和用法类似,但动作不可被覆盖

# mkdir docker

# cd docker/

# echo timinglee > timinglee

# vim Dockerfile 编写构建规则文件

FROM busybox:latest

COPY timinglee /root

# docker build -t timinglee:v1 .

# echo lee > lee

# vim Dockerfile

FROM busybox:latest

LABEL Creater=lee

COPY timinglee /root

ADD lee /root

可以解压缩COPY不能

FROM busybox:latest

LABEL Creater=lee

COPY bin.tar.gz /root

ADD bin.tar.gz /mnt

# vim Dockerfile

FROM busybox

MAINTAINER lee@timinglee.org

ENV NAME lee

CMD echo $NAME

# docker build -t example:v3 .

# docker run -it --rm --name test example:v3

# vim Dockerfile

ENV NAME lee

CMD ["/bin/echo", "$NAME"]

CMD ["/bin/echo", "$NAME"]

EXPOSE 8080 #暴露端口

# docker history lee:v3

# vim Dockerfile

FROM busybox:latest

LABEL Creater=lee

ENV NAME=timinglee

EXPOSE 8080

VOLUME "/mnt"

RUN ["/bin/sh","-c", "touch /root/$NAME" ]

# docker build -t lee:v4 .

# docker run -it --name test --rm lee:v4

# docker inspect test | grep -i mounts -A10

# cd /var/lib/docker/volumes/ e7* /_data/

_data]# touch lee{1..5}

# docker ps

# docker attach test 重新进入容器

# vim Dockerfile

FROM busybox:latest

LABEL Creater=lee

ENV NAME=timinglee

EXPOSE 8080

VOLUME "/mnt"

RUN ["/bin/sh","-c", "touch /root/$NAME" ]

WORKDIR "/mnt"

# docker run -it --name test --rm lee:v 5

FROM busybox

MAINTAINER lee@timinglee.org

ENV NAME lee

CMD ["/bin/sh", "-c", "/bin/echo $NAME"]

# docker run -it --rm --name test example:v3

# docker run -it --name test --rm lee:v 6 echo haha

# vim Dockerfile

FROM busybox

MAINTAINER lee@timinglee.org

ENV NAME lee

ENTRYPOINT echo $NAME

# docker run -it --name test --rm lee:v 6

# docker run -it --name test --rm lee:v 6 echo haha

centos构建

# docker load -i busybox-latest.tar.gz 【加载镜像到本地镜像库】

# docker load -i nginx-1.23.tar.gz

# docker run -d --name mario -p 80:8080 timinglee/mario 【创建启动一个新容器】

访问网址172.25.254.10:8080

# docker run -it --name centos7 centos:7

镜像优化示例

缩减镜像层

# vim Dockerfile

FROM centos:7 as build

ADD nginx-1.23.tar.gz /mnt

WORKDIR /mnt/nginx-1.23

RUN yum install -y gcc make pcre-devel openssl-devel && sed -i 's/CFLAGS="CFLAGS -g"/#CFLAGS="CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.23 && yum clean all

EXPOSE 80

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

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

# docker build -t webserver:v 1 .

# docker images webserver

多阶段构建

# vim Dockerfile

FROM centos:7 as lee

ADD nginx-1.23.tar.gz /mnt

WORKDIR /mnt/nginx-1.23.3

RUN yum install -y gcc make pcre-devel openssl-devel && sed -i 's/CFLAGS="CFLAGS -g"/#CFLAGS="CFLAGS -g"/g' auto/cc/gcc && ./configure --with-http_ssl_module --with-http_stub_status_module && make && make install && cd .. && rm -fr nginx-1.23 && yum clean all

FROM centos:7

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

EXPOSE 80

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

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

# docker build -t webserver:v 2 .

# docker images webserver

利用最精简镜像构建

# docker load -i /mnt/packages/debian11.tar.gz

# vim Dockerfile

FROM nginx:1.23 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 &&

FROM gcr.io/distroless/base-debian11

COPY --from=base /opt /

EXPOSE 80 443

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

# docker build -t nginx:lee 【构建很快】

# docker images nginx 查看结果:

容器镜像仓库

docker-node1 ~]# scp /etc/modules-load.d/docker_mod.conf root@172.25.254.20://etc/modules-load.d/docker_mod.conf

# scp /etc/sysctl.d/docker.conf root@172.25.254.20:/etc/sysctl.d/docker.conf

# scp /etc/yum.repos.d/docker.repo root@172.25.254.20:/etc/yum.repos.d/docker.repo

docker-node2 ~]# modprobe -a br_netfilter

# dnf install docker-ce -y

什么是docker仓库

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

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

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

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

例如,您想要部署一个 Nginx 服务器,就可以从 Docker Hub 上拉取 Nginx 的镜像。

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

比如,一家企业为其特定的业务应用创建了定制化的镜像,并将其存储在自己的私有仓库中,以保证安全性和控制访问权限。

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

docker hub

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

它是 Docker 生态系统中最知名和广泛使用的镜像仓库之一,有大量官方和社区贡献的镜像。

以下是 Docker Hub 的一些关键特点和优势:

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

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

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

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

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

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

docker hub的使用方法 【不常用】

docker-node1 ~]# docker login 【使用公有的仓库】

# ls .docker/

config.json

# docker tag gcr.io/distroless/base-debian11:latest timinglee/base-debian11:latest

# docker push timinglee/base-debian11:latest 【推送】

docker仓库的工作原理

仓库中的三个角色

index docker索引服务,负责并维护有关用户帐户,镜像校验以及公共命名空间的信息。

registry docker仓库,是镜像和图表的仓库,它不具有本地数据库以及不提供用户认证,通过Index Auth service的Token的方式进行认证

Registry Client Docker充当registry客户端来维护推送和拉取,以及客户端的授权。

pull原理

镜像拉取分为以下几步:

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

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

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

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

5.index确认此token合法性

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

push原理

镜像上传的步骤:

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

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

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

4.Registry向index合适token的合法性

5.index证实token的合法性

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

搭建docker的私有仓库

为什么搭建私有仓库

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

需要internet连接,速度慢

所有人都可以访问

由于安全原因企业不允许将镜像放到外网

好消息是docker公司已经将registry开源,我们可以快速构建企业私有仓库

搭建简单的Registry仓库

下载Registry镜像

docker-node1 ~]# docker pull registry 【下载镜像】

# docker load -i /root/dockerregistry.tar 【建立镜像】

# docker images | grep registry 【查看镜像】

# docker images | grep registry 查看暴露的端口

# docker run -d -p 5000:5000 --restart=always --name registry registry:latest 开启Registry

# docker ps 【查看开启】

# docker inspect registry

# docker logs registry 【查看仓库有无问题】

# docker tag busybox:latest 172.25.254.10:5000/busybox:latest 【给仓库打标签】

# docker push 172.25.254.10:5000/busybox:latest 【查看推送】

# vim /etc/docker/daemon.json

"insecure-registries": ["172.25.254.10:5000"] ## 添加或修改内容

# systemctl restart docker

# docker info

上传镜像

docker-node1 ~]# docker push 172.25.254.10:5000/busybox:latest 【上传镜像,几乎无延迟】

# curl 172.25.254.10:5000/v2/_catalog 【查看镜像上传】

# docker pull 172.25.254.10:5000/ busybox:latest 【可以直接快速拉取镜像】

# scp /etc/docker/daemon.json root@172.25.254.20: /etc/docker/daemon.json

docker-node2 ~]# systemctl restart docker

# docker pull 172.25.254.10:5000/ busybox:latest

为Registry提供加密传输

生成认证key和证书

docker-node1 ~]# mkdir -p /etc/docker/certs 【创建目录】

# docker stop registry 【关闭仓库容器,发布后面配置】

# docker rm -f registry

docker-node1-2 ~]# > /etc/docker/daemon.json

# systemctl restart docker

# vim /etc/hosts

node1 ~]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout /etc/docker/certs/timinglee.org.key -addext "subjectAltName = DNS:reg.timinglee.org" -x509 -days 365 -out /etc/docker/certs/timinglee.org.crt

# openssl x509 -in /etc/docker/certs/timinglee.org.crt -noout -text 查看证书

# docker run -d -p 443:443 --restart=always --name registry -v /etc/docker/certs :/certs -v /opt/registry:/var/lib/registry -e REGISTRY_HTTP_ADDR=0.0.0.0:443 -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/timinglee.org.crt -e REGISTRY_HTTP_TLS_KEY=/certs/timinglee.org.key registry:latest

# docker tag timinglee:v1 reg.timinglee.org/timinglee:v1

# docker push reg.timinglee.org/timinglee:v1

# mkdir /etc/docker/certs.d/reg.timinglee.org/ -p

# cp /etc/docker/certs/timinglee.org.crt /etc/docker/certs.d/reg.timinglee.org/ca.crt

# systemctl restart docker

# docker push reg.timinglee.org/timinglee:v1

# curl -k https://reg.timinglee.org/v2/_catalog 查看结果:

配置另一台主机登录认证

node2 ]# dnf remove podman -y

# dnf install iptables-services -y

# vim /usr/lib/systemd/system/docker.service

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

node1 ~]# dnf install httpd-tools -y

# mkdir -p /etc/docker/auth

# htpasswd -Bc /etc/docker/auth /htpasswd timinglee 创建仓库更改密码,只有 -B是添加库

# openssl x509 -in /etc/docker/certs/timinglee.org.crt -noout -text 查看证书

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

# curl -k https://reg.timinglee.org/v2/_catalog -u timinglee:lee 查看结果:

# vim /etc/docker/daemon.json 【配置解析】

# docker login reg.timinglee.org 【登录仓库】

# ls /root/.docker/ 【查看登录目录】

node2 ]# docker pull reg.timinglee.org/busybox

# mkdir -p /etc/docker/certs.d/reg.timinglee.orgsudo 【创建证书目录】

# scp root@172.25.254.10: /root/data/certs/timinglee.org.crt /etc/docker/certs.d/reg.timinglee.org/ca.crt

# systemctl restart docker

# docker pull reg.timinglee.org/busybox 查看结果:

构建企业级私有仓库

Harbor 是由vmware公司开源的企业级 Docker Registry 项目。

它提供了以下主要功能和特点:

基于角色的访问控制(RBAC):可以为不同的用户和用户组分配不同的权限,增强了安全性和管理的灵活性。

镜像复制:支持不同 Harbor 实例间复制镜像,方便在多个数据中心或环境中分发镜像。

图形化用户界面(UI):提供了直观的 Web 界面,便于管理镜像仓库、项目、用户等。

审计日志:记录了对镜像仓库的各种操作,有助于追踪和审查活动。

垃圾回收:可以清理不再使用的镜像,节省存储空间。

部署harbor

node1 ]# cp /mnt/ packages/harbor-offline-installer-v2.5.4.tgz /root/

# cd harbor/

# cp harbor.yml.tmpl harbor.yml

# vim harbor.yml 【配置安装文件格式】

# docker rm -f registry 【删除使用的仓库容器】

# docker logout reg.timinglee.org 【退出登录】

# mkdir -p /data/harbor 【创建安装目录】

# ./install.sh --with-chartmuseum 【安装】

# docker compose stop 【停止】

# docker compose up -d 【开启】

管理仓库

建立仓库项目

node1-2 ]# vim /etc/hosts

# vim /etc/docker/daemon.json 【配置解析】

# systemctl restart docker

# docker login reg.timinglee.org

# docker tag busybox:latest reg.timinglee.org/timinglee/busybox:latest

# docker images | grep busybox 查看结果:

# docker push reg.timinglee.org/timinglee/busybox:latest

Docker 网络

docker的镜像是令人称道的地方,但网络功能还是相对薄弱的部分

docker安装后会自动创建3种网络:bridge(桥接网桥)、host(直连)、none

# docker network ls

docker原生bridge网路

docker安装时会创建一个名为docker0的Linux bridge,新建的容器会自动桥接到这个接口

# ip link show type bridge

bridge模式下容器没有一个公有ip,只有宿主机可以直接访问,外部主机是不可见的。

容器通过宿主机的NAT规则后可以访问外网

# docker run -d --name web nginx:1.23

# ifconfig

# iptables -t nat -Ln 查看结果:

# docker stop nginx

# docker run -d --name web -p 8080:80 nginx:1.23

# iptables -t nat -Ln 查看结果:

docker原生网络host

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

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

# docker run -it --name test --rm busybox:latest

/ # ifconfig

# docker run -it --name test --rm --network host busybox:latest

/ # ifconfig

/ # exit

# ifconfig 查看网络:

docker 原生网络none

# docker run -it --name test --rm --network none busybox:latest

/ # ifconfig

docker的自定义网络

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

bridge , overlay , macvlan

bridge驱动类似默认的bridge网络模式,但增加了一些新的功能,

overlay和macvlan是用于创建跨主机网络

建议用自定义的网络控制哪些容器可以相互通信,还可以自动DNS解析容器名称到IP地址。

自定义桥接网络

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

# docker network create mybridge

# docker network ls

桥接默认是单调递增

# ifconfig

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

# docker network create mybridge2 --subnet 192.168.0.0/24 --gateway 192.168.0.100

# docker network inspect mybridge 2

为什么要自定义桥接

多容器之间如何互访通过ip就可以,但是有什么问题

# docker run -d --name test1 nginx

# docker run -d --name test2 nginx

# docker inspect (test1 / test2)

# docker stop test1 test2

# docker start test2

# docker start test1 【会发现容器ip颠倒】

docker引擎在分配ip时时根据容器启动顺序分配到,谁先启动谁用,是动态变更的

多容器互访用ip很显然不是很靠谱,那么多容器访问一般使用容器的名字访问更加稳定

docker原生网络是不支持dns解析的,自定义网络中内嵌了dns

# docker run -d --network my_net1 --name web nginx 【运行创建web服务】

# docker run -it --network my_net1 --name test busybox 【运行box镜像】

/ # ping web

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

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

# nft list ruleset 【可以看到网络隔离策略】

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

确定网络纯净

# docker network create mynet1 【创建网桥】

# docker network create mynet 2

# docker run -d --name web1 --network mynet 2 nginx 【运行容器】

# docker run -it --name test --network mynet1 busybox

# docker network connect mynet 2 test 【连接网络】

# docker start test 【开启停止的容器】

# docker attach test 【重新加入容器】

joined容器网络

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

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

# docker run -d --name web1 -p 80:80 nginx 【创建wbe服务】

# docker run -it --rm --network container:web1 busybox

/ # ifconfig

# docker run -it --rm --network container:web1 centos:7

# curl localhost 【连接访问】

/]# ping web1 查看结果:

joined网络示例演示

node2 ~]# docker load -i phpmyadmin-latest.tar.gz

# docker load -i mysql-8.0.tar

# docker run -d --name phpmyadmin -e PMA_ARBITRARY=1 -p 80:80 phpmyadmin:latest

# docker run -d --name mysql -e MYSQL_ROOT_PASSWORD='lee' --network container:phpmyadmin mysql:8.0

开启的phpmyadmin容器中是没有数据库的

这里填写的localhost:3306是因为mysql容器和phpmyadmin容器公用一个网络站

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

macvlan网络方式

Linux kernel提供的一种网卡虚拟化技术。

无需Linux bridge,直接使用物理接口,性能极好

容器的接口直接与主机网卡连接,无需NAT或端口映射。

macvlan会独占主机网卡,但可以使用vlan子接口实现多macvlan网络

vlan可以将物理二层网络划分为4094个逻辑网络,彼此隔离,vlan id取值为1~4094

macvlan网络间的隔离和连通

macvlan网络在二层上是隔离的,所以不同macvlan网络的容器是不能通信的

可以在三层上通过网关将macvlan网络连通起来

docker本身不做任何限制,像传统vlan网络那样管理即可

实现macvlan

在两台docker主机上各添加一块网卡(两个都有个仅主机模式网卡),打开网卡混杂模式:

所有主机 ]# docker compose down

# ip a show eth1

# ip link set eth1 promisc on

# ip link set up eth1

# ifconfig eth1

添加macvlan网路

# docker network create -d macvlan --subnet 1.1.1.0/24 --gateway 1.1.1.1 -o parent=eth1 lee

# docker network ls

10 ]# docker run -it --name busybox --rm --network lee --ip 1.1.1. 1 00 --rm busybox

/ # ping 1.1.1.200 运行结果:

20 ]# docker run -it --name busybox --rm --network lee --ip 1.1.1.200 --rm busybox

/ # ping 1.1.1.100 运行结果:

容器内外网的访问

容器访问外网

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

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

# iptables -t nat -nL

# w -i

外网访问docker容器

20 ~]# docker run -d --name webserver -p 8080:80 nginx

# ps aux | grep docker 【查看代理】

10 ~]# curl -v 172.25.254.20:8080 【现在可以访问】

20 ~]# kill 9 7105 【删除代理】

10 ~]# curl -v 172.25.254.20:8080 【依然可以访问】

20 ~]# iptables -t nat -nL 【策略还在,代理没有依然可以访问】

# iptables -t nat -D DOCKER 2 【删除DOCKER 的策略2】

# iptables -t nat -nL 查看结果:

10 ~]# curl -v 172.25.254.20:8080

docker-proxy和dnat在容器建立端口映射后都会开启,那个传输速录高走那个

docker跨主机网络

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

跨主机网络解决方案

docker原生的overlay和macvlan

第三方的flannel、weave、calico

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

libnetwork docker容器网络库

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

CNM (Container Network Model)

NM分三类组件

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

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

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

Docker 数据卷管理及优化

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

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

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

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

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

为什么要用数据卷

docker分层文件系统

性能差

生命周期与容器相同

docker数据卷

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

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

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

docker提供了两种卷:

bind mount

docker managed volume

bind mount 数据卷

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

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

使用 -v 选项指定路径

-v选项指定的路径,如果不存在,挂载时会自动创建

# rm -fr /data/

# docker run -it --rm --name test -v /data:/data -v /data1:/data1:ro -v /etc/passwd:/passwd:ro busybox:latest

/ # touch /data/file1 /data/file2

# watch -n 1 ls /data

# rm -fr /data/*

docker managed 数据卷

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

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

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

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

# docker volume create timinglee

# docker volume ls

# cd /var/lib/docker/volumes

# touch timinglee/_data/file

# docker run -it --rm -v timinglee:/data:ro busybox:latest 以只读方式挂载容器

# docker volume rm timinglee

# docker volume ls

数据卷容器

# docker run -it --rm --name data -v /etc/hosts:/hosts:ro -v /data:/data busybox:latest

/ # cat /hosts

# docker run -it --rm --name lee --volumes-from data busybox:latest

/ # ls

数据卷中数据的备份和迁移

# docker run -d --name webserver -p 80:80 -v /data:/usr/share/nginx/html nginx:1.23

# docker exec -it webserver bash

# cd /usr/share/nginx/html/

# ls

# docker run -it --rm --volumes-from webserver -v $(pwd):/backup busybox:latest

数据恢复

# rm -fr /data/*

# docker exec -it webserver bash

# docker rm -f webserver

# docker run -d --name webserver -p 80:80 -v /data:/usr/share/nginx/html -v $(pwd):/backup nginx:1.23

# docker exec -it webserver bash

# tar zxf /backup/html.tar.gz -C /

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

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

不同点:

Docker 的安全优化

更改系统cgroup版本

# mount -t cgroup

# mount -t cgroup2

# grubby --update-kernel=/boot/vmlinuz-$(uname -r) --args="systemd.unified_cgroup_hierarchy=0 systemd.legacy_systemd_cgroup_controller" 修改内核引导参数

# reboot

Docker资源限制

cpu的用量

# docker load -i ubuntu-latest.tar.gz

# docker run -it --rm ubuntu:latest

# dd if=/dev/zero of=/dev/null & cpu使用

# top

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

# dd if=/dev/zero of=/dev/null &

# top 查看限制占用

cpu优先级

# cd /sys/devices/system/cpu/ 确保在系统中只有一个cpu核心在下

# echo 0 > cpu1/online

# cat /proc/cpuinfo | grep cores

# docker run -it --rm --name test ubuntu:latest

# dd if=/dev/zero of=/dev/null &

# top

# docker run -it --rm --name test1 ubuntu:latest

# dd if=/dev/zero of=/dev/null &

# top

# docker run -it --rm --cpu-shares 100 ubuntu:latest 资源限制,最开始占用100%

# dd if=/dev/zero of=/dev/null &

# docker run -it --rm ubuntu:latest

# dd if=/dev/zero of=/dev/null & 有别的占用,上一个占用cpu衰减

限制内存使用

# docker run -d --name test --memory 200M --memory-swap 200M nginx:1.23

# rpm -ivh libcgroup-0.41-19.el8.x86_64.rpm

# rpm -ivh libcgroup-tools-0.41-19.el8.x86_64.rpm

# cgexec -g memory:docker/4bea7 * dd if=/dev/zero of=/dev/shm/bigfile bs=1M count=64

# cgexec -g memory:docker/4bea7 * dd if=/dev/zero of=/dev/shm/bigfile bs=1M count= 200

磁盘io限制

# docker run -it --name test --device-write-bps /dev/sda3:30M --rm ubuntu:latest

容器特权

指定特权容器

# docker run -it --name test --rm busybox:latest 普通容器(无特殊权限)

/ # ip a

/ # ip a a 1.2.3.4/24 eth0@if41

# docker run -it --rm --privileged busybox:latest 特权容器(--privileged) ,有宿主机所有权限

/ # fdisk -l

指定白名单权限

# docker run -it --rm --cap-add CAP_NET_ADMIN busybox:latest 精细化权限控制(--cap-add)

/ # ifconfig

/ # ip a

容器编排工具Docker Compose

Docker Compose 概述

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

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

Docker Compose 的常用命令参数

# mkdir /root/timinglee/

# cd /root/timinglee/

# vim docker-compose.yml

docker-compose.yml - 最简单版本

services: # 定义服务

web: # web 服务(nginx)

image: nginx:1.23 # 使用 nginx 1.23 镜像

ports: # 端口映射

  • "80:80" # 宿主机80端口映射到容器80端口

volumes: # 数据卷挂载

  • lee:/data # 命名卷 lee 挂载到容器 /data 目录

dbserver: # 数据库服务(MySQL)

image: mysql:8.0 # 使用 MySQL 8.0 镜像

environment: # 环境变量

MYSQL_ROOT_PASSWORD: lee # 设置 root 密码为 lee

# docker compose up # 这个 会占用终端的

# docker compose down

# docker compose ps

# docker compose -f /root/timinglee/docker-compose.yml up -d

# docker compose stop

# docker compose start

# docker compose down

# docker compose restart

# docker compose logs web 查看特定服务日志

docker compose 中对于镜像的预处理

# vim webserver #编写dockerfile

FROM nginx:1.23

COPY index.html /usr/share/nginx/html

# echo timinglee > index.html

# docker compose build #提前构建

# docker images | grep web

Docker Compose 的yml文件

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

服务(services)

服务名称(service1_name/service2_name 等):

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

# vim ~/.vimrc

# vim docker-compose.yml

services:

web:

服务1的配置

mysql:

服务2的配置

镜像(image):

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

镜像的最新版本

# vim docker-compose.yml

services:

web:

images:nginx

mysql:

images:mysql:5.7

端口映射(ports):

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

# vim docker-compose.yml

services:

mysql:

images: mysql:5.7

environment:

MYSQL_ROOT_PASSWORD: lee

container_name: mysql

# docker compose -f docker-compose.yml up -d

# docker compose down

# vim docker-compose.yml

services:

mysql:

images: mysql:5.7

environment:

MYSQL_ROOT_PASSWORD: lee

container_name: mysql

expose:

  • "8080"

# docker compose -f docker-compose.yml up -d

# docker compose ps -a 查看结果:

环境变量(environment):

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

# vim docker-compose.yml

services:

web:

images:mysql:5.7

environment:

MYSQL_ROOT_PASSWORD: lee

存储卷(volumes):

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

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

# vim docker-compose.yml

services:

test:

image: busybox

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

restart: always

container_name: busybox1

volumes:

  • /etc/passwd:/tmp/passwd:ro

# docker compose down

# docker compose -f docker-compose.yml up -d

# docker exec -it busybox1 cat /tmp/passwd 【查看挂载内容】

网络(networks)

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

# vim docker-compose.yml

services:

busybox:

image: busybox:latest

container_name: busybox

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

networks:

  • mynet1

  • mynet2

networks:

mynet1:

driver: bridge

mynet2:

driver: bridge

# docker compose down

# docker compose -f docker-compose.yml up -d

# docker network ls

# docker compose exec busybox sh

/ # ifconfig 查看结果:

命令(command):

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

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

#或# command:

- /bin/sh

- -c

- sleep3000

网络服务(networks):

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

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

# vim docker-compose.yml

services:

busybox:

image: busybox:latest

container_name: busybox

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

network_mode: default

networks:

default:

external: true

name: bridge

# docker compose down

# docker compose -f docker-compose.yml up -d

# docker network ls 【显示没有建立】

# vim docker-compose.yml

# docker compose down

# docker compose -f docker-compose.yml up -d

# docker network ls 查看建立:

# docker compose exec busybox sh

/ # ifconfig 查看结果:

/ # route -n

存储卷(volumes)

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

# vim docker-compose.yml

services:

test:

image: busybox

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

restart: always

container_name: busybox1

volumes:

  • data:/mnt #挂在/mnt/

volumes:

data:

name: lee

# docker compose down

# docker compose -f docker-compose.yml up -d

# docker volume ls 查看结果:

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

软件下载:

# dnf install haproxy-2.4.22-3.el9_3.x86_64 --downloadonly --destdir /mnt/ -y

# rpm2cpio /mnt/haproxy-2.4.22-3.el9_3.x86_64.rpm | cpio -id

# dnf install /mnt/haproxy-2.4.22-3.el9_3.x86_64.rpm -y

# mv /etc/haproxy/haproxy.cfg /mnt/

负载调度:

# vim /mnt/haproxy .cfg

listen web

bind *:80

mode http

balance roundrobin

server web1 web1:80 check

server web2 web2:80 check

容器配置:

# vim docker-compose.yml

services:

web1:

image: nginx:latest #使用 nginx 镜像

container_name: web1 # 指定容器名为 web1

restart: always # 容器退出时自动重启

expose:

  • 80 # 暴露容器内的 80 端口(仅对 Docker 网络可见)

volumes:

  • web1_data:/usr/share/nginx/html # 挂载名为 web1_data 的卷到容器内的 nginx 网页目录

networks:

  • mynet1

web2:

image: nginx:latest

container_name: web2

restart: always

expose:

  • 80

volumes:

  • web2_data:/usr/share/nginx/html

networks:

  • mynet1

haproxy:

image: haproxy:2.3 # 使用 HAProxy 2.3 镜像

container_name: haproxy

expose:

  • "80"

networks:

  • mynet1 # 连接到同一网络

volumes:

  • /mnt/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg

ports:

  • "80:80" # 将宿主机的 80 端口映射到容器的 80 端口(允许外部访问)

networks:

mynet1:

driver: bridge # 使用 bridge 网络驱动(默认)

volumes:

web1_data:

name: web1_data # 显式命名卷为 web1_data

web2_data:

name: web2_data

# docker compose config 【检测语法】

# sudo lsof -i :80 【无输出,确认80端口无占用】

# docker compose -f docker-compose.yml up -d

# docker compose ps 查看运行:

# curl -v http://localhost 查看结果:

# echo "Web1" > /var/lib/docker/volumes/web1_data/_data/index.html

# echo "Web2" > /var/lib/docker/volumes/web2_data/_data/index.html

# for i in {1..4}; do curl -s http://localhost; don e

相关推荐
jiayong232 小时前
第 4 课:怎么把一个大页面拆成多个组件
运维·服务器·前端
咖啡忍者2 小时前
【SAP CO】4.COPC产品成本控制-5.生产订单
笔记
qq_8573058192 小时前
ubuntu 22 源码安装bochs
linux·运维·ubuntu
A-刘晨阳2 小时前
麒麟v10桌面版2403版本运行程序提示权限不足(KYSEC)
运维·云计算·操作系统·银河麒麟·麒麟桌面系统
_李小白2 小时前
【OSG学习笔记】Day 40: EventCallback(事件回调)
笔记·学习
恒创科技HK2 小时前
恒创科技:刚交付的香港云服务器应该做哪些测试
运维·服务器
愈努力俞幸运2 小时前
docker入门,容器,镜像
java·分布式·docker
刘某的Cloud2 小时前
svc中外部流量访问限制
linux·运维·docker·kubernetes·service
janthinasnail2 小时前
使用Docker安装Penpot(UI/UX设计与原型制作工具)
docker·penpot