Kubernetes 네트워크 정책

12626 단어 devopskubernetes

네트워크 정책

Using the NetworkPolicy resource, you can control the traffic flow for your applications in the cluster, at the IP address level or port level (OSI layer 3 or 4).

Open Systems Interconnection model (OSI model) is a conceptual model that characterises and standardizes the communication functions, regardless of the underlying technology. For more information, see the OCI model.



NetworkPolicy를 사용하면 포드가 클러스터의 다양한 네트워크 엔티티와 통신할 수 있는 방법을 정의할 수 있습니다.NetworkPolicy 정의에는 세 부분이 있습니다.
  • 정책이 적용되는 팟(Pod)을 선택하십시오. 레이블을 사용하여 그렇게 할 수 있습니다. 예를 들어 app=hello을 사용하면 해당 레이블이 있는 모든 포드에 정책이 적용됩니다.
  • 정책이 수신(수신) 트래픽, 발신(송신) 트래픽 또는 둘 다에 적용되는지 결정하십시오.
  • IP 블록, 포트, 포드 선택기 또는 네임스페이스 선택기를 지정하여 수신 또는 송신 규칙을 정의합니다.

  • 다음은 샘플 NetworkPolicy입니다.

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: my-network-policy
      namespace: default
    spec:
      podSelector:
        matchLabels:
          app: hello
      policyTypes:
      - Ingress
      - Egress
      ingress:
      - from:
        - ipBlock:
            cidr: 172.17.0.0/16
            except:
            - 172.17.1.0/24
        - namespaceSelector:
            matchLabels:
              owner: ricky 
        - podSelector:
            matchLabels:
              version: v2
        ports:
        - protocol: TCP
          port: 8080
      egress:
      - to:
        - ipBlock:
            cidr: 10.0.0.0/24
        ports:
        - protocol: TCP
          port: 500
    


    위의 YAML을 분석해 보겠습니다. podSelector은 정책이 default 라벨 세트가 있는 app: hello 네임스페이스의 모든 Pod에 적용됨을 알려줍니다. 수신 및 송신 트래픽 모두에 대한 정책을 정의하고 있습니다.

    적용되는 포드 정책에 대한 호출은 CIDR 블록 172.17.0.0/16(172.17.0.0에서 172.17.255.255까지의 65536개 IP 주소) 내의 모든 IP에서 수행될 수 있습니다. 단, IP가 CIDR 블록 172.17.1.0/24에 속하는 포드는 예외입니다. (256 IP 주소, 172.17.1.0에서 172.17.1.255까지) 포트 8080 . 또한 포드 정책이 적용되는 호출은 라벨이 owner: ricky 인 네임스페이스의 모든 포드와 라벨이 defaultversion: v2 네임스페이스의 모든 포드에서 올 수 있습니다.



    이그레스 정책은 app: hello 네임스페이스에 default 레이블이 있는 포드가 10.0.0.0/24(10.0.0.0, 10.0.0.255의 256개 IP 주소) 내의 모든 IP를 호출할 수 있지만 포트 5000 에만 호출할 수 있도록 지정합니다.



    Pod 및 네임스페이스 선택기는 and and or 시맨틱을 지원합니다. 다음 스니펫을 살펴보겠습니다.

      ...
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              user: ricky
          podSelector:
            matchLabels:
              app: website
      ...
    

    from 배열에 단일 요소가 있는 위의 스니펫에는 app: website 라벨이 지정된 네임스페이스의 라벨이 user: ricky 인 모든 포드가 포함됩니다. 이것은 및 연산자와 동일합니다.
    podSelector 을 추가하여 from- 배열의 별도 요소로 변경하면 or 연산자를 사용하는 것입니다.

      ...
      ingress:
      - from:
        - namespaceSelector:
            matchLabels:
              user: ricky
        - podSelector:
            matchLabels:
              app: website
      ...
    


    위 스니펫에는 라벨이 app: website 인 모든 포드 또는 라벨이 user: ricky 인 네임스페이스의 모든 포드가 포함됩니다.

    섬모 설치

    Network policies are implemented (and rules enforced) through network plugins. If you don't install a network plugin, the policies won't have any effect.

    I will use the Cilium plugin 그리고 Minikube 위에 설치한다. Calico 과 같은 다른 플러그인을 사용할 수도 있습니다.

    Minikube가 이미 실행 중인 경우 클러스터를 중지하고 삭제(또는 새로 생성)해야 합니다. Cilium이 올바르게 작동하려면 cni 플래그로 Minikube를 시작해야 합니다.

    $ minikube start --network-plugin=cni
    


    Minikube가 시작되면 Cilium을 설치할 수 있습니다.

    $ kubectl create -f https://raw.githubusercontent.com/cilium/cilium/1.8.3/install/kubernetes/quick-install.yaml
    all/kubernetes/quick-install.yaml
    serviceaccount/cilium created
    serviceaccount/cilium-operator created
    configmap/cilium-config created
    clusterrole.rbac.authorization.k8s.io/cilium created
    clusterrole.rbac.authorization.k8s.io/cilium-operator created
    clusterrolebinding.rbac.authorization.k8s.io/cilium created
    clusterrolebinding.rbac.authorization.k8s.io/cilium-operator created
    daemonset.apps/cilium created
    deployment.apps/cilium-operator created
    


    Cilium은 kube-system 네임스페이스에 설치되므로 kubectl get po -n kube-system을 실행하고 Cilium Pod가 실행될 때까지 기다릴 수 있습니다.

    예시

    Let's look at an example that demonstrates how to disable egress traffic from the Pods.

    apiVersion: v1
    kind: Pod
    metadata:
      name: no-egress-pod
      labels:
        app.kubernetes.io/name: hello
    spec:
      containers:
        - name: container
          image: radial/busyboxplus:curl
          command: ["sh", "-c", "sleep 3600"]
    

    Save the above YAML to no-egress-pod.yaml and create the Pod using kubectl apply -f no-egress-pod.yaml .

    Once the Pod is running, let's try calling google.com using curl :

    $ kubectl exec -it no-egress-pod -- curl -I -L google.com
    HTTP/1.1 301 Moved Permanently
    Location: http://www.google.com/
    Content-Type: text/html; charset=UTF-8
    Date: Thu, 24 Sep 2020 16:30:59 GMT
    Expires: Sat, 24 Oct 2020 16:30:59 GMT
    Cache-Control: public, max-age=2592000
    Server: gws
    Content-Length: 219
    X-XSS-Protection: 0
    X-Frame-Options: SAMEORIGIN
    
    HTTP/1.1 200 OK
    ...
    

    The call completes successfully. Let's define a network policy that will prevent egress for Pods with the label app.kubernetes.io/name: hello :

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: deny-egress
    spec:
      podSelector:
        matchLabels:
          app.kubernetes.io/name: hello
      policyTypes:
        - Egress
    

    If you run the same command this time, curl won't be able to resolve the host:

    $ kubectl exec -it no-egress-pod -- curl -I -L google.com
    curl: (6) Couldn't resolve host 'google.com'
    

    Try running kubectl edit pod no-egress-pod and change the label value to hello123 . Save the changes and then re-run the curl command. This time, the command works fine because we changed the Pod label, and the network policy does not apply to it anymore.

    공통 네트워크 정책

    Let's look at a couple of scenarios and corresponding network policies.

    모든 이그레스 트래픽 거부

    Denies all egress traffic from the Pods in the namespace, so Pods cannot make any outgoing requests.

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

    모든 인그레스 트래픽 거부

    Denies all ingress traffic, and Pods cannot receive any requests.

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

    특정 Pod에 대한 인그레스 트래픽 허용

    Allow ingress to specific Pods, identified by the label app: my-app .

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

    특정 포드에 대한 인그레스 거부

    Denies ingress to specific Pods, identified by the label app: my-app .

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: pods-deny-all
    spec:
      podSelector:
        matchLabels:
          app: my-app
      ingress: []
    

    특정 포드에 대한 트래픽 제한

    Allows traffic from certain Pods only. Allow traffic from app: customers to any frontend Pods ( role: frontend ) that are part of the same app ( app: customers ).

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: frontend-allow
    spec:
      podSelector:
        matchLabels:
          app: customers
          role: frontend
      ingress:
        - from:
            - podSelector:
                matchLabels:
                  app: customers
    

    네임스페이스에 대한 모든 트래픽 거부

    Denies all incoming traffic (no ingress rules defined) to all Pods (empty podSelector ) in the prod namespace. Any calls from outside of the default namespace will be blocked and any calls between Pods in the same namespace.

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: prod-deny-all
      namespace: prod
    spec:
      podSelector: {}
      ingress: []
    

    다른 네임스페이스의 모든 트래픽 거부

    Denies all traffic from other namespaces, coming to the Pods in the prod namespace. It matches all pods (empty podSelector ) in the prod namespace and allows ingress from all Pods in the prod namespace, as the ingress podSelector is empty as well.

    kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
      name: deny-other-namespaces
      namespace: prod
    spec:
      podSelector: {}
      ingress:
        - from:
            - podSelector: {}
    

    특정 포드에 대한 모든 이그레스 트래픽 거부

    Denies Pods labeled with app: api from making any external calls.

    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: api-deny-egress
    spec:
      podSelector:
        matchLabels:
          app: api
      policyTypes:
        - Egress
      egress: []
    

    좋은 웹페이지 즐겨찾기