目录
[一.认识Multus CNI](#一.认识Multus CNI)
[1.1什么是Multus CNI](#1.1什么是Multus CNI)
[2.6创建多网络接口 Pod](#2.6创建多网络接口 Pod)
一.认识Multus CNI
1.1什么是Multus CNI
1.概念:Multus CNI 是一个用于 Kubernetes 的多网络插件(Multi-Network Plugin) ,它的核心作用是让一个 Pod 能够同时接入多个网络接口。
默认k8s集群使用的主要网卡是eth0,apiserver,probe和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提供额外的网络接口,用于实现高并发等需求。
二.部署Multus
2.1下载yaml配置文件
bash
wget https://raw.githubusercontent.com/k8snetworkplumbingwg/multus-cni/master/deployments/multus-daemonset.yml

2.2下载镜像文件
1.下载镜像
bash
docker pull ghcr.io/k8snetworkplumbingwg/multus-cni:snapshot
2.上传镜像到harbar
bash
docker tag ghcr.io/k8snetworkplumbingwg/multus-cni:snapshot reg.westos.org/multus/multus-cni:snapshot
docker push reg.westos.org/multus/multus-cni:snapshot
2.3修改yaml文件
bash
vim multus-daemonset.yml
修改镜像地址为下面的内容:
bash
image: reg.westos.org/multus/multus-cni:snapshot

bash
image: reg.westos.org/multus/multus-cni:snapshot

2.4部署Multus
bash
kubectl apply -f multus-daemonset.yml

bash
kubectl get pod -n kube-system -l app=multus
说明:multus以daemonent形式部署,要求集群中的所有节点都要运行。k8s1上没有运行是因为自身节点存在污点,k8s1不会进行调度。

2.5创建macvlan从网络(静态网络)
说明 :macvlan 允许在一张物理网卡上创建多个"虚拟子接口",每个子接口有自己独立的 MAC 地址和 IP,在网络上看起来就像一台独立的物理机器。
1.编辑yaml文件
bash
vim macvlan-static.yml
添加以下内容:
bash
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.运行从网络
bash
kubectl apply -f macvlan-static.yml
kubectl get networkattachmentdefinition.k8s.cni.cncf.io/macvlan-static
kubectl describe


2.6创建多网络接口 Pod
说明 :为Pod配置刚才的从网络接口,除了默认 CNI 给的 eth0,再按名字 macvlan-static 找到对应的 NetworkAttachmentDefinition,给 Pod 额外挂一张网卡。
1.编写yaml文件
bash
vim pod-web-multus-static.yml
添加以下内容:
bash
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: 80

2.运行Pod
bash
kubectl create -f pod-web-multus-static.yml
kubectl get pod multus-web -o wide
kubectl describe pod multus-web


3.测试连通性
说明:由于 macvlan绑定eth0后 破坏了宿主机和vxlan隧道之间的通信,所以使用Cluster IP无法访问到Pod,选择的独立网卡,不会影响Cluster IP的Pod访问
bash
curl 192.168.7.10 #从网络上分配的IP
curl 10.244.219.57 #访问Cluster IP


2.7创建macvlan-pool网络池(自动分配)
说明 :配置单一macvlan网络比较麻烦,创建pool网络池,当有新的Pod被创建后,会从网络池中自动分配网路给新Pod
1. 编写yaml文件
bash
vim macvlan-pool.yml
添加以下内容:
bash
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.关闭静态分配网络,运行自动分配网络
bash
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-pool



2.8自动分配IP
1.编写yaml文件
bash
vim pod-web-multus-pool.yml
添加以下内容:
bash
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: 80

2.运行Pod
bash
kubectl apply -f pod-web-multus-pool.yml
kubectl get pod multus-web-pool -o wide
kubectl describe pod multus-web-pool


3.测试网络连通性
bash
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文件
bash
vim networkpolicy-test1.yml
添加以下内容:
bash
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 #只允许带有 run=test 标签的 Pod 访问app=web的Pod。
ports:
- protocol: TCP
port: 80

2.创建策略
bash
kubectl apply -f networkpolicy-test1.yml
kubectl get networkpolicy networkpolicy-test1
kubectl describe networkpolicy networkpolicy-test1


3.测试
3.1创建带有app=web标签的httpdPod
bash
kubectl apply -f pod-web.yml
kubectl get pod webserver -o wide --show-labels

3.2使用busybox访问该Pod
说明:由于没有配对Ingress白名单中的标签,所以无法访问到webserver
bash
kubectl run demo --image reg.westos.org/library/busyboxplus -it --rm #运行并进入容器
curl 10.244.219.55 #访问Pod

主要原因:标签不匹配

3.3修改demo的Pod标签为 run=test 标签后,访问webserver
bash
kubectl label pod demo run=test --overwrite #修改标签
kubectl get pod demo --show-labels

访问Pod:
bash
curl 10.244.219.55

3.2限制namespace流量
1.编写yaml文件
bash
vim networkpolicy-test2
添加以下内容:
bash
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 #允许带有project=test标签的namespace访问这个Pod
- podSelector:
matchLabels:
run: test ##允许带有run=test标签的Pod访问这个Pod
ports:
- protocol: TCP
port: 80

2.创建策略
bash
kubectl delete -f networkpolicy-test1.yml
kubectl create -f networkpolicy-test2.yml
kubectl describe networkpolicy networkpolicy-test2

3.访问Pod
3.1创建test命名空间
说明:如果是私有项目,需要配置secret
bash
kubectl create ns test

3.2为命名空间添加标签
bash
kubectl label ns test project=test
kubectl get ns test --show-labels

3.3测试
创建pod
bash
kubectl apply -f deploy-web1.yml
kubectl get pod web1 -o wide --show-labels

1.直接访问
bash
curl 10.244.219.61

2.使用test命名空间访问
bash
kubectl run demo --image reg.westos.org/library/busyboxplus -it --rm -n test
curl 10.244.219.61

3.使用带有 run = test的标签访问
bash
kubectl run test --image reg.westos.org/library/busyboxplus -it --rm -n default #使用default命名空间
curl 10.244.219.61
kubectl get pod test --show-labels


3.3同时限制Pod和Namespace
1.创建yaml文件
bash
vim networkpolicy-test3.yml
添加以下内容:
bash
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: 80

2.创建策略
bash
kubectl delete -f networkpolicy-test2.yml
kubectl apply -f networkpolicy-test3.yml
kubectl describe networkpolicy networkpolicy-test3

3.测试
运行Pod
bash
kubectl apply -f deploy-web2.yml
kubectl get pod web2 --show-labels -o wide


1.使用test命名空间访问
bash
kubectl run demo --image reg.westos.org/library/busyboxplus -it --rm -n test
curl 10.244.219.1

2.使用标签 run:test访问
bash
kubectl run test --image reg.westos.org/library/busyboxplus -it --rm -n default
curl 10.244.219.1

3.同时使用命名空间和标签访问
bash
kubectl run test --image reg.westos.org/library/busyboxplus -it --rm -n test
curl 10.244.219.1

3.4限制集群外部流量
说明:对集群外部的网络流量加以限制。Ingress-from是入站,egress-to是出站。
1.编写yaml文件
bash
vim networkpolicy-test4.yml
添加以下内容:
bash
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: 80

2.创建策略
bash
kubectl delete -f networkpolicy-test3.yml
kubectl apply -f networkpolicy-test4.yml
kubectl describe networkpolicy networkpolicy-test4

3.测试
说明:Local模式能够将外部访问的VIP直接发送到Pod所在的节点上,不需要使用kube-proxy做二次转发。
1.创建Pod
bash
kubectl 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主机访问该Pod
bash
curl 192.168.7.100


3.使用网段中的其他主机访问Pod
bash
curl 192.168.7.100
