企业级运维之云原生与Kubernetes实战课程
第三章第5讲 阿里云ACK集群网络
视频地址:https://developer.aliyun.com/learning/course/913/detail/14606
目录
一、 Flannel网络
二、 Terway网络
三、 CoreDNS
四、 最佳实践
在ACK中,可以通过两种网络模式实现容器网络能力,分别是Flannel网络模式和Terway网络模式。
一、Flannel网络
Flannel是为Kubernetes设置的一个简单的三层网络实现的网络插件,在阿里云上使用的Flannel网络模式采用阿里云VPC模式,Flannel网络基于阿里云VPC的自定义路由能力,来实现跨节点的Pod直接与VPC的互相访问。
1. Flannel工作原理
集群的每个节点上会起一个flannel agent,并且会给每个节点预分配一个Pod CIDR,这个Pod CIDR是容器集群Pod CIDR的子集。Pod的报文通过后端机制来进行转发。
在集群中,无论Pod是否跨节点,Pod之间是可以相互通信的,前面章节也讲解了Pod与SVC(Service)、Pod与外部的通信原理。在Flannel网络模式中,如下图所示,集群的CIDR地址段包含了节点所在的网络地址段,基于设备对的映射关系流量会首先经过eth0,流向cni0到达对端Pod内eth0,CCM负责将每个节点的Pod CIDR网段在VPC路由表中指向对应的ECS。
问题:在集群里添加新的节点,如果Pod网络不通,在Flannel模式中如何排查?
解决方法:
- 登录Flannel模式K8s集群Master节点;
- 执行命令kubectl describe node xxx(xxx为节点名称)可以查看到Pod CIDR网络地址段,而CCM会将该网段加到VPC的路由表;
- 执行命令kubectl exec -it xxx(xxx为Pod服务名) bash,以bash的方式进入任意运行的Pod中;
- 执行dig请求或tcpdump进行抓包分析,Flannel集群模式下在主要在节点eth0和对端Pod内eth0上进行抓包;
- 如果在节点eth0上可以抓到流出的包及回包,以此判断iptables/lpvs转发正常;
- 如果在节点eth0节点上可以抓到包,而在对端Pod内eth0上抓不到包,可能是iptables/lpvs、内核协议栈、tcp/udp memory满导致流量包被丢弃,通过执行命令netstat -st查看所有TCP的统计信息;
- 抓包示例:
- 命令:tcpdump -i any host ip -s0 -w p.pcap -C 200 -W 50
- -i any指定所有网卡,host ip是指定主机ip地址,-s0设置buffer值为不限制包的大小,-w指定写入的文件,-C -W指定抓包文件大小和数量。
二、Terway网络
Terway是阿里云容器服务团队推出的针对阿里云VPC网络的CNI插件,稳定、高性能,支持Kubernetes NetworkPolicy 流控等,在Terway网络下,Pod的IP和集群的ECS所属相同VPC,是由交换机进行分配,如下图所示:
在Terway网络插件中,每个Pod都拥有自己网络栈和IP地址。同一台ECS内的Pod之间通信,直接通过机器内部的转发;跨ECS的Pod通信、报文通过VPC的弹性网卡直接转发。
目前云上Flannel、Terway网络模式的集群,不支持节点上不同的Pod CIDR扩容,建议使用Terway的eni多IP方式增加交换机。
Terway集群下执行命令:terway-cli mapping查看Pod名称及分配的Pod IP;抓包命令:tcpdump -i any host ip -nnvv -xxx。
Terway网络拓扑图
三、CoreDNS
CoreDNS是一个灵活可扩展的DNS服务器,可以作为Kubernetes集群DNS,解析服务域名和集群外部域名。
云上默认配置CoreDns的IP为x.x.0.10(x.x为容器分配的网段),与选择的网段无关,默认启动两副本,可以进入任意Pod执行命令kubectl exec -it xxx(xxx为服务名) bash,进入容器内执行命令cat /etc/resolv.conf查看nameserver的值为x.x.0.10。
CoreDNS的解析过程
集群服务域名,如:<servicename>.<namespace>.svc.cluster.local
集群外部域名,如: www.aliyun.com, rm-2z****9na.mysql.rds.aliyuncs.com
- Pod发起域名解析请求时,首先发给CoreDNS x.x.1.0进行解析,CoreDNS根据集群模式的不同转发到后端endpoint;
- 执行命令:ipvsadm -Ln|grep 0.10查看转发信息;
- 当在集群中解析外部域名失败时,可以通过抓包,在节点和容器内分别执行命令:tcpdump -i any port 53 -nnvv -xxx|grep -i xx(xx为匹配查找的关键字);
- 执行命令ipvsadm -Ln -c,可以查看ipvs session,默认900s会话保持,超过900s会话连接会被释放,在ipvs集群中建议长连接keepalive的值设置900s以内。
四、最佳实践
场景一:
当有海量DNS请求时,如何调整CoreDNS cache时间,减少CoreDNS forward外部DNS解析的压力。
方案一:kubectl -nkube-system edit cm coredns,修改cache的值为60
示例:
Corefile:
.:53 {
errors
health{
lameduck 5s
}
ready
kubernetes clusterlocal in-addrarpaip6arpa{
pods insecure
upstream
fallthrough in-addrarpaip6.arpa
ttl 30
}
rewrite name regex (.*)\.my\.domain {1}.default.svc.cluster.local
prometheus:9153
Forward. /etc/resolv.conf
cache 10
Log
Loop
reload
loadbalance
}
kind: ConfigMap
方案一:通过curl -4 -v url来指定通过ipv4方式访问服务。
方案三:Pod内启用nscd(DNS缓存服务),根据nscd的缓存机制可以忽略解析本身导致的问题。
场景二:
添加svc.local后缀的外部域名,直接用默认dns去解析,而不是先走完所有zone: defaultsvc.clusterlocal,svc.clusterlocal,cluster.local,如何优化呢?
方案一:使用标准fqdn域名,即在域名后加“.”(比如www.aliyun.com.)
方案二:
修改deployment,增加options里的:
-name ndots
value:"1"
示例:
app: test1
spec:
containers:
- image: nginx: latest
imagePullPolicy: Always
LivenessProbe:
failureThreshold:3
initialDelaySeconds:15
periodSeconds:10
successThreshold:1
tcpSocket:
port:80
timeoutSeconds: 1
name:test1
resources:
limits:
cpu: “1”
memory: 100Mi
requests:
cpu:250m
memory:32Mi
terminationMessagePath:/dev/termination-log terminationMessagePolicy: File
dnsConfig:
options:
- name: single-request-reopen
- name: ndots
value: “1”
dnsPolicy: ClusterFirst
restartPolicy:Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
场景三:
如何将AAAA请求和A请求分开发送,而不是放到一个stream中,避免conntrack插表竞争导致解析失败?
方案:
修改deployment配置:kubectl edit deploy test1
在template.spec下的dns配置,添加:
dnsConfig:
options:
-name:single-request-reopen
示例:
template:
metadata:
creationTimestamp:null
labels:
app:test1
Spec:
containers:
- image:nginx:latest
imagePullPolicy:Always
livenessProbe:
failureThreshold:3
initialDelaySeconds:15
periodseconds:10
successThreshold:1
tcpSocket:
port:80
timeoutSeconds:1
name:test1
resources:
limits:
cpu:"1"
memory: 100Mi
requests:
cpu:250m
memory:32Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicv: File
dnsConfig:
options:
-name: single-request-reopen
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
本讲小结
1. 集群网络相关的知识,包括flannel、terway两种网络插件;
2. CoreDns组件是如何解析集群内外部域名的;
思考:
1. flannel集群,Pod访问内网rds、slb实例的网络过程?
2. flannel/terway集群,Pod访问内网rds,要如何添加 rds白名单?
3. flannel/terway集群遇到网络问题时如何抓包?
4. Pod内解析外部域名失败,要怎么排查?