• Namespace 隔离

默认情况下,所有 Pod 之间是全通的。每个 Namespace 可以配置独立的网络策略,来 隔离 Pod 之间的流量。

v1.7 + 版本通过创建匹配所有 Pod 的 Network Policy 来作为默认的网络策略

  • 默认拒绝所有 Pod 之间 Ingress 通信

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
    name: default-deny
spec:
    podSelector: {}
    policyTypes:
    - Ingress
  • 默认拒绝所有 Pod 之间 Egress 通信的策略

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
    name: default-deny
spec:
    podSelector: {}
    policyTypes:
    - Egress
  • 默认拒绝所有 Pod 之间 Ingress 和 Egress 通信的策略

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
    name: default-deny
spec:
    podSelector: {}
    policyTypes:
    - Ingress
    - Egress
  • 默认允许所有 Pod 之间 Ingress 通信的策略

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
    name: allow-all
spec:
    podSelector: {}
    ingress:
    - {}
  • 默认允许所有 Pod 之间 Egress 通信的策略

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
    name: allow-all
spec:
    podSelector: {}
    egress:
    - {}
  • Pod 隔离

通过使用标签选择器(包括 namespaceSelector 和 podSelector)来控制 Pod 之间的流量。

允许 default namespace 中带有 role=frontend 标签的 Pod 访问 default
namespace 中带有 role=db 标签 Pod 的 6379 端口
允许带有 project=myprojects 标签的 namespace 中所有 Pod 访问 default
namespace 中带有 role=db 标签 Pod 的 6379 端口

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
    name: test-network-policy
    namespace: default
spec:
    podSelector:
        matchLabels:
            role: db
    ingress:
    - from:
        - namespaceSelector:
            matchLabels:
                project: myproject
        - podSelector:
            matchLabels:
                role: frontend
        ports:
        - protocol: tcp
            port: 6379
允许 default namespace 中带有 role=frontend 标签的 Pod 访问 default
namespace 中带有 role=db 标签 Pod 的 6379 端口
允许带有 project=myprojects 标签的 namespace 中所有 Pod 访问 default
namespace 中带有 role=db 标签 Pod 的 6379 端口
NetworkPolicy
238
允许 default namespace 中带有 role=db 标签的 Pod 访问 10.0.0.0/24 网段
的 TCP 5978 端口
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
    name: test-network-policy
    namespace: default
spec:
    podSelector:
        matchLabels:
            role: db
    policyTypes:
    - Ingress
    - Egress
    ingress:
    - from:
        - ipBlock:
            cidr: 172.17.0.0/16
            except:
            - 172.17.1.0/24
        - namespaceSelector:
            matchLabels:
                project: myproject
        - podSelector:
            matchLabels:
                role: frontend
        ports:
        - protocol: TCP
            port: 6379
    egress:
    - to:
        - ipBlock:
            cidr: 10.0.0.0/24
        ports:
        - protocol: TCP
            port: 5978
  • 例子

现在已经配置了一个nginx服务,访问端口是80,默认的状态是所有的pod都可以访问这个服务

$ kubectl get svc
NAME                TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
nginx-deployment    NodePort    10.102.52.246    <none>        80:31180/TCP   19d

启动一个busybox pod来访问nginx-deployment服务
$ kubectl exec -it pod/busybox-test -- sh
/ # wget --spider --timeout=1 nginx-deployment
Connecting to nginx-deployment (10.102.52.246:80)
remote file exists
/ #

现在给nginx-deployment服务配置network策略,使得pod无法访问这个服务 

$ cat default-deny.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}
  policyTypes:
  - Ingress

$ kubectl create -f default-deny.yaml
networkpolicy.networking.k8s.io/default-deny created

现在busybox的pod无法访问nginx-deployment服务了
$ kubectl exec -it pod/busybox-test -- sh
/ # wget --spider --timeout=1 nginx-deployment
Connecting to nginx-deployment (10.102.52.246:80)
wget: download timed out
/ # exit


查看networkpolicy
$ kubectl get networkpolicy
NAME           POD-SELECTOR   AGE
default-deny   <none>         102s

再创建一个运行带有 access=true 的 Pod 访问的网络策略:

表示所有带有 access=true label 的pods都可以访问nginx-deployment服务
$ cat nginx-policy.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: access-nginx
spec:
  podSelector:
    matchLabels:
      app: nginx
  ingress:
  - from:
    - podSelector:
        matchLabels:
          access: "true"


启动一个带有access=true label的busybox服务
$ cat busybox-test.yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    cni.projectcalico.org/containerID: fefc92be6bb04bacdf757a0b4132d72c2133c94dbfa684296cf59772817fc939
    cni.projectcalico.org/podIP: 172.16.43.1/32
    cni.projectcalico.org/podIPs: 172.16.43.1/32
  creationTimestamp: "2024-06-28T08:39:13Z"
  labels:
    access: "true"
    purpose: demonstrate-busybox
  name: busybox-test
  namespace: default
  resourceVersion: "208006"
  uid: 2d94690d-4f16-4bb6-a540-4682334170af
spec:
  containers:
  - command:
    - sleep
    - "3600"
    image: busybox
    imagePullPolicy: IfNotPresent
    name: busybox
    resources:
... ...


$ kubectl apply -f busybox-test.yaml

此时看到busybox-test这个pod已经带有access=true的label了
$ kubectl describe pod busybox-test
Name:             busybox-test
Namespace:        default
Priority:         0
Service Account:  default
Node:             kevin-pc/192.168.227.129
Start Time:       Fri, 28 Jun 2024 16:39:13 +0800
Labels:           access=true


然后通过busybox-test访问nginx服务就可以访问到了
$ kubectl exec -it pod/busybox-test -- sh
/ # wget --spider -timeout=1 nginx-deployment
Connecting to nginx-deployment (10.102.52.246:80)
remote file exists
/ #
  • 删除networkpolicy

删除networkpolicy之后,所有的pod默认都可以访问nginx-deployment服务了 

$ kubectl get networkpolicy
NAME           POD-SELECTOR   AGE
access-nginx   app=nginx      10m
default-deny   <none>         17m
$ kubectl delete network policy access-nginx
  • 几种访问策略的配置例子

  • 禁止访问指定服务 

首先启动一个nginx服务,并且给这个服务打上label

kubectl run web --image=nginx --labels app=web,env=prod --expose --po
rt 80

(没有配置ingress,所以所有的pod都没法访问这个服务)
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
    name: web-deny-all
spec:
    podSelector:
        matchLabels:
            app: web
            env: prod
  • 只允许指定 Pod 访问服务

kubectl run apiserver --image=nginx --labels app=bookstore,role=api -
-expose --port 80

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
    name: api-allow
spec:
    podSelector:
        matchLabels:
            app: bookstore
            role: api
    ingress:
    - from:
        - podSelector:
            matchLabels:
                app: bookstore
  •  禁止 namespace 中所有 Pod 之间的相互访问

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
    name: default-deny
    namespace: default
spec:
    podSelector: {}
  • 禁止其他 namespace 访问服务

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
    namespace: default
    name: web-deny-other-namespaces
spec:
    podSelector:
        matchLabels:
    ingress:
    - from:
        - podSelector: {}
  •  只允许指定 namespace 访问服务

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
    name: web-allow-prod
spec:
    podSelector:
        matchLabels:
            app: web
    ingress:
    - from:
        - namespaceSelector:
            matchLabels:
                purpose: production
  •  允许外网访问服务

kubectl run web --image=nginx --labels=app=web --port 80
kubectl expose deployment/web --type=LoadBalancer

kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
    name: web-allow-external
spec:
    podSelector:
        matchLabels:
            app: web
    ingress:
    - ports:
        - port: 80
        from: []

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部