Kubernetes集群——网络管理

目录

[一.认识Multus CNI](#一.认识Multus CNI)

[1.1什么是Multus CNI](#1.1什么是Multus CNI)

1.2核心价值

1.3工作原理

二.部署Multus

2.1下载yaml配置文件

2.2下载镜像文件

2.3修改yaml文件

2.4部署Multus

2.5创建macvlan从网络(静态网络)

[2.6创建多网络接口 Pod](#2.6创建多网络接口 Pod)

2.7创建macvlan-pool网络池(自动分配)

2.8自动分配IP

三.网络策略------NetworkPolicy

3.1限制Pod流量

3.2限制namespace流量

3.3同时限制Pod和Namespace

3.4限制集群外部流量


一.认识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
相关推荐
做一个AK梦1 小时前
云原生服务网格
云原生
java_logo3 小时前
Docker 部署 Portainer CE:轻松搭建容器管理平台
运维·docker·容器·portainer·容器管理·轩辕镜像·portainer-ce
阿里云云原生9 小时前
AI 语音一直“正在连接”?用 RUM 排查 WebSocket 建连问题
云原生
阿里云云原生17 小时前
从页面渲染到智能体:ARMS Node.js 探针解锁 SSR + AI 全链路可观测
云原生
程序员老赵20 小时前
Docker 部署 Portainer CE:轻松搭建容器管理平台
docker·容器·开源
大侠归来21 小时前
Docker 部署 Dolibarr:从零开始的完整指南
运维·docker·容器
七月吃橘子21 小时前
WSL2+Docker+Ollama,本地部署大模型实践(Qwen1.8b)
运维·docker·容器
Nontee1 天前
K3s vs K8s:差的不是功能,是交付方式
云原生·容器·kubernetes