四、固定ip地址到pod

1、确认环境

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: myapp
  annotations:
    "cni.projectcalico.org/ipAddrs": '["10.244.140.67"]'
  name: myapp-ip
  namespace: default
spec:
  containers:
  - image: wangyanglinux/myapp:v1.0
    imagePullPolicy: IfNotPresent
    name: myapp

2、总结

五、NetworkPolicy

1、网络策略

 2、前置条件

3、默认策略

默认情况下,如果名字空间中不存在任何策略,则所有进出该名字空间中 Pod 的流量都被允许。 以下示 例使你可以更改该名字空间中的默认行为

1. 默认拒绝所有入站流量

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: <目标命名空间>  # 如 "default"
spec:
  podSelector: {}  # 匹配命名空间内所有 Pod
  policyTypes:
    - Ingress  # 仅控制入站流量
# 注:无 ingress 规则,默认拒绝所有入站流量

2. 允许所有入站流量

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-ingress
  namespace: <目标命名空间>
spec:
  podSelector: {}
  ingress:
    - {}  # 空规则表示允许所有入站流量
  policyTypes:
    - Ingress

3. 默认拒绝所有出站流量

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-egress
  namespace: <目标命名空间>
spec:
  podSelector: {}
  policyTypes:
    - Egress  # 仅控制出站流量
# 注:无 egress 规则,默认拒绝所有出站流量

4. 允许所有出站流量

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-egress
  namespace: <目标命名空间>
spec:
  podSelector: {}
  egress:
    - {}  # 空规则表示允许所有出站流量
  policyTypes:
    - Egress

5. 默认拒绝所有入站和所有出站流量 

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: <目标命名空间>
spec:
  podSelector: {}  # 匹配所有 Pod
  policyTypes:
    - Ingress  # 控制入站
    - Egress   # 控制出站
# 注:无 ingress/egress 规则,默认拒绝所有双向流量

4、基本语法

apiVersion: networking.k8s.io/v1  # K8s 网络策略标准 API 版本,文档中缺失部分已补全
kind: NetworkPolicy
metadata:
  name: <策略名称>  # 需自定义,如 "db-network-policy"
  namespace: <目标命名空间>  # 需自定义,如 "default"
spec:
  podSelector:  # 选择要应用此策略的 Pod(通过标签匹配)
    matchLabels:
      role: db  # 示例标签,如匹配 "role=db" 的 Pod
  policyTypes:  # 策略生效方向:Ingress(入站)、Egress(出站)
    - Ingress
    - Egress
  ingress:  # 入站流量规则(允许的流量来源和端口)
    - from:
        # 1. 允许指定 IP 段(排除特定子段)
        - ipBlock:
            cidr: 172.17.0.0/16  # 允许的 IP 段
            except:
              - 172.17.1.0/24  # 排除的子段
        # 2. 允许指定命名空间(通过标签匹配)
        - namespaceSelector:
            matchLabels:
              project: myproject  # 匹配 "project=myproject" 的命名空间下所有 Pod
        # 3. 允许指定 Pod(通过标签匹配,同命名空间)
        - podSelector:
            matchLabels:
              role: frontend  # 匹配 "role=frontend" 的 Pod
      ports:  # 允许的入站端口
        - protocol: TCP  # 协议类型(TCP/UDP/SCTP)
          port: 6379  # 允许的端口(如 Redis 默认端口)
  egress:  # 出站流量规则(允许的流量目的地和端口)
    - to:
        # 允许指定 IP 段
        - ipBlock:
            cidr: 10.0.0.0/24  # 允许访问的目标 IP 段
      ports:  # 允许的出站端口
        - protocol: TCP
          port: 5978  # 允许访问的目标端口

4.1 选择器 - to 和 from 的行为

NetworkPolicy 通过 ingress.from(入站来源)或 egress.to(出站目的地)定义流量匹配规则,支持三种选择器类型,可单独或组合使用:

  1. podSelector:匹配同命名空间内带指定标签的 Pod(如允许 "role=frontend" 的 Pod 访问目标 Pod)。
  2. namespaceSelector:匹配带指定标签的命名空间(该命名空间下所有 Pod 均被允许,跨命名空间生效)。
  3. ipBlock:匹配指定的 IP 段(支持 CIDR 格式,可排除子段)。
ingress:
  - from:
      - namespaceSelector:  # 先匹配命名空间
          matchLabels:
            user: alice
        podSelector:        # 再匹配该命名空间下的 Pod
                            #有-是或者,没-是并且
          matchLabels:
            role: client

4.3 针对某个端口范围(使用 endPort 字段)

通过 endPort 字段可允许连续端口范围(需 K8s 1.20+ 版本,特性为 Beta 级),需遵守以下限制:

  • endPort ≥ port(端口范围起始值 ≤ 结束值);
  • 仅当指定 port 时才能定义 endPort
  • 两者均需为数字(不支持命名端口)。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-port-range-egress
  namespace: <目标命名空间>
spec:
  podSelector:
    matchLabels:
      role: app  # 匹配 "role=app" 的 Pod
  policyTypes:
    - Egress
  egress:
    - to:
        - ipBlock:
            cidr: 10.0.0.0/24  # 目标 IP 段
      ports:
        - protocol: TCP
          port: 80        # 端口范围起始值
          endPort: 90     # 端口范围结束值(允许 80-90 所有 TCP 端口)

5、生产使用场景

1、允许指定的 Pod 访问

  1. 创建 Deployment

kubectl create deployment nginx --image=wangyanglinux/myapp:v1.0
  1. 暴露为 Service
kubectl expose deployment nginx --port=80

通过 Pod 测试服务访问(初始)

kubectl run busybox --rm -ti --image=busybox:1.28 /bin/sh
# 容器内执行访问测试
wget --spider --timeout=1 nginx

限制 Nginx 服务访问的 NetworkPolicy 资源清单

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: access-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - from:
    - podSelector:
        matchLabels:
          access: "true"

策略生效后测试(无标签 Pod 访问,应失败)

wget --spider --timeout=1 nginx

添加标签后访问(带 access=true 标签的 Pod 访问,应成功)

kubectl run busybox --rm -ti --labels="access=true" --image=busybox:1.28 -- /bin/sh
# 容器内执行访问测试
wget --spider --timeout=1 nginx

2、禁止访问指定服务

创建带标签的 Web 服务(Pod + Service)

bash

kubectl run web --image=wangyanglinux/myapp:v1.0 --labels app=web,env=prod --expose --port 80

2. 网络策略资源清单(web-deny-all

yaml

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: web-deny-all
spec:
  podSelector:
    matchLabels:
      app: web
      env: prod
  policyTypes:
    - Ingress  # 无入站规则,默认拒绝所有访问该 Pod 的入站流量

3、禁止 namespace 中所有 Pod 之间的相互访问

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: <目标命名空间>  # 如 "test-namespace"
spec:
  podSelector: {}  # 匹配命名空间内所有 Pod
  policyTypes:
    - Ingress  # 拒绝所有入站
    - Egress   # 拒绝所有出站
# 注:命名空间内所有 Pod 无法接收/发送任何流量

4、只允许指定命名空间访问 Web 服务

步骤 1:部署 Web 服务

# 创建 Web Deployment(标签 "app=web")
kubectl run web --image=wangyanglinux/myapp:v1.0 --labels="app=web" --expose --port=80

步骤 2:创建 NetworkPolicy(仅允许 "purpose=production" 命名空间访问)

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: web-allow-prod
  namespace: default  # Web 服务所在命名空间
spec:
  podSelector:
    matchLabels:
      app: web  # 匹配 Web Pod
  policyTypes:
    - Ingress
  ingress:
    - from:
        - namespaceSelector:
            matchLabels:
              purpose: production  # 仅允许 "purpose=production" 命名空间下所有 Pod 访问
      ports:
        - protocol: TCP
          port: 80  # Web 服务端口

6、注意

7、通过网络策略目前无法完成的

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐