【原】k8s-网络策略

k8s NetworkPolicy

demo 示例

---
# Source: tests/busybox.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: busybox
  name: busybox
spec:
  containers:
  - name: busybox
    # 确保使用 busybox:1.28 image(或更早版本)进行任何测试,最新版本有一个unpstream bug,影响nslookup的使用
    #image: busybox:1.28
    # 如下镜像含有 curl,git,telnet,nslookup 命令
    image: radial/busyboxplus
    command:
      - sleep
      - "3600"
    imagePullPolicy: IfNotPresent
  restartPolicy: Always
---
# Source: tests/myapp-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: myapp
  name: myapp
spec:
  replicas: 1
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: ikubernetes/myapp:v1
        resources: {}
        ports:
        - name: http
          containerPort: 80
      dnsPolicy: ClusterFirst
      restartPolicy: Always
---
# Source: tests/myapp-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: myapp
  name: myapp
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: myapp
---
# Source: tests/myapp-ingress.yaml
#apiVersion: extensions/v1beta1
#kind: Ingress
#metadata:
#  name: ingress-myapp
#  labels:
#    app: myapp
#  annotations:
#    kubernetes.io/ingress.class: "nginx"
#spec:
#  rules:
#  - host: myapp.5179.top
#    http:
#      paths:
#      - path: /
#        backend:
#          serviceName: myapp
#          servicePort: 80

执行

kubectl apply -f demo.yaml
kubectl apply -f demo.yaml -n test
kubectl apply -f demo.yaml -n kube-system

通过进入不同 namespace 的 busybox 的 pod 进行验证

[root@centos7-nginx ~]# kubectl exec -it busybox -- sh
/ # nslookup myapp
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      myapp
Address 1: 10.103.12.181 myapp.default.svc.cluster.local
/ # curl myapp/hostname.html
myapp-5cbd66595b-sgqpg
/ #

1.默认禁止任何客户端访问该 Namespace 中的所有 Pod

默认拒绝:当在spec.policyTypes中指定规则类型,却在networkpolicy.spec中没有定义任何ingressegress 字段时,将拒绝相关方向上一切流量!

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}  # 匹配所有Pod
  policyTypes:
  - Ingress

2.默认允许任何客户端访问该 Namespace 中的所有 Pod

默认允许:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector: {}  # 匹配所有Pod
  ingress:
  - {}
  policyTypes:
  - Ingress

3.默认禁止该 Namespace 中的所有 Pod 访问外部服务:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}  # 匹配所有Pod
  policyTypes:
  - Egress

4.默认允许该 Namespace 中的所有 Pod 访问外部服务

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector: {}  # 匹配所有Pod
  egress:
  - {}
  policyTypes:
  - Egress

5.默认禁止任何客户端访问该 Namespace 中的所有 Pod ,同时禁止访问外部服务

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny
spec:
  podSelector: {}  # 匹配所有Pod
  policyTypes:
  - Ingress
  - Egress

6.隔离Namespace, 放行与kube-system名称空间中Pod的通信,以实现监控和名称解析等各种管理功能

需要先给 ns 打上类似这样的标签,kubectl label ns test name=test

# 一条命令给所有 namespace 打上标签
[root@centos7-nginx ~]# kubectl get ns --show-labels |grep -v NAME |awk '{print $1}' |xargs -I {} kubectl label namespace {} name={}

[root@centos7-nginx ~]# kubectl get ns --show-labels
NAME              STATUS   AGE     LABELS
default           Active   3d17h   name=default
ingress-nginx     Active   22h     app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx,name=ingress-nginx
kube-node-lease   Active   3d17h   name=kube-node-lease
kube-public       Active   3d17h   name=kube-public
kube-system       Active   3d17h   name=kube-system
test              Active   23h     name=test

修改文件

# 先禁出所有
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: namespace-deny-all
  namespace: default
spec:
  policyTypes: ["Ingress","Egress"]
  podSelector: {}
---
# 放行对应 Namespace 的流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: namespace-
  namespace: default
spec:
  policyTypes: ["Ingress","Egress"]
  podSelector: {}
  ingress:
  - from:
    - namespaceSelector:
        matchExpressions:  # matchExpressions是标签选择器要求的列表。
        - key: name
          operator: In
          values: ["default","kube-system","ingress-nginx","monitoring"]
  egress:
  - to:
    - namespaceSelector:
        matchExpressions:
        - key: name
          operator: In
          values: ["default","kube-system","ingress-nginx","monitoring"]

注意:

  • matchExpressions 是标签选择器要求的列表。
  • matchLabels{key,value} 对的映射。matchLabels映射中的单个 {key,value}等同于matchExpressions的元素,其key字段为key,运算符为In,而 values 数组仅包含 value

查看策略

[root@centos7-nginx policy]# kubectl describe netpol namespace-deny-all -n test
Name:         namespace-deny-all
Namespace:    test
Created on:   2020-07-06 17:09:06 +0800 CST
Labels:       <none>
Annotations:  Spec:
  PodSelector:     <none> (Allowing the specific traffic to all pods in this namespace)
  Allowing ingress traffic:
    <none> (Selected pods are isolated for ingress connectivity)
  Allowing egress traffic:
    <none> (Selected pods are isolated for egress connectivity)
  Policy Types: Ingress, Egress

[root@centos7-nginx policy]# kubectl describe netpol namespace-allow-some-ns -n test
Name:         namespace-allow-some-ns
Namespace:    test
Created on:   2020-07-06 17:09:06 +0800 CST
Labels:       <none>
Annotations:  Spec:
  PodSelector:     <none> (Allowing the specific traffic to all pods in this namespace)
  Allowing ingress traffic:
    To Port: <any> (traffic allowed to all ports)
    From:
      NamespaceSelector: name in (ingress-nginx,kube-system,monitoring,test)
  Allowing egress traffic:
    To Port: <any> (traffic allowed to all ports)
    To:
      NamespaceSelector: name in (ingress-nginx,kube-system,monitoring,test)
  Policy Types: Ingress, Egress

7.隔离 Namespace, 限制入方向

# 先禁止所有入方向的流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: namespace-deny-all
  namespace: test
spec:
  policyTypes: ["Ingress"]
  podSelector: {}
---
# 放行对应 Namespace 入方向的流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: namespace-allow-some-ns
  namespace: test
spec:
  policyTypes: ["Ingress"]
  podSelector: {}
  ingress:
  - from:
    - namespaceSelector:
        matchExpressions:
        - key: name
          operator: In
          values: ["test","kube-system","ingress-nginx","monitoring"]

8.示例

放行特定入站流量

仅定义from将隐含允许本地Pod所有端口;仅定义ports将隐含允许所有源端点;同时定义fromports时,是逻辑与关系
多个from之间是逻辑或关系
多个ports之间是逻辑或关系
fromports间是逻辑与关系
from ipBlocknamespaceSelectorpodSelector同时使用多个时,为逻辑或关系

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-myapp-ingress
  name: default
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes: ["Ingress"]
  ingress:
  - from:
    - ipBlock:
        cidr: 10.244.0.0/16
        except:
        - 10.244.3.0/24
    - podSelector:
        matchLabels:
          app: myapp
    ports:
    - protocol: TCP
      port: 80

管控出站流量

# 默认出方向拒绝所有
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
spec:
  podSelector: {}
  policyTypes: ["Egress"]
# 放行特定的出站流量
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-tomcat-egress
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: tomcat
  policyTypes: ["Egress"]
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: nginx
  - ports:
    - protocol: TCP
      port: 80
  - to:
    - podSelector:
        matchLabels:
          app: mysql
    ports:
    - protocol: TCP
      port: 3306
posted @ 2020-07-07 13:37  liyongjian5179  阅读(290)  评论(0编辑  收藏  举报