Kubernetes集群——网络管理
目录一.认识Multus CNI1.1什么是Multus CNI1.2核心价值1.3工作原理二.部署Multus2.1下载yaml配置文件2.2下载镜像文件2.3修改yaml文件2.4部署Multus2.5创建macvlan从网络静态网络2.6创建多网络接口 Pod2.7创建macvlan-pool网络池(自动分配)2.8自动分配IP三.网络策略——NetworkPolicy3.1限制Pod流量3.2限制namespace流量3.3同时限制Pod和Namespace3.4限制集群外部流量一.认识Multus CNI1.1什么是Multus CNI1.概念Multus CNI是一个用于 Kubernetes 的多网络插件Multi-Network Plugin它的核心作用是让一个 Pod 能够同时接入多个网络接口。默认k8s集群使用的主要网卡是eth0apiserverprobe和Pod属于管理组件和默认Pod流量他们属于是软件转发veth bridge主要走eth0这条默认路径。而真正的业务Pod由于流量巨大软件转发会大量消耗 CPU。因此需要独立的网络接口去承担流量。1.2核心价值默认情况下k8s集群的CNI网络插件只允许为Pod分配一个主网络接口所有流量都通过这个接口流通。而Multus提供了一种新的网络方式1.挂载多个网络接口Pod允许同时拥有多个网络接口分别接入不同的网络中。2.兼容CNI网络插件允许多个网络插件存在共同管理网络。1.3工作原理Multus插件的核心机制分层协作。即“主 CNI 从 CNI”。1.主CNI负责Pod的主要网络接口eth0通常是Calico提供Pod与集群内其他资源的基础通信。2.从CNI其他网络插件如Multus为Pod提供额外的网络接口用于实现高并发等需求。二.部署Multus2.1下载yaml配置文件wget https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset.yml2.2下载镜像文件1.下载镜像docker pull ghcr.io/k8snetworkplumbingwg/multus-cni:snapshot2.上传镜像到harbardocker tag ghcr.io/k8snetworkplumbingwg/multus-cni:snapshot reg.westos.org/multus/multus-cni:snapshot docker push reg.westos.org/multus/multus-cni:snapshot2.3修改yaml文件vim multus-daemonset.yml修改镜像地址为下面的内容image: reg.westos.org/multus/multus-cni:snapshotimage: reg.westos.org/multus/multus-cni:snapshot2.4部署Multuskubectl apply -f multus-daemonset.ymlkubectl get pod -n kube-system -l appmultus说明multus以daemonent形式部署要求集群中的所有节点都要运行。k8s1上没有运行是因为自身节点存在污点k8s1不会进行调度。2.5创建macvlan从网络静态网络说明macvlan 允许在一张物理网卡上创建多个“虚拟子接口”每个子接口有自己独立的 MAC 地址和 IP在网络上看起来就像一台独立的物理机器。1.编辑yaml文件vim macvlan-static.yml添加以下内容apiVersion: k8s.cni.cncf.io/v1 kind: NetworkAttachmentDefinition metadata: name: macvlan-static spec: config: { cniVersion: 0.4.0, type: macvlan, master: eth0, #在指定网卡上创建一个子接口最好选一张独立的物理网卡 mode: bridge, #网络模式 ipam: { type: static, #静态IP addresses: [{ address: 192.168.7.10/24, gateway: 192.168.7.2 }] #新的网络和网卡 } }2.运行从网络kubectl apply -f macvlan-static.yml kubectl get networkattachmentdefinition.k8s.cni.cncf.io/macvlan-static kubectl describe2.6创建多网络接口 Pod说明为Pod配置刚才的从网络接口除了默认 CNI 给的eth0再按名字macvlan-static找到对应的 NetworkAttachmentDefinition给 Pod 额外挂一张网卡。1.编写yaml文件vim pod-web-multus-static.yml添加以下内容apiVersion: v1 kind: Pod metadata: name: multus-web labels: app: multus annotations: #注解 k8s.v1.cni.cncf.io/networks: macvlan-static #创建这个 Pod 时除了默认 CNI 给的 eth0再按名字 macvlan-static 找到对应的 NetworkAttachmentDefinition给 Pod 额外挂一张网卡。 spec: containers: - name: apache-frontend image: reg.westos.org/library/httpd:dns ports: - containerPort: 802.运行Podkubectl create -f pod-web-multus-static.yml kubectl get pod multus-web -o wide kubectl describe pod multus-web3.测试连通性说明由于macvlan绑定eth0后破坏了宿主机和vxlan隧道之间的通信所以使用Cluster IP无法访问到Pod选择的独立网卡不会影响Cluster IP的Pod访问curl 192.168.7.10 #从网络上分配的IP curl 10.244.219.57 #访问Cluster IP2.7创建macvlan-pool网络池(自动分配)说明配置单一macvlan网络比较麻烦创建pool网络池当有新的Pod被创建后会从网络池中自动分配网路给新Pod1. 编写yaml文件vim macvlan-pool.yml添加以下内容apiVersion: k8s.cni.cncf.io/v1 kind: NetworkAttachmentDefinition metadata: name: macvlan-pool spec: config: { cniVersion: 0.4.0, type: macvlan, master: eth0, mode: bridge, ipam: { type: host-local, subnet: 192.168.7.0/24, #分配网段 rangeStart: 192.168.7.200, #分配网络起始IP rangeEnd: 192.168.7.216, #分配网络末尾IP gateway: 192.168.7.2 } }2.关闭静态分配网络运行自动分配网络kubectl delete -f pod-web-multus-static.yml kubectl delete -f macvlan-static.yml kubectl apply -f macvlan-pool.yml kubectl get net-attach-def macvlan-pool kubectl describe net-attach-def macvlan-pool2.8自动分配IP1.编写yaml文件vim pod-web-multus-pool.yml添加以下内容apiVersion: v1 kind: Pod metadata: name: multus-web-pool labels: app: multus annotations: k8s.v1.cni.cncf.io/networks: macvlan-pool #使用macvlan-pool spec: containers: - name: apache-frontend image: reg.westos.org/library/httpd:dns ports: - containerPort: 802.运行Podkubectl apply -f pod-web-multus-pool.yml kubectl get pod multus-web-pool -o wide kubectl describe pod multus-web-pool3.测试网络连通性curl 192.168.7.200三.网络策略——NetworkPolicy说明一组白名单规则用来规定“哪些 Pod 可以访问哪些 Pod 的哪些端口”。核心是Ingress(访问规则)和Engress出站规则核心模型1.默认全通K8s 默认没有任何隔离所有 Pod 可以互相访问所有 Pod 可以访问所有 Service所有 Pod 可以出外网。2.被选中才受限NetworkPolicy 用podSelector选中一组 Pod选中的 Pod → 进入“默认拒绝 白名单”模式没选中的 Pod → 仍然全通。3.一旦声明方向该方向默认拒绝3.1限制Pod流量1.编写yaml文件vim networkpolicy-test1.yml添加以下内容apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: networkpolicy-test1 namespace: default spec: podSelector: #筛选Pod matchLabels: app: web policyTypes: - Ingress #定义该Pod的入站流量规则一旦定义默认该Pod的入站流量都被拒绝除了Ingress的规则 ingress: #Ingress白名单规则 - from: - podSelector: matchLabels: run: test #只允许带有 runtest 标签的 Pod 访问appweb的Pod。 ports: - protocol: TCP port: 802.创建策略kubectl apply -f networkpolicy-test1.yml kubectl get networkpolicy networkpolicy-test1 kubectl describe networkpolicy networkpolicy-test13.测试3.1创建带有appweb标签的httpdPodkubectl apply -f pod-web.yml kubectl get pod webserver -o wide --show-labels3.2使用busybox访问该Pod说明由于没有配对Ingress白名单中的标签所以无法访问到webserverkubectl run demo --image reg.westos.org/library/busyboxplus -it --rm #运行并进入容器 curl 10.244.219.55 #访问Pod主要原因标签不匹配3.3修改demo的Pod标签为 runtest 标签后访问webserverkubectl label pod demo runtest --overwrite #修改标签 kubectl get pod demo --show-labels访问Pod:curl 10.244.219.553.2限制namespace流量1.编写yaml文件vim networkpolicy-test2添加以下内容apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: networkpolicy-test2 namespace: default spec: podSelector: matchLabels: app: web1 #限制这个Pod policyTypes: - Ingress #限制Pod的进站流量规则 ingress: - from: #这里使用的是两个 - 表示满足其一个条件都可以访问Pod - namespaceSelector: matchLabels: project: test #允许带有projecttest标签的namespace访问这个Pod - podSelector: matchLabels: run: test ##允许带有runtest标签的Pod访问这个Pod ports: - protocol: TCP port: 802.创建策略kubectl delete -f networkpolicy-test1.yml kubectl create -f networkpolicy-test2.yml kubectl describe networkpolicy networkpolicy-test23.访问Pod3.1创建test命名空间说明如果是私有项目需要配置secretkubectl create ns test3.2为命名空间添加标签kubectl label ns test projecttest kubectl get ns test --show-labels3.3测试创建podkubectl apply -f deploy-web1.yml kubectl get pod web1 -o wide --show-labels1.直接访问curl 10.244.219.612.使用test命名空间访问kubectl run demo --image reg.westos.org/library/busyboxplus -it --rm -n test curl 10.244.219.613.使用带有 run test的标签访问kubectl run test --image reg.westos.org/library/busyboxplus -it --rm -n default #使用default命名空间 curl 10.244.219.61 kubectl get pod test --show-labels3.3同时限制Pod和Namespace1.创建yaml文件vim networkpolicy-test3.yml添加以下内容apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: networkpolicy-test3 namespace: default spec: podSelector: matchLabels: app: web2 policyTypes: - Ingress ingress: #需要同时满足namespace和Pod的要求 - from: - namespaceSelector: matchLabels: project: test podSelector: matchLabels: run: test ports: - protocol: TCP port: 802.创建策略kubectl delete -f networkpolicy-test2.yml kubectl apply -f networkpolicy-test3.yml kubectl describe networkpolicy networkpolicy-test33.测试运行Podkubectl apply -f deploy-web2.yml kubectl get pod web2 --show-labels -o wide1.使用test命名空间访问kubectl run demo --image reg.westos.org/library/busyboxplus -it --rm -n test curl 10.244.219.12.使用标签 run:test访问kubectl run test --image reg.westos.org/library/busyboxplus -it --rm -n default curl 10.244.219.13.同时使用命名空间和标签访问kubectl run test --image reg.westos.org/library/busyboxplus -it --rm -n test curl 10.244.219.13.4限制集群外部流量说明对集群外部的网络流量加以限制。Ingress-from是入站egress-to是出站。1.编写yaml文件vim networkpolicy-test4.yml添加以下内容apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: networkpolicy-test4 namespace: default spec: podSelector: matchLabels: app: web policyTypes: - Ingress ingress: - from: - ipBlock: cidr: 192.168.7.0/24 #允许192.168.7.0/24网段的流量进入 except: - 192.168.7.161/32 #除了192.168.7.161这个网段 - ipBlock: cidr: 10.244.0.0/16 #允许集群内部访问该Pod - namespaceSelector: matchLabels: project: test podSelector: matchLabels: run: test ports: - protocol: TCP port: 802.创建策略kubectl delete -f networkpolicy-test3.yml kubectl apply -f networkpolicy-test4.yml kubectl describe networkpolicy networkpolicy-test43.测试说明Local模式能够将外部访问的VIP直接发送到Pod所在的节点上不需要使用kube-proxy做二次转发。1.创建Podkubectl apply -f pod-web.yml kubectl get pod webserver -o wide --show-labels kubectl apply -f service-web-lb.yml kubectl get svc web-service-lb kubectl get endpointslice web-service-lb-t8qm9 kubectl patch svc web-service-lb -n default -p {spec:{externalTrafficPolicy:Local}}2.使用 192.168.7.161主机访问该Podcurl 192.168.7.1003.使用网段中的其他主机访问Podcurl 192.168.7.100