打赏 jQuery火箭图标返回顶部代码

NetworkPolicy

在Kubernetes中,网络隔离功能是通过叫NetworkPolicy的API对象来描述的。

如下一个完整的NetworkPolicy定义:

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

解释:

  • podSelector:定义这个NetworkPolicy的限制范围,上面就是定义namespace中标签为role: db的Pod,如果为空,则标识这个namespace下的所有Pod,如果一旦被podSelector选中,则这个Pod就会进入拒绝所有的状态,即这个Pod既不允许被外界访问,也不能对外界发起访问。
  • policyTypes:定义NetworkPolicy的类型,ingress表示流入请求,egress表示流出请求。
  • ingress:定义流入的规则
  • egress:定义流出的规则

其中ingress字段中的from和ports,定义允许流入的白名单和端口,这里面的白名单有三种限制方式:

  • ipBlock:限制IP,上面定义的即为允许172.17.0.0/16但不是172.17.1.0/24的网段请求;
  • namespaceSelector:限制namespace,上面定义即为允许default namespace下标签为project: myproject的的Pod请求;
  • podSelector:限制Pod,上面定义即为允许标签为role: frontend的Pod请求;

而egress字段中的to和ports,则指定允许流出的白名单和端口,这里的限制方式和ingress类似。

注意:下面这两种白名单的定义方式是不一样的。

(1)、第一种

  ...
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          user: alice
    - podSelector:
        matchLabels:
          role: client
  ...

(2)、第二种

...
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          user: alice
      podSelector:
        matchLabels:
          role: client
  ...

这两种看起来类似,但是其表示的意义是不一样的,对于第一种表示的是一种OR(或)的关系,对于这种情况只要其中一种规则满足要求都可以通过,而对于第二种则表示AND(与)的关系,必须两种同时满足才会通过。

Kubernetes对Pod的网络隔离其实是靠宿主机上生成NetworkPolicy对应的iptables规则来实现的。

比如定义好了上面的NetworkPolicy,那么就会生成类似下面的iptables规则:

iptables -A KUBE-NWPLCY-CHAIN -s $srcIP -d $dstIP -p $protocol -m $protocol --dport $port -j ACCEPT 

其中:

  • srcIP:原IP
  • dstIP:目的IP
  • protocol:协议
  • port:端口

这些参数都是从我们定义的NetworkPolicy中取出来,然后还将对所有对被隔离Pod的访问请求都转发到KUBE-NWPLCY-CHAIN上去匹配,如果匹配不通过则拒绝。

第一组KUBE-NWPLCY-CHAIN规则如下:

iptables -A FORWARD -d $podIP -m physdev --physdev-is-bridged -j KUBE-POD-SPECIFIC-FW-CHAIN
iptables -A FORWARD -d $podIP -j KUBE-POD-SPECIFIC-FW-CHAIN

其中:

  • 第一条FORWARD链的作用是通过本机网桥设备发往podIP的IP包;
  • 第二条就是拦截跨主机通信,定义规则都到KUBE-POD-SPECIFIC-FW-CHAIN规则上

第二组KUBE-POD-SPECIFIC-FW-CHAIN规则如下:

iptables -A KUBE-POD-SPECIFIC-FW-CHAIN -j KUBE-NWPLCY-CHAIN
iptables -A KUBE-POD-SPECIFIC-FW-CHAIN -j REJECT --reject-with icmp-port-unreachable

其中:

  • 第一条是把数据包发到KUBE-NWPLCY-CHAIN去匹配;
  • 第二条就是把不满足NetworkPolicy中定义的请求都拒绝掉,从而实现对容器的隔离;

默认的Policies:

(1)、默认拒绝所有Ingress:

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

(2)、默认允许所有ingress:

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

(3)、默认拒绝所有Egress:

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

(4)、默认允许所有Egress:

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

(5)、拒绝所有Ingress和Egress:

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

例子:

1、创建两个namespace

kubectl create ns dev
kubectl create ns sit

2、给dev下的所有pod配置Ingress权限,不允许所有人访问

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: networkpolicy-ingress-demo
spec:
  podSelector: {}
  policyTypes:
  - Ingress

然后使其作用于dev

kubectl apply -f ingress-demo.yaml -n dev

我们在dev里创建一个Pod,在外部访问查看情况

apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
  - name: myapp
    image: nginx:1.7.9
    imagePullPolicy: IfNotPresent
    command:
    - "/bin/sh"
    - "-c"
    args:
    - "nginx && sleep 3600"

启动Pod

kubectl apply -f pod-demo.yaml -n dev
posted @ 2020-12-07 13:01  浪漫De刺猬  阅读(218)  评论(0编辑  收藏  举报