在Kubernetes中,网络隔离功能是通过叫NetworkPolicy的API对象来描述的。 如下一个完整的NetworkPolicy定义:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: test-network-policy namespace: defaultspec: 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
解释:
其中ingress字段中的from和ports,定义允许流入的白名单和端口,这里面的白名单有三种限制方式:
而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
其中:
这些参数都是从我们定义的NetworkPolicy中取出来,然后还将对所有对被隔离Pod的访问请求都转发到KUBE-NWPLCY-CHAIN上去匹配,如果匹配不通过则拒绝。 第一组KUBE-NWPLCY-CHAIN规则如下:
iptables -A FORWARD -d $podIP -m physdev --physdev-is-bridged -j KUBE-POD-SPECIFIC-FW-CHAINiptables -A FORWARD -d $podIP -j KUBE-POD-SPECIFIC-FW-CHAIN
其中:
第二组KUBE-POD-SPECIFIC-FW-CHAIN规则如下:
iptables -A KUBE-POD-SPECIFIC-FW-CHAIN -j KUBE-NWPLCY-CHAINiptables -A KUBE-POD-SPECIFIC-FW-CHAIN -j REJECT --reject-with icmp-port-unreachable
其中:
默认的Policies: (1)、默认拒绝所有Ingress:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-denyspec: podSelector: {} policyTypes: - Ingress
(2)、默认允许所有ingress:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-allspec: podSelector: {} ingress: - {} policyTypes: - Ingress
(3)、默认拒绝所有Egress:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-denyspec: podSelector: {} policyTypes: - Egress
(4)、默认允许所有Egress:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: allow-allspec: podSelector: {} egress: - {} policyTypes: - Egress
(5)、拒绝所有Ingress和Egress:
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: default-denyspec: podSelector: {} policyTypes: - Ingress - Egress
例子: 1、创建两个namespace
# kubectl create ns dev# kubectl create ns sit
2、给dev下的所有pod配置Ingress权限,不允许所有人访问
apiVersion: networking.k8s.io/v1kind: NetworkPolicymetadata: name: networkpolicy-ingress-demospec: podSelector: {} policyTypes: - Ingress
然后使其作用于dev
# kubectl apply -f ingress-demo.yaml -n dev
我们在dev里创建一个Pod,在外部访问查看情况
apiVersion: v1kind: Podmetadata: name: myappspec: 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
完