技术分享及探讨
前言
很高兴给大家做一个技术分享及探讨。
下面给大家分享几个工作遇到有趣的例子。
docker
docker 进程
现象
客户的模型导入到BML平台发布预测服务后,模型本身是用django提供的支持。按照本地docker的方式进行调试,kill掉django的进程修改代码后重启进程服务,发现服务会重启。前提,客户是有一定的容器使用经验的。
原脚本如下:
#!/bin/bash
Nohup nginx start > /dev/null
Nohup python mange.py runserver 127.0.0.1:8080 > /dev/null
原因
对linux系统来说1号进程为init进程,是由0号进程(内核进程)通过调用系统init函数创建的第一个用户进程1进程,主要做用户态进程的管理,垃圾回收等动作。
对docker来讲1号进程大多数情况下都是服务进程,或者是用户自己开发的服务daemon进程,这也是瘦容器的理论,那服务进程作为1号进程有什么区别呢?
docker进程管理的基础是LINUX内核中的PID命名空间技术,在不同PID名空间中,进程ID是独立的;即在两个不同名空间下的进程可以有相同的PID。这句话的意思就是docker通过空间技术进行了容器间的进程隔离。
当创建一个Docker容器的时候,就会新建一个PID名空间。容器启动进程在该名空间内PID为1。
当PID1进程结束之后,Docker会销毁对应的PID名空间,并向容器内所有其它的子进程发送SIGKILL。
容器的设计本身是“单进程”模型,容器=应用=进程。
方案:
加上一个前台进程也是pid=1的进程。
tail -f /etc/hosts
相关文档
BML模型纳管与模型调试
docker overlay 文件系统
背景
光大较为谨慎,采用的是双线加负载方式。所以生产环境部署BML4.3需要上线2套环境,需要在周末俩天之内部署完成,部署时间还是比较紧张。
由于4.3部署采用的是镜像load的方式镜像,load镜像时间极长。并且是把镜像load到一个docker的挂载卷上。
分析
docker提供了两种 OverlayFS,一个是原本的 overlay文件系统,另一个是更新、更稳定的 overlay2。在日常使用中,应该更倾向于使用更好更稳定的 overlay2而不是 overlay。
查看/etc/docker/daemon.json文件来查看是用的那种方式。
{
"storage-driver": "overlay2"
}
磁盘上的镜像和容器层
这里举拉取乌邦图镜像的例子来说明。
在使用指令docker pull ubuntu下载五层镜像的ubantu后,可以在/var/lib/docker/overlay2看到有六个目录。
$ ls -l /var/lib/docker/overlay2
total 24
drwx------ 5 root root 4096 Jun 20 07:36 223c2864175491657d238e2664251df13b63adb8d050924fd1bfcdb278b866f7
drwx------ 3 root root 4096 Jun 20 07:36 3a36935c9df35472229c57f4a27105a136f5e4dbef0f87905b2e506e494e348b
drwx------ 5 root root 4096 Jun 20 07:36 4e9fa83caff3e8f4cc83693fa407a4a9fac9573deaf481506c102d484dd1e6a1
drwx------ 5 root root 4096 Jun 20 07:36 e8876a226237217ec61c4baf238a32992291d059fdac95ed6303bdff3f59cff5
drwx------ 5 root root 4096 Jun 20 07:36 eca1e4e1694283e001f200a667bb3cb40853cf2d1b12c29feda7422fed78afed
drwx------ 2 root root 4096 Jun 20 07:36 l
思考与方案
将A集群load好的镜像docker卷打包,在B集群上进行解压,以此完成快速部署的目的。
这个也在事后提出,反馈并合并到后面的标版部署中。
缺点
由于是解压后卷镜像挂载,不是导入的镜像,所以使用docker images 等命令 无法查看到相关的镜像。
整理如下命令,供参考
相应的参考命令:
#查询镜像
curl <仓库地址>/v2/_catalog
#查询镜像tag(版本)
curl <仓库地址>/v2/<镜像名>/tags/list
#查询镜像 digest_hash
curl --header "Accept:application/vnd.docker.distribution.manifest.v2+json" -I -XGET <仓库地址>/v2/<镜像名>/manifests/<tag>
#删除镜像API
curl -I -X DELETE "<仓库地址>/v2/<镜像名>/manifests/<镜像digest_hash>"
#查询镜像
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NWsgcerW-1680159294012)(null)]
#查询镜像tag(版本)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3oEWYuwt-1680159294359)(null)]
docker 常见问题排查
场景一、生产集群磁盘爆满
根据目录查找所在的容器名称,找到对应的容器名称,根据对应的容器名称找到BMl 上对应的POD。
根据docker overylay2 目录下的文件夹名称 查找容器
docker ps -q | xargs docker inspect --format '{{.State.Pid}}, {{.Id}}, {{.Name}}, {{.GraphDriver.Data.WorkDir}}' | grep "文件夹名称"
最后发现是一个用户起的notebook,上传东西到容器内,将磁盘撑爆了。
场景二、物理机上某个线程占用GPU、CPU 高
方法一
根据pid 查找容器名称
[root@gzbh-intel016 ~]# cd /proc/74841
[root@gzbh-intel016 74841]# pwd
/proc/74841
[root@gzbh-intel016 74841]# ps -ef | grep 74841
root 74841 74840 1 Dec18 ? 03:49:46 bin/signature_handwriting
root 89107 20906 0 17:48 pts/2 00:00:00 grep --color=auto 74841
[root@gzbh-intel016 74841]# ps -ef | grep 74840
root 74840 74327 0 Dec18 ? 00:00:00 bin/supervise.signature_handwriting -p status/signature_handwriting -f bin/signature_handwriting
root 74841 74840 1 Dec18 ? 03:49:47 bin/signature_handwriting
root 89663 20906 0 17:48 pts/2 00:00:00 grep --color=auto 74840
[root@gzbh-intel016 74841]# ps -ef | grep 74327
root 74327 74308 0 Dec18 ? 00:00:00 sh /home/work/app/console/all_start.sh 0 4g
root 74385 74327 0 Dec18 ? 00:00:00 sh java_start.sh
root 74389 74327 0 Dec18 ? 00:00:00 tail -f /etc/hosts
root 74840 74327 0 Dec18 ? 00:00:00 bin/supervise.signature_handwriting -p status/signature_handwriting -f bin/signature_handwriting
root 91492 20906 0 17:48 pts/2 00:00:00 grep --color=auto 74327
[root@gzbh-intel016 74841]#
[root@gzbh-intel016 74841]# ps -ef | grep 74308
root 74308 13670 0 Dec18 ? 00:01:05 docker-containerd-shim -namespace moby -workdir /data/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/0000936684d05d4c98c67fa8606d89f367a7985a0d05449bbef812422897b1b2 -address /var/run/docker/containerd/docker-containerd.sock -containerd-binary /usr/bin/docker-containerd -runtime-root /var/run/docker/runtime-nvidia
root 74327 74308 0 Dec18 ? 00:00:00 sh /home/work/app/console/all_start.sh 0 4g
root 93870 20906 0 17:48 pts/2 00:00:00 grep --color=auto 74308
最重发现 物理机 路径为 /data/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/0000936684
查找容器名称
[root@gzbh-intel016 0000936684d05d4c98c67fa8606d89f367a7985a0d05449bbef812422897b1b2]# pwd
/data/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/0000936684d05d4c98c67fa8606d89f367a7985a0d05449bbef812422897b1b2
[root@gzbh-intel016 0000936684d05d4c98c67fa8606d89f367a7985a0d05449bbef812422897b1b2]# ll
total 0
[root@gzbh-intel016 0000936684d05d4c98c67fa8606d89f367a7985a0d05449bbef812422897b1b2]# docker ps -a | grep 0000936684
0000936684d0 244aea358579 "/bin/bash -ce 'sh /…" 11 days ago Up 11 days k8s_guangda-cursive_guangda-cursive-86d55fcf65-7dpsw_default_d0b3091b-5fc3-11ec-9318-bc97e1b8d4ae_0
可知容器名称为
k8s_guangda-cursive_guangda-cursive-86d55fcf65-7dpsw_default_d0b3091b-5fc3-11ec-9318-bc97e1b
方法二
根据进程号获取容器名称
docker ps -q | xargs docker inspect -f '{{.State.Pid}} {{.Config.Hostname}}' | grep 2811
再通过docker ps | grep 0bbea2sd3ds15
便可获取到容器名称
场景三、GPU服务器上 启动docker容器识别不到GPU
概念
为了让docker支持nvidia显卡,英伟达公司开发了nvidia-docker。该软件是对docker的包装,使得容器能够看到并使用宿主机的nvidia显卡。
正常机器的对比
GPU服务器的docker 与daemon.json
[root@instance-q2pzfrcc ~]# rpm -qa | grep docker
docker-ce-18.09.7-3.el7.x86_64
docker-ce-cli-18.09.7-3.el7.x86_64
nvidia-container-runtime-2.0.0-3.docker18.09.7.x86_64
nvidia-docker2-2.0.3-3.docker18.09.7.ce.noarch
[root@gzbh-intel003 ~]# cat /etc/docker/daemon.json
{
"hosts": ["tcp://10.36.245.149:8137", "unix:///var/run/docker.sock"],
"default-runtime": "nvidia",
"runtimes": {
"nvidia": {
"path": "/usr/bin/nvidia-container-runtime",
"runtimeArgs": []
}
}
}
CPU服务器的docker 与daemon.json
[root@instance-asdsadsadcds ~]# rpm -qa | grep docker
docker-ce-18.09.7-3.el7.x86_64
docker-ce-cli-18.09.7-3.el7.x86_64
[root@gzbh-intelmbx001 images]# cat /etc/docker/daemon.json
{
"hosts": ["tcp://10.36.252.167:8137", "unix:///var/run/docker.sock"],
"init": true,
"init-path": "/usr/bin/docker-init",
"storage-opts": [
"overlay2.override_kernel_check=true"
]
}
原理
nvidia-docker是一个可以使用GPU的docker,nvidia-docker是在docker上做了一层封装,通过nvidia-docker-plugin,然后调用到docker上,其最终实现的还是在docker的启动命令上携带一些必要的参数。因此在安装nvidia-docker之前,还是需要安装docker的。
Nvidia-dockerNvidia提供Nvidia-docker项目,它是通过修改Docker的Runtime为nvidia runtime工作,当我们执行 nvidia-docker create 或者 nvidia-docker run时,它会默认加上 --runtime=nvidia 参数。将runtime指定为nvidia。当然,为了方便使用,可以直接修改Docker daemon 的启动参数,修改默认的 Runtime为 nvidia-container-runtime
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-tHfdELOp-1680159294138)(null)]
注意
在docker19以前都需要单独下载nvidia-docker1或nvidia-docker2来启动容器,自从升级了docker19后跑需要gpu的docker只需要加个参数–gpus all 即可
docker run -d -it -p 1518:1518 --name="centos" --gpus all nvidia/cuda:9.1-cudnn7-runtime-centos7 /bin/bash
其他场景问题
1、镜像八小时问题。
2、root 与 普通用户切换问题。
3、docker 迁移存储目录
4、添加信任仓库。
5、容器启动不使用网桥默认网段。
参考文档:docker原理及运维
推荐工具
一、docker-compose
举例:
使用命令docker-compose -f *.yaml up -d 启动mysql
类似于k8s的yaml 编排。
是单机管理,编排容器,可以同时管理多个 container ,将多个相关的容器⼀次性启动,⽐如运⾏⼀个jar需要依赖jdk、mysql、mq、redis等,这些容器只需要 docker-composer up 就可以全部启动,不需要⼀个个单独启动。
version: '2'
services:
mysql-db:
container_name: mysql
restart: always
image: mysql:5.7
ports:
- 3306:3306
environment:
TZ: Asia/Shanghai
MYSQL_ROOT_PASSWORD: 123456
command:
--character-set-server=utf8mb4
--collation-server=utf8mb4_general_ci
--explicit_defaults_for_timestamp=true
--lower_case_table_names=1
--max_allowed_packet=128M
--sql-mode="STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,NO_ZERO_DATE,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO"
volumes:
- /Users/wangjinlong05/app/data/mysqldockerdata/data:/var/lib/mysql
二、portainer
适合客户侧容器小白使用
开启2375 docker远程管理端口
vim /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H unix://var/run/docker.sock -H tcp://0.0.0.0:2375
systemctl daemon-reload && systemctl restart docker
拉取镜像
docker pull portainer/portainer
启动容器
docker run -d -p 9000:9000 \
-v /var/run/docker.sock:/var/run/docker.sock \
--restart=always \
portainer/portainer
如果已经启动可以更新
docker run -d -p 9000:9000\
-v /var/run/docker.sock:/var/run/docker.sock \
update --restart=always \
portainer/portainer
k8s
场景一:集群数据库迁移
背景
客户测试环境部署4.3交付。
原部署计划是由客户提供mysql集群,由我们部署对接,由于客户测试环境的mysql环境没提前准备好,所以我们集群自建mysql环境搭建。运行一个月后,客户要求BML的mysql 迁移对接到他们的mysql行内集群。
难点
由于bml 部署配置繁杂,mysql 初始化地方极多,稍有不慎就会导致集群出现故障。迁移mysql 改造对接成本较高。
概念
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SF48FwhD-1680159294081)(null)]
具体的四表
- filter表——涉及FORWARD、INPUT、OUTPUT三条链,多用于本地和转发过程中数据过滤;(负责过滤工程,防火墙 )
- Nat表——涉及PREROUTING、OUTPUT、POSTROUTTING三条链,多用于源地址/端口转换和目标地址/端口的转换;(网络地址转换功能 network address translate )
- Mangle表——涉及整条链,可实现拆解报文、修改报文、重新封装,可常见于IPVS的PPC下多端口会话保持。
- (拆解报文,做出修改,并重新封装 )
- Raw表——涉及PREROUTING和OUTPUT链,决定数据包是否被状态跟踪机制处理,需关闭nat表上的连接追踪机制。
- (关闭nat表上启用的连接追踪机制)
具体的五链
- INPUT——进来的数据包应用此规则链中的策略
- OUTPUT——外出的数据包应用此规则链中的策略
- FORWARD——转发数据包时应用此规则链路中的策略
- PREROUTING——对数据包作路由选择前应用此链中的规则(所有的数据包进来的时候都先由这个链处理)
- POSTROUTING——对数据包作路由选择后应用此链中的规则(所有的数据包出来的时候都先由这个链处理)
链表关系
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hgyLFrkx-1680159294199)(null)]
iptables处理动作
iptables处理动作除了 ACCEPT、REJECT、DROP、REDIRECT 、MASQUERADE 以外,还多出 LOG、ULOG、DNAT、RETURN、TOS、SNAT、MIRROR、QUEUE、TTL、MARK等。我们只说明其中最常用的动作:
REJECT 拦阻该数据包,并返回数据包通知对方,可以返回的数据包有几个选择:ICMP port-unreachable、ICMP echo-reply 或是tcp-reset(这个数据包包会要求对方关闭联机),进行完此处理动作后,将不再比对其它规则,直接中断过滤程序。 范例如下:
iptables -A INPUT -p TCP --dport 22 -j REJECT --reject-with ICMP echo-reply
DROP 丢弃数据包不予处理,进行完此处理动作后,将不再比对其它规则,直接中断过滤程序。
REDIRECT 将封包重新导向到另一个端口(PNAT),进行完此处理动作后,将会继续比对其它规则。这个功能可以用来实作透明代理 或用来保护web 服务器。例如:
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT–to-ports 8081
MASQUERADE 改写封包来源IP为防火墙的IP,可以指定port 对应的范围,进行完此处理动作后,直接跳往下一个规则链(mangle:postrouting)。这个功能与 SNAT 略有不同,当进行IP 伪装时,不需指定要伪装成哪个 IP,IP 会从网卡直接读取,当使用拨接连线时,IP 通常是由 ISP 公司的 DHCP服务器指派的,这个时候 MASQUERADE 特别有用。范例如下:
iptables -t nat -A POSTROUTING -p TCP -j MASQUERADE --to-ports 21000-31000
LOG 将数据包相关信息纪录在 /var/log 中,详细位置请查阅 /etc/syslog.conf 配置文件,进行完此处理动作后,将会继续比对其它规则。例如:
iptables -A INPUT -p tcp -j LOG --log-prefix “input packet”
SNAT 改写封包来源 IP 为某特定 IP 或 IP 范围,可以指定 port 对应的范围,进行完此处理动作后,将直接跳往下一个规则炼(mangle:postrouting)。范例如下:
iptables -t nat -A POSTROUTING -p tcp -o eth0 -j SNAT --to-source 192.168.10.15-192.168.10.160:2100-3200
DNAT 改写数据包包目的地 IP 为某特定 IP 或 IP 范围,可以指定 port 对应的范围,进行完此处理动作后,将会直接跳往下一个规则链(filter:input 或 filter:forward)。范例如下:
iptables -t nat -A PREROUTING -p tcp -d 15.45.23.67 --dport 80 -j DNAT --to-destination 192.168.10.1-192.168.10.10:80-100
MIRROR 镜像数据包,也就是将来源 IP与目的地IP对调后,将数据包返回,进行完此处理动作后,将会中断过滤程序。
QUEUE 中断过滤程序,将封包放入队列,交给其它程序处理。透过自行开发的处理程序,可以进行其它应用,例如:计算联机费用…等。
RETURN 结束在目前规则链中的过滤程序,返回主规则链继续过滤,如果把自订规则炼看成是一个子程序,那么这个动作,就相当于提早结束子程序并返回到主程序中。
MARK 将封包标上某个代号,以便提供作为后续过滤的条件判断依据,进行完此处理动作后,将会继续比对其它规则。
方案
在不改变原集群任何的组件及配置的基础上进行使用iptables进行转发。
分为两部分:请求出去的时候转发,请求回来的时候处理转发。
将mysql请求发送出去,不再由本机处理。
将请求到原地址36.6的3308转发到 3309
iptables -t nat -A PREROUTING -d 10.200.36.6 -p tcp -m tcp --dport 3308 -j DNAT --to-destination mysqlIP:3309
说明: 修改nat表 在规则链的末尾加入新规则 PREROUTING链匹配来自36.6 端口3308的请求-j 进行DNAT 操作 目的地为 mysqlIP:3309
将对方请求接收后,转发回给微服务。
比如bml-dataset 请求原地址的mysql ip端口,再由这个ip端口进行回应。
只要是从mysqlip 3309 过来的的通讯 POSTROUTING 到 36.6的3308上出去
iptables -t nat -A POSTROUTING -d mysqlIP -p tcp -m tcp --dport 3309 -j SNAT --to-source 10.200.36.6:3308
优缺点
优点; 对接改造成本比较低,执行两个规则即可。
缺点:所有的mysql请求都在一个节点上,做不到mysql的高可用(可接受)
综述:利大于弊。
场景二: 预测服务转发无效
背景
用户在集群上发布了俩个预测服务A和B,但是外面访问不到A服务,但是可以访问到B服务。
kubect 查看pod 正常,无日志输出。
概念
kube-proxy通过观察Kubernetes中service和endpoint对象的变化,当有servcie创建时,kube-proxy在iptables中追加新的规则。对于service的每一个endpoint,会在iptables中追加一条规则,设定动作为DNAT,将目的地址设置成真正提供服务的pod地址;再为servcie追加规则,设定动作为跳转到对应的endpoint的规则上,
默认情况下,kube-proxy随机选择一个后端的服务,可以通过iptables中的 -m recent 模块实现session affinity功能,通过 -m statistic 模块实现负载均衡时的权重功能
排查过程
在Node节点上实现Pod网络代理,维护网络规则和四层负载均衡工作。实现让Pod节点(一个或者多个容器)对外提供服务
service在逻辑上代表了后端的多个Pod,外借通过service访问Pod。service接收到请求就需要kube-proxy完成转发到Pod的。每个Node都会运行kube-proxy服务,负责将访问的service的TCP/UDP数据流转发到后端的容器。
第一步 初步怀疑kube-porxy
感觉问题出在kube-proxy上,之前有过类似问题排查结果。初步怀疑是转发规则创建问题。
kubectl delete pod kube-porxy ,
等待kube-porxy重启
。。。。。。。
没起作用。
第二步 重建规则
清空规则,重建规则
iptables -F
kubectl delete pod kube-porxy
等待kube-porxy重启
。。。。。。。
没起作用。
第三步 排查创建的规则并且抓包
[root@nf52801602]# iptables -t nat -nvL
Chain PREROUTING (policy ACCEPT 84 packets, 5040 bytes)
pkts bytes target prot opt in out source destination
5216M 752G KUBE-SERVICES all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes service portals */
37M 2240M CNI-HOSTPORT-DNAT all -- * * 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
查看svc的链 iptables -t nat -nvL KUBE-SERVICES
[root@nf52801602]# iptables -t nat -nvL KUBE-SERVICES
Chain KUBE-SERVICES (2 references)
pkts bytes target prot opt in out source destination
0 0 KUBE-MARK-MASQ tcp -- * * !10.233.64.0/18 10.233.0.55
/* default/redis-cluster-proxy:proxy cluster IP */ tcp dpt:7777
0 0 KUBE-SVC-3FNBBYIZCXANEL3B tcp -- * * 0.0.0.0/0 10.233.0.55
/* default/redis-cluster-proxy:proxy cluster IP */ tcp dpt:7777
10.233.0.55 为svice ip
查看 KUBE-SVC-3FNBBYIZCXANEL3B链
[root@nf52801602]# iptables -t nat -nvL KUBE-SVC-3FNBBYIZCXANEL3B
Chain KUBE-SVC-3FNBBYIZCXANEL3B (2 references)
pkts bytes target prot opt in out source destination
0 0 KUBE-SEP-E3VN2RK7BFTPB2QU all -- * * 0.0.0.0/0 0.0.0.0/0 statistic mode random probability 0.50000000000
0 0 KUBE-SEP-QWICKHRY75ZBMBDW all -- * * 0.0.0.0/0 0.0.0.0/0
发现2个pod是随机0.5概率
查看 KUBE-SEP-E3VN2RK7BFTPB2QU自定义链
[root@nf52801602]# iptables -t nat -nvL KUBE-SEP-E3VN2RK7BFTPB2QU
Chain KUBE-SEP-E3VN2RK7BFTPB2QU (1 references)
pkts bytes target prot opt in out source destination
0 0 KUBE-MARK-MASQ all -- * * 10.233.64.160 0.0.0.0/0
0 0 DNAT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp to:10.233.64.160:7777
发现DNAT转发到10.233.64.160:7777 正是上面的 pod ip
SNAT
[root@nf52801602]# iptables -t nat -nvL KUBE-POSTROUTING
Chain KUBE-POSTROUTING (1 references)
pkts bytes target prot opt in out source destination
0 0 MASQUERADE all -- * * 0.0.0.0/0 0.0.0.0/0 /* kubernetes service traffic requiring SNAT */ mark match 0x4000/0x4000
[root@yq01-aip-aikefu08 ~]#
ok 没有问题。
抓包 tcpdump,使用wireshark分析,抓到了业务方请求。。
请求确实已经到达了我方。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-99If7b73-1680159294305)(null)]
对pod中的veth 设备对抓包发现没有请求。
#!/bin/bash
for container in $(docker ps -q); do
iflink=`docker exec -it $container bash -c 'cat /sys/class/net/eth0/iflink'`
iflink=`echo $iflink|tr -d '\r'`
veth=`grep -l $iflink /sys/class/net/veth*/ifindex`
veth=`echo $veth|sed -e 's;^.*net/\(.*\)/ifindex$;\1;'`
echo $container:$veth
done
那就抓flannel.1网桥
tcpdump -i flannel.1 -nn icmp
分析一波,也有业务方请求。。
继续下一波
抓去cni,发现cni没有收到请求。
比较诡异,重启flannel.1 与cni后正常。
其他场景
1、k8s集群证书过期k8s证书相关
2、api-server宕掉。
3、单节点容器数量上限。
4、ipvs替换iptables.
5、k8s集群服务访问集群外服务coredns映射。
结尾
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Rgbz5d1w-1680159294252)(null)]
今天我的分享就到这里,谢谢大家!