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 的一些关键特点和优势:
- 丰富的镜像资源:涵盖了各种常见的操作系统、编程语言运行时、数据库、Web 服务器等众多应用的镜像。
例如,您可以轻松找到 Ubuntu、CentOS 等操作系统的镜像,以及 MySQL、Redis 等数据库的镜像。
官方支持:提供了由 Docker 官方维护的一些重要镜像,确保其质量和安全性。
社区贡献:开发者们可以自由上传和分享他们创建的镜像,促进了知识和资源的共享。
版本管理:对每个镜像通常都有多个版本可供选择,方便用户根据需求获取特定版本。
便于搜索:用户可以通过关键词轻松搜索到所需的镜像。
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






































































































































































































