기술나눔

k8s 네트워크 정책

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

  • 네임스페이스 격리

기본적으로 모든 Pod는 완전히 액세스할 수 있습니다. 각 네임스페이스는 독립적인 네트워크 정책으로 구성되어 포드 간의 트래픽을 격리할 수 있습니다.

v1.7+는 모든 포드와 일치하는 네트워크 정책을 생성하여 기본 네트워크 정책 역할을 합니다.

  • 모든 포드 간의 인그레스 통신은 기본적으로 거부됩니다.

  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4. name: default-deny
  5. spec:
  6. podSelector: {}
  7. policyTypes:
  8. - Ingress
  • 기본적으로 모든 Pod 간의 송신 통신을 거부하는 정책

  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4. name: default-deny
  5. spec:
  6. podSelector: {}
  7. policyTypes:
  8. - Egress
  • 기본적으로 모든 Pod 간의 Ingress 및 Egress 통신을 거부하는 정책

  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4. name: default-deny
  5. spec:
  6. podSelector: {}
  7. policyTypes:
  8. - Ingress
  9. - Egress
  • 기본적으로 모든 Pod 간의 Ingress 통신을 허용하는 정책

  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4. name: allow-all
  5. spec:
  6. podSelector: {}
  7. ingress:
  8. - {}
  • 기본적으로 모든 Pod 간의 송신 통신을 허용하는 정책

  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4. name: allow-all
  5. spec:
  6. podSelector: {}
  7. egress:
  8. - {}
  • 포드 격리

네임스페이스선택기 및 podSelector를 포함한 라벨 선택기를 사용하여 포드 간의 트래픽을 제어합니다.

  1. 允许 default namespace 中带有 role=frontend 标签的 Pod 访问 default
  2. namespace 中带有 role=db 标签 Pod 的 6379 端口
  3. 允许带有 project=myprojects 标签的 namespace 中所有 Pod 访问 default
  4. namespace 中带有 role=db 标签 Pod 的 6379 端口
  5. apiVersion: networking.k8s.io/v1
  6. kind: NetworkPolicy
  7. metadata:
  8. name: test-network-policy
  9. namespace: default
  10. spec:
  11. podSelector:
  12. matchLabels:
  13. role: db
  14. ingress:
  15. - from:
  16. - namespaceSelector:
  17. matchLabels:
  18. project: myproject
  19. - podSelector:
  20. matchLabels:
  21. role: frontend
  22. ports:
  23. - protocol: tcp
  24. port: 6379
  1. 允许 default namespace 中带有 role=frontend 标签的 Pod 访问 default
  2. namespace 中带有 role=db 标签 Pod 的 6379 端口
  3. 允许带有 project=myprojects 标签的 namespace 中所有 Pod 访问 default
  4. namespace 中带有 role=db 标签 Pod 的 6379 端口
  5. NetworkPolicy
  6. 238
  7. 允许 default namespace 中带有 role=db 标签的 Pod 访问 10.0.0.0/24 网段
  8. 的 TCP 5978 端口
  9. apiVersion: networking.k8s.io/v1
  10. kind: NetworkPolicy
  11. metadata:
  12. name: test-network-policy
  13. namespace: default
  14. spec:
  15. podSelector:
  16. matchLabels:
  17. role: db
  18. policyTypes:
  19. - Ingress
  20. - Egress
  21. ingress:
  22. - from:
  23. - ipBlock:
  24. cidr: 172.17.0.0/16
  25. except:
  26. - 172.17.1.0/24
  27. - namespaceSelector:
  28. matchLabels:
  29. project: myproject
  30. - podSelector:
  31. matchLabels:
  32. role: frontend
  33. ports:
  34. - protocol: TCP
  35. port: 6379
  36. egress:
  37. - to:
  38. - ipBlock:
  39. cidr: 10.0.0.0/24
  40. ports:
  41. - protocol: TCP
  42. port: 5978

이제 nginx 서비스가 구성되었습니다. 액세스 포트는 80입니다. 기본 상태는 모든 포드가 이 서비스에 액세스할 수 있다는 것입니다.

  1. $ kubectl get svc
  2. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  3. nginx-deployment NodePort 10.102.52.246 <none> 80:31180/TCP 19d
  4. 启动一个busybox pod来访问nginx-deployment服务
  5. $ kubectl exec -it pod/busybox-test -- sh
  6. / # wget --spider --timeout=1 nginx-deployment
  7. Connecting to nginx-deployment (10.102.52.246:80)
  8. remote file exists
  9. / #

이제 포드가 이 서비스에 액세스할 수 없도록 nginx-deployment 서비스에 대한 네트워크 정책을 구성합니다.

  1. $ cat default-deny.yaml
  2. apiVersion: networking.k8s.io/v1
  3. kind: NetworkPolicy
  4. metadata:
  5. name: default-deny
  6. spec:
  7. podSelector: {}
  8. policyTypes:
  9. - Ingress
  10. $ kubectl create -f default-deny.yaml
  11. networkpolicy.networking.k8s.io/default-deny created
  12. 现在busybox的pod无法访问nginx-deployment服务了
  13. $ kubectl exec -it pod/busybox-test -- sh
  14. / # wget --spider --timeout=1 nginx-deployment
  15. Connecting to nginx-deployment (10.102.52.246:80)
  16. wget: download timed out
  17. / # exit
  18. 查看networkpolicy
  19. $ kubectl get networkpolicy
  20. NAME POD-SELECTOR AGE
  21. default-deny <none> 102s

access=true로 Pod 액세스를 실행하는 다른 네트워크 정책을 만듭니다.

  1. 表示所有带有 access=true label 的pods都可以访问nginx-deployment服务
  2. $ cat nginx-policy.yaml
  3. apiVersion: networking.k8s.io/v1
  4. kind: NetworkPolicy
  5. metadata:
  6. name: access-nginx
  7. spec:
  8. podSelector:
  9. matchLabels:
  10. app: nginx
  11. ingress:
  12. - from:
  13. - podSelector:
  14. matchLabels:
  15. access: "true"
  16. 启动一个带有access=true label的busybox服务
  17. $ cat busybox-test.yaml
  18. apiVersion: v1
  19. kind: Pod
  20. metadata:
  21. annotations:
  22. cni.projectcalico.org/containerID: fefc92be6bb04bacdf757a0b4132d72c2133c94dbfa684296cf59772817fc939
  23. cni.projectcalico.org/podIP: 172.16.43.1/32
  24. cni.projectcalico.org/podIPs: 172.16.43.1/32
  25. creationTimestamp: "2024-06-28T08:39:13Z"
  26. labels:
  27. access: "true"
  28. purpose: demonstrate-busybox
  29. name: busybox-test
  30. namespace: default
  31. resourceVersion: "208006"
  32. uid: 2d94690d-4f16-4bb6-a540-4682334170af
  33. spec:
  34. containers:
  35. - command:
  36. - sleep
  37. - "3600"
  38. image: busybox
  39. imagePullPolicy: IfNotPresent
  40. name: busybox
  41. resources:
  42. ... ...
  43. $ kubectl apply -f busybox-test.yaml
  44. 此时看到busybox-test这个pod已经带有access=true的label了
  45. $ kubectl describe pod busybox-test
  46. Name: busybox-test
  47. Namespace: default
  48. Priority: 0
  49. Service Account: default
  50. Node: kevin-pc/192.168.227.129
  51. Start Time: Fri, 28 Jun 2024 16:39:13 +0800
  52. Labels: access=true
  53. 然后通过busybox-test访问nginx服务就可以访问到了
  54. $ kubectl exec -it pod/busybox-test -- sh
  55. / # wget --spider -timeout=1 nginx-deployment
  56. Connecting to nginx-deployment (10.102.52.246:80)
  57. remote file exists
  58. / #
  • 네트워크 정책 삭제

네트워크 정책을 삭제하면 모든 포드는 기본적으로 nginx-deployment 서비스에 액세스할 수 있습니다.

  1. $ kubectl get networkpolicy
  2. NAME POD-SELECTOR AGE
  3. access-nginx app=nginx 10m
  4. default-deny <none> 17m
  5. $ kubectl delete network policy access-nginx
  • 여러 액세스 정책의 구성 예

  • 지정된 서비스에 대한 액세스 거부

먼저 nginx 서비스를 시작하고 이 서비스에 라벨을 붙입니다.

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

  1. (没有配置ingress,所以所有的pod都没法访问这个服务)
  2. kind: NetworkPolicy
  3. apiVersion: networking.k8s.io/v1
  4. metadata:
  5. name: web-deny-all
  6. spec:
  7. podSelector:
  8. matchLabels:
  9. app: web
  10. env: prod
  • 지정된 포드만 서비스에 액세스하도록 허용

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

  1. kind: NetworkPolicy
  2. apiVersion: networking.k8s.io/v1
  3. metadata:
  4. name: api-allow
  5. spec:
  6. podSelector:
  7. matchLabels:
  8. app: bookstore
  9. role: api
  10. ingress:
  11. - from:
  12. - podSelector:
  13. matchLabels:
  14. app: bookstore
  • 네임스페이스에 있는 모든 포드 간의 상호 액세스를 비활성화합니다.

  1. apiVersion: networking.k8s.io/v1
  2. kind: NetworkPolicy
  3. metadata:
  4. name: default-deny
  5. namespace: default
  6. spec:
  7. podSelector: {}
  • 다른 네임스페이스가 서비스에 액세스하지 못하도록 방지

  1. kind: NetworkPolicy
  2. apiVersion: networking.k8s.io/v1
  3. metadata:
  4. namespace: default
  5. name: web-deny-other-namespaces
  6. spec:
  7. podSelector:
  8. matchLabels:
  9. ingress:
  10. - from:
  11. - podSelector: {}
  • 지정된 네임스페이스만 서비스에 액세스하도록 허용

  1. kind: NetworkPolicy
  2. apiVersion: networking.k8s.io/v1
  3. metadata:
  4. name: web-allow-prod
  5. spec:
  6. podSelector:
  7. matchLabels:
  8. app: web
  9. ingress:
  10. - from:
  11. - namespaceSelector:
  12. matchLabels:
  13. purpose: production
  • 서비스에 대한 외부 네트워크 액세스 허용

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

  1. kind: NetworkPolicy
  2. apiVersion: networking.k8s.io/v1
  3. metadata:
  4. name: web-allow-external
  5. spec:
  6. podSelector:
  7. matchLabels:
  8. app: web
  9. ingress:
  10. - ports:
  11. - port: 80
  12. from: []