Kubernetes网络隔离NetworkPolicy实验

前言

Kubernetes的一个重要特性就是要把不同node节点的pod(container)连接起来,无视物理节点的限制。但是在某些应用环境中,比如公有云,不同租户的pod不应该互通,这个时候就需要网络隔离。幸好,Kubernetes提供了NetworkPolicy,支持按Namespace级别的网络隔离。Network Policy提供了基于策略的网络控制,用于隔离应用并减少攻击面。它使用标签选择器模拟传统的分段网络,并通过策略控制它们之间的流量以及来自外部的流量。

使用NetworkPolicy需要特定的网络解决方案,如果不启用,即使配置了NetworkPolicy也无济于事。

注意:

  • v1.6以及以前的版本需要在apiserver开启extensions/v1beta1/networkpolicies
  • v1.7+版本Network Policy已经GA,API版本为http://networking.k8s.io/v1
  • 网络插件要支持Network Policy,如Calico、Romana、Weave Net和trireme等
  • 还需要一些配置支持networkpolicy:
    • kubelet启用cni网络插件,即设置启动参数:–network-plugin=cni –cni-conf-dir=/etc/cni/net.d –cni-bin-dir=/opt/cni/bin(我的部署方式下配置这个文件:/etc/kubernetes/kubelet.env)
    • kube-proxy必须启用iptables代理模式,这是默认模式
    • kube-proxy不得启用–masquerade-all,这会跟calico冲突

实验环境

kubernetes1.8、calico2.6.2

实验步骤

1.创建两个namespace: ns-calico1、ns-calico2

2.分别在两个namespace下创建应用:

ns-calico1下面创建三个应用

ns-calico1下的calico1-busybox应用:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: calico1-busybox
  namespace: ns-calico1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        user: calico1
        app: calico1-busybox
    spec:
      containers:
      - name: calico1-busybox
        image: busybox
        imagePullPolicy: IfNotPresent
        command:
          - sleep
          - "3600"

ns-calico1下的calico1-nginx应用:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: calico1-nginx
  namespace: ns-calico1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        user: calico1
        app: calico1-nginx
    spec:
      containers:
      - name: calico1-nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: calico1-nginx
  namespace: ns-calico1
  labels:
    user: calico1
spec:
  selector:
    app: calico1-nginx
  ports:
  - port: 80

ns-calico1下的calico1-nginx2应用:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: calico1-nginx2
  namespace: ns-calico1
spec:
  replicas: 1
  template:
    metadata:
      labels:
        user: calico1
        app: calico1-nginx2
    spec:
      containers:
      - name: calico1-nginx2
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: calico1-nginx2
  namespace: ns-calico1
  labels:
    user: calico1
spec:
  selector:
    app: calico1-nginx2
  ports:
  - port: 80

ns-calico2下面创建一个应用

ns-calico2下的calico2-busybox应用:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: calico2-busybox
  namespace: ns-calico2
spec:
  replicas: 1
  template:
    metadata:
      labels:
        user: calico2
        app: calico2-busybox
    spec:
      containers:
      - name: calico2-busybox
        image: busybox
        imagePullPolicy: IfNotPresent
        command:
          - sleep
          - "3600"

3.测试

3.1加策略前

测试结果

kubectl exec -it calico1-busybox-5f4d7d5f4-n7qjg -n ns-calico1 -- wget --spider --timeout=1 calico1-nginx.ns-calico1
Connecting to calico1-nginx.ns-calico1 (10.233.30.47:80)
通

kubectl exec -it calico2-busybox-6dd875d4f-8747j -n ns-calico2 -- wget --spider --timeout=1 calico1-nginx.ns-calico1
Connecting to calico1-nginx.ns-calico1 (10.233.30.47:80)
通

结论:加策略前,同namespace以及跨namespace的应用之间都是互通的

3.2加策略后,应用未打标签前

策略文件:

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

说明:该策略只允许有access: “true”标签的应用访问ns-calico1下面有app: calico1-nginx标签的应用,即我们的测试应用

测试结果

kubectl exec -it calico1-busybox-5f4d7d5f4-n7qjg -n ns-calico1 -- wget --spider --timeout=1 calico1-nginx.ns-calico1
Connecting to calico1-nginx.ns-calico1 (10.233.30.47:80)
wget: download timed out
不通

kubectl exec -it calico2-busybox-6dd875d4f-8747j -n ns-calico2 -- wget --spider --timeout=1 calico1-nginx.ns-calico1
Connecting to calico1-nginx.ns-calico1 (10.233.30.47:80)
wget: download timed out
不通

kubectl exec -it calico1-busybox-5f4d7d5f4-n7qjg -n ns-calico1 -- wget --spider --timeout=1 calico1-nginx2.ns-calico1
Connecting to calico1-nginx2.ns-calico1 (10.233.23.44:80)
通

kubectl exec -it calico2-busybox-6dd875d4f-8747j -n ns-calico2 -- wget --spider --timeout=1 calico1-nginx2.ns-calico1
Connecting to calico1-nginx2.ns-calico1 (10.233.23.44:80)
通

结论:
1.加上访问策略后,同namespace及跨namespace的应用都无法访问目标应用
2.对某个应用加上访问策略,该策略并不会影响对同namespace下的其他应用的访问

3.3加策略后,两个namespace的应用都打标签后

给两个namespace下的busybox应用都添加access: “true”的label
测试结果:

kubectl exec -it calico1-busybox-5f4d7d5f4-n7qjg -n ns-calico1 -- wget --spider --timeout=1 calico1-nginx.ns-calico1
Connecting to calico1-nginx.ns-calico1 (10.233.30.47:80)
通

kubectl exec -it calico2-busybox-6dd875d4f-8747j -n ns-calico2 -- wget --spider --timeout=1 calico1-nginx.ns-calico1
Connecting to calico1-nginx.ns-calico1 (10.233.30.47:80)
wget: download timed out
不通

结论:只有同namespace下的应用打上对应标签才通,跨namespace的应用打上标签也无法访问

附录,常见策略示例:

1.默认拒绝所有Pod之间通信

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
  namespace: ns-calico1
spec:
  podSelector:

说明:加上后,无论是从同namespace内还是跨namespace访问都不通

2.默认允许所有Pod通信的策略为

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector:
  ingress:
  - {}

3.
(1)允许default namespace中带有role=frontend标签的Pod访问default namespace中带有role=db标签Pod的6379端口
(2)允许带有project=myprojects标签的namespace中所有Pod访问default namespace中带有role=db标签Pod的6379端口

# apiVersion: extensions/v1beta1
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

参考:

1.http://blog.csdn.net/qq_34463875/article/details/74288175
2.https://zhuanlan.zhihu.com/p/27699958

猜你喜欢

转载自blog.csdn.net/liukuan73/article/details/78651942