20230709作业

1.实现并总结容器跨主机的通信过程:通过host-gw模式实行容器跨主机通信

修改docker的默认IP地址范围:
宿主机192.168.220.52
[root@db02 ~]# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=10.10.0.1/24
[root@db02 ~]# systemctl daemon-reload && systemctl restart docker

宿主机192.168.220.53

[root@db03 ~]# vim /lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --bip=10.20.0.1/24
[root@db03 ~]# systemctl daemon-reload && systemctl restart docker

在宿主机添加静态路由,将去往的目的容器网关(下一跳)指向目的容器所在的宿主机eth0网卡:

宿主机192.168.220.52

[root@db02 ~]# route add -net 10.20.0.0/24 gw 192.168.220.53
[root@db02 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
10.20.0.0       192.168.220.53  255.255.255.0   UG    0      0        0 eth0
[root@db02 ~]# iptables -A FORWARD -s 192.168.220.0/24 -j ACCEPT  #允许响应报文的转发
[root@db02 ~]# iptables -vnL
 Chain FORWARD (policy DROP 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination         
  0     0      ACCEPT     all  --  *      *       192.168.220.0/24     0.0.0.0/0 

宿主机192.168.220.53

[root@db03 ~]# route add -net 10.10.0.0/24 gw 192.168.220.52
[root@db03 ~]# iptables -A FORWARD -s 192.168.220.0/24 -j ACCEPT  #允许响应报文的转发

运行容器并测试容器间通信

宿主机192.168.220.52

[root@db02 ~]# docker run -d alpine sh
3857f488f20737faf5e0ef0416f0f8a7638e1e1f757daaaf82fb8100d728e955
[root@db02 ~]# docker exec -it 3857f488f20737f sh
/ # ip a
21: eth0@if22: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:0a:0a:00:02 brd ff:ff:ff:ff:ff:ff
    inet 10.10.0.2/24 brd 10.10.0.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ping 10.20.0.2
PING 10.20.0.2 (10.20.0.2): 56 data bytes
64 bytes from 10.20.0.2: seq=0 ttl=62 time=0.338 ms
64 bytes from 10.20.0.2: seq=1 ttl=62 time=0.224 ms
64 bytes from 10.20.0.2: seq=2 ttl=62 time=0.230 ms
64 bytes from 10.20.0.2: seq=3 ttl=62 time=0.235 ms
^C
--- 10.20.0.2 ping statistics ---

4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.224/0.256/0.338 ms

宿主机192.168.220.53

[root@db03 ~]# docker run -d  alpine sh
4462e4a836ec16e101766a4e33407ada834eda8dae6b883f7e63c69333cc7533
[root@db03 ~]# docker exec -it 4462e4a836e sh
/ # ip a
7: eth0@if8: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:0a:14:00:02 brd ff:ff:ff:ff:ff:ff
    inet 10.20.0.2/24 brd 10.20.0.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # ping 10.10.0.2
PING 10.10.0.2 (10.10.0.2): 56 data bytes
64 bytes from 10.10.0.2: seq=0 ttl=62 time=3.062 ms
64 bytes from 10.10.0.2: seq=1 ttl=62 time=0.230 ms
64 bytes from 10.10.0.2: seq=2 ttl=62 time=0.291 ms
64 bytes from 10.10.0.2: seq=3 ttl=62 time=0.267 ms
^C
--- 10.10.0.2 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.230/0.962/3.062 ms
host-gw模式原理在于宿主机充当路由

host-gw 模式的工作原理: 将每个 Flannel 子网(Flannel Subnet,比如:10.20.0.1/24)的“下一跳”,设置成了该子网对应的宿主机的 IP 地址。也就是说,这台“主机”(Host)会充当这条容器通信路径里的“网关”(Gateway)。这也正是“host-gw”的含义。

步骤1:宿主机Node1上新建一条路由规则
flanneld 会在宿主机上创建一条路由规则,以 Node 1 为例:

$ ip route
...
10.244.1.0/24 via 10.168.0.3 dev eth0
这条路由规则的含义是:目的 IP 地址属于 10.244.1.0/24 网段的 IP 包,应该经过本机的 eth0 设备发出去(即:dev eth0);并且,它下一跳地址(next-hop)是 10.168.0.3(即:via 10.168.0.3)。所谓下一跳地址就是:如果 IP 包从主机 A 发到主机 B,需要经过路由设备 X 的中转。那么 X 的 IP 地址就应该配置为主机 A 的下一跳地址。而从 host-gw 示意图中我们可以看到,这个下一跳地址对应的,正是我们的目的宿主机 Node 2。

步骤2:宿主机Node1将目的IP转为目的MAC
一旦配置了下一跳地址,那么接下来,**当 IP 包从网络层进入链路层封装成帧的时候,eth0 设备就会使用下一跳地址对应的 MAC 地址,作为该数据帧的目的 MAC 地址。显然,这个 MAC 地址,正是 Node 2 的 MAC 地址。**这样,这个数据帧就会从 Node 1 通过宿主机的二层网络顺利到达 Node 2 上。

步骤3:宿主机Node2从收到的请求中取出IP包
Node 2 的内核网络栈从二层数据帧里拿到 IP 包后,会“看到”这个 IP 包的目的 IP 地址是 10.244.1.3,即 Infra-container-2 的 IP 地址。这时候,根据 Node 2 上的路由表,该目的地址会匹配到第二条路由规则(也就是 10.244.1.0 对应的路由规则),从而进入 cni0 网桥,进而进入到 Infra-container-2 当中。

2.总结Dockerfile的常见指令

FROM centos:7.9.2009 #在整个dockfile文件中除了注释之外的第一行,要是FROM指令,FROM 指令用于指定当前镜像(base image)引用的父镜像(parent image)
LABEL “key” = “value” #设置镜像的属性标签
LABEL author="jack jack@gmail.com"
LABEL version="1.0"
ADD [--chown=<user>:<group>] <src>... <dest> #用于添加宿主机本地的文件、目录、压缩等资源到镜像里面去,会自动解压tar.gz格式的压缩包,但不会自动解压zip包
ADD --chown=root:root test /opt/test
COPY [--chown=<user>:<group>] <src>... <dest> #用于添加宿主机本地的文件、目录、压缩等资源到镜像里面去,不会解压任何压缩包
ENV MY_NAME="John Doe" #设置容器环境变量
USER <user>[:<group>] or USER <UID>[:<GID>] #指定运行操作的用户
RUN yum install vim unzip -y && cd /etc/nginx #执行shell命令,但是一定要以非交互式的方式执行
VOLUME ["/data/data1" , "/data/data2"] #定义volume
WORKDIR /data/data1 #用于定义当前工作目录
EXPOSE <port> [<port>/<protocol>...] #声明要把容器的某些端口映射到宿主机
CMD有以上三种方式定义容器启动时所默认执行的命令或脚本
CMD ["executable" , "param1" , "param2"] (exec form, this is the preferred form) #推荐的可执行程序方式
CMD ["param1" , "param2"] (as default parameters to ENTRYPOINT) #作为ENTRYPOINT默认参数
CMD command param1 param2 (shell form) #基于shell命令的
如:基于CMD #镜像启动为一个容器时候的默认命令或脚本,
CMD ["/bin/bash"]
ENTRYPOINT #也可以用于定义容器在启动时候默认执行的命令或者脚本,如果是和CMD命令混合使用的时候,会将CMD的命令当做参数传递给
ENTRYPOINT后面的脚本,可以在脚本中对参数做判断并相应的容器初始化操作。
案例1:
ENTRYPOINT ["top" , "-b"]
CMD ["-c"]
等于如下一行:
ENTRYPOINT ["top" , "-b" , "-c"]
案例2:
ENTRYPOINT ["docker-entrypoint.sh"] #定义一个入口点脚本,并传递mysqld 参数
CMD ["mysqld"]
等于如下一行:
ENTRYPOINT ["docker-entrypoint.sh" , "mysqld"]
使用总结:
ENTRYPOINT(脚本) + CMD(当做参数传递给ENTRYPOINT)
3.基于Dockerfile构建Nginx镜像并验证可以启动为容器
下载基础镜像
docker pull ubuntu:22.04
编写Dockerfile
上传网页文件frontend.tar.gz ,nginx源码包nginx-1.22.0.tar.gz ,nginx配置文件nginx.conf ,apt仓库文件sources.list
mkdir nginx-dockerfile
cd nginx-dockerfile
vim Dockerfile
FROM ubuntu:22.04
MAINTAINER "jack 2973707860@qq.com"
ADD sources.list /etc/apt/sources.list
RUN apt update && apt install -y iproute2 ntpdate tcpdump telnet traceroute nfs-kernel-server nfs-common lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute gcc openssh-server lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute iotop unzip zip make
ADD nginx-1.22.0.tar.gz /usr/local/src/
RUN cd /usr/local/src/nginx-1.22.0 && ./configure --prefix=/apps/nginx && make && make install && ln -sv /apps/nginx/sbin/nginx /usr/bin
RUN groupadd -g 2088 nginx && useradd -g nginx -s /usr/sbin/nologin -u 2088 nginx && chown -R nginx.nginx /apps/nginx
ADD nginx.conf /apps/nginx/conf/
ADD frontend.tar.gz /apps/nginx/html/
EXPOSE 80 443
#ENTRYPOINT ["nginx"]
CMD ["nginx","-g","daemon off;"]
构建镜像
docker build -t harbor.magedu.net/myserver/nginx:v1 .
[root@db02 nginx-dockerfile]# docker images
REPOSITORY                         TAG       IMAGE ID       CREATED          SIZE
harbor.magedu.net/myserver/nginx   v1        db67cd822e4f   12 seconds ago   447MB
运行容器并访问
docker run -d -p 80:80  db67cd822e4f

4.部署单机harbor并实现镜像的上传与下载

Harbor 部署的先决条件

Harbor 部署为多个 Docker 容器。因此,您可以将其部署在任何支持 Docker 的 Linux 发行版上。目标主机需要安装 Docker 和 Docker Compose。

硬件

下表列出了用于部署 Harbor 的最低和建议的硬件配置。

资源最低推荐
中央处理器2 核4 核
内存4 GB8 GB
磁盘40 GB160 GB

软件

下表列出了必须在目标主机上安装的软件版本。

软件版本描述
Docker引擎版本 17.06.0-ce+ 或更高版本有关安装说明,请参阅 Docker 引擎文档
docker-composedocker-compose (v1.18.0+) 或 docker compose v2 (docker-compose-plugin)有关安装说明,请参阅 Docker 撰写文档
OpenSSL最新者优先用于为 Harbor 生成证书和密钥

网络端口

Harbor 要求在目标主机上打开以下端口。

港口协议描述
443HTTPSHarbor 门户和核心 API 接受此端口上的 HTTPS 请求。您可以在配置文件中更改此端口。
4443HTTPS连接到 Docker Content Trust Service for Harbor。仅当启用了公证时才需要。您可以在配置文件中更改此端口。
80HTTPHarbor 门户和核心 API 接受此端口上的 HTTP 请求。您可以在配置文件中更改此端口。

下载并上传安装包后解压安装包

[root@hadoop100 ~]# cd /opt/software/
[root@hadoop100 software]# rz -E
rz waiting to receive.
[root@hadoop100 software]# tar xf harbor-offline-installer-v2.8.2.tgz

打开Harbor配置文件修改域名,关闭https

[root@hadoop100 software]# cd harbor/

[root@hadoop100 harbor]# cp harbor.yml.tmpl harbor.yml
[root@hadoop100 harbor]# vim harbor.yml

hostname: www.mydomain.com

# https related config
#https:
  # https port for harbor, default is 443
  #port: 443
  # The path of cert and key files for nginx
  #certificate: /your/certificate/path
  #private_key: /your/private/key/path

配置域名解析

[root@hadoop100 harbor]# vim /etc/hosts

192.168.220.100 www.mydomain.com

执行安装脚本

[root@hadoop100 harbor]# ./install.sh --with-trivy #启用镜像安全扫描

在镜像上传主机配置仓库地址和域名解析

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

{
"insecure-registries": ["www.mydomain.com"]
}

[root@db02 ~]# systemctl restart docker

[root@db02 ~]# vim /etc/hosts

92.168.220.100 www.mydomain.com

给需要上传的镜像打标签

[root@db02 ~]# docker images
REPOSITORY                         TAG       IMAGE ID       CREATED         SIZE
harbor.magedu.net/myserver/nginx   v1        db67cd822e4f   6 hours ago     447MB

[root@db02 ~]# docker tag harbor.magedu.net/myserver/nginx:v1 www.mydomain.com/myserver/nginx:v1
[root@db02 ~]# docker images
REPOSITORY                         TAG       IMAGE ID       CREATED         SIZE
harbor.magedu.net/myserver/nginx   v1        db67cd822e4f   6 hours ago     447MB
www.mydomain.com/myserver/nginx    v1        db67cd822e4f   6 hours ago     447MB

登录并上传镜像

[root@db02 ~]# docker login www.mydomain.com

[root@db02 ~]# docker push www.mydomain.com/myserver/nginx:v1

在另一台主机下载镜像

[root@db03 ~]# vim /etc/hosts
[root@db03 ~]# vim /etc/docker/daemon.json
[root@db03 ~]# systemctl restart docker
[root@db03 ~]# docker pull www.mydomain.com/myserver/nginx:v1

[root@db03 ~]# docker images
REPOSITORY                        TAG       IMAGE ID       CREATED       SIZE
www.mydomain.com/myserver/nginx   v1        db67cd822e4f   7 hours ago   447MB

5.基于systemd实现容器的CPU及内存的使用限制

默认情况下,容器没有资源限制,可以使用主机内核调度程序允许的尽可能多的给定资源,Docker提供了控制容器可以限制容器使用多少内存或CPU的 方法,运行docker run命令创建容器的时候可以进行资源限制。
Docker早期使用cgroupfs进行容器的资源限制管理,然后再调用内核的cgroup进行资源限制,而kubernetes后来使用systemd直接调用cgroup对进程实现资源限制,等于绕过了docker的cgroupfs的管理,对资源限制更严格、性能更好,因此在kubernetes环境推荐使用systemd进行资源限制。
修改资源限制驱动为 systemd
vim /etc/docker/daemon.json
"exec-opts": ["native.cgroupdriver=systemd"]
systemctl restart docker
docker info
 Cgroup Driver: systemd
物理内存限制参数:
大部分的选项取正整数,跟着一个后缀b,k, m,g,,表示字节,千字节,兆字节或千兆字节。
-m or --memory #限制容器可以使用的最大内存量,如果设置此选项,最小存值为4m(
4兆字节)。
--memory-swap #容器可以使用的交换分区大小,必须要在设置了物理内存限制的前提才能设置交换分区的限制
--memory-swappiness #设置容器使用交换分区的倾向性,值越高表示越倾向于使用swap分区,范围为0-100,0为能不用就不用,100为
能用就用。
--kernel-memory #容器可以使用的最大内核内存量,最小为4m,由于内核内存与用户空间内存隔离,因此无法与用户空间内存直接交换,
因此内核内存不足的容器可能会阻塞宿主主机资源,这会对主机和其他容器或者其他服务进程产生影响,因此不要设置内核内存大小。
--memory-reservation #允许指定小于--memory的软限制,当Docker检测到主机上的争用或内存不足时会激活该限制,如果使用--
memory-reservation,则必须将其设置为低于--memory才能使其优先。 因为它是软限制,所以不能保证容器不超过限制。
--oom-kill-disable #默认情况下,发生OOM时,kernel会杀死容器内进程,但是可以使用--oom-kill-disable参数,可以禁止oom发生在指
定的容器上,即 仅在已设置-m / - memory选项的容器上禁用OOM,如果-m 参数未配置,产生OOM时,主机为了释放内存还会杀死系统进
程。
CPU限制验证:
#只给容器分配最多两核宿主机CPU利用率
# docker run -it --rm --name magedu-c1 --cpus 2 lorel/docker-stress-ng --cpu 4 --vm 4
注:CPU资源限制是将分配给容器的2核心分配到了宿主机每一核心CPU上,也就是容器的总CPU值是在宿主机的每一个核心CPU分配了部
分比例。
Tasks: 288 total, 10 running, 278 sleeping, 0 stopped, 0 zombie
%Cpu0 : 51.2 us, 0.0 sy, 0.0 ni, 48.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 26.4 us, 23.4 sy, 0.0 ni, 50.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 23.1 us, 27.7 sy, 0.0 ni, 49.2 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 18.3 us, 31.3 sy, 0.0 ni, 50.3 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
将容器运行到指定的CPU上:
# docker run -it --rm --name magedu-c1 --cpus 2 --cpuset-cpus 1,3 lorel/docker-stress-ng --cpu 4 --vm 4
基于cpu--shares值(共享值)对CPU进行限制,分别启动两个容器,magedu-c1的--cpu-shares值为1000,magedu-c2的--cpu-shares为
500,观察最终效果,--cpu-shares值为1000的magedu-c1的CPU利用率基本是--cpu-shares为500的magedu-c2的两倍:
# docker run -it --rm --name magedu-c1 --cpu-shares 1000 lorel/docker-stress-ng --cpu 4 --vm 4
# docker run -it --rm --name magedu-c2 --cpu-shares 500 lorel/docker-stress-ng --cpu 4 --vm 4
资源限制验证
1.cgroup验证:
root@docker-server1:~# cat
/sys/fs/cgroup/docker/b7b3755f22962538418dc56c23c03941cd7f97178ed8e25c7d02fbc4ca9878ed/memory.max
536870912
root@docker-server1:~# cat
/sys/fs/cgroup/docker/b7b3755f22962538418dc56c23c03941cd7f97178ed8e25c7d02fbc4ca9878ed/cpu.max
200000 100000
2.systemd限制验证:
root@docker-server1:~# docker start b7b3755f2296
b7b3755f2296
root@docker-server1:~# ps -ef | grep nginx #过滤出目的服务的进程号
root 18770 18736 1 17:08 ? 00:00:00 nginx: master process nginx -g daemon off;
systemd+ 18816 18770 0 17:08 ? 00:00:00 nginx: worker process
root@docker-server1:~# cat /proc/ 18770 /cpuset #查询进程的限制
/system.slice/docker-b7b3755f22962538418dc56c23c03941cd7f97178ed8e25c7d02fbc4ca9878ed.scope
root@docker-server1:~# cat /sys/fs/cgroup/system.slice/docker-
b7b3755f22962538418dc56c23c03941cd7f97178ed8e25c7d02fbc4ca9878ed.scope/cpu.max #
查询cpu限制范围
200000 100000
root@docker-server1:~# cat /sys/fs/cgroup/system.slice/docker-
b7b3755f22962538418dc56c23c03941cd7f97178ed8e25c7d02fbc4ca9878ed.scope/memory.max #查询内存限制范围
/sys/fs/cgroup/systemd/system.slice/docker-ecf608ac1031be2c78c99c0b7d12a9798a70388aee8bc50425873f3af039aef2.scope
536870912
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值