Amazon EKS용 Kubernetes 네트워크 정책 문제 해결하기

Amazon EKS용 Kubernetes 네트워크 정책 문제 해결하기 (Troubleshooting Kubernetes network policies for Amazon EKS)

이 문서는 Amazon VPC CNI의 네트워크 정책 기능에 대한 문제 해결 안내서예요. 다음 내용을 다뤄요.

  • 설치 정보, CRD 및 RBAC 권한 (새로운 policyendpoints CRD 및 권한)
  • 네트워크 정책 문제를 진단할 때 살펴볼 로그 (네트워크 정책 로그)
  • eBPF SDK 도구 모음 실행
  • 알려진 문제 및 해결 방법 (알려진 문제와 해결책)

참고

네트워크 정책은 Kubernetes Deployment로 만든 Pod에만 적용된다는 점을 기억하세요. VPC CNI의 네트워크 정책에 대한 더 많은 제약 사항은 고려 사항(Considerations)을 참고하세요.

네트워크 정책 로그(Network policy logs)를 읽고 eBPF SDK의 도구를 실행하여 네트워크 정책을 사용하는 네트워크 연결을 문제 해결하고 조사할 수 있어요.

출처: 문서

본문

새로운 policyendpoints CRD 및 권한

  • CRD: policyendpoints.networking.k8s.aws
  • Kubernetes API: v1.networking.k8s.io라고 하는 apiservice
  • Kubernetes 리소스: Kind: NetworkPolicy
  • RBAC: aws-node라고 하는 ClusterRole(VPC CNI), eks:network-policy-controller라고 하는 ClusterRole(EKS 클러스터 컨트롤 플레인의 네트워크 정책 컨트롤러)

네트워크 정책을 위해 VPC CNI는 policyendpoints.networking.k8s.aws라는 새로운 CustomResourceDefinition(CRD)을 만들어요. VPC CNI는 CRD를 만들고, 이 CRD와 VPC CNI가 설치한 다른 CRD(eniconfigs.crd.k8s.amazonaws.com)의 CustomResource(CR)를 만들 권한이 있어야 해요. 두 CRD 모두 GitHub의 crds.yaml 파일에서 사용할 수 있어요. 특히 VPC CNI는 policyendpoints에 대해 get, list, watch 동사 권한이 있어야 해요.

Kubernetes Network Policy는 v1.networking.k8s.io라고 하는 apiservice의 일부이며, 정책 YAML 파일에서는 apiversion: networking.k8s.io/v1이에요. VPC CNI DaemonSet은 Kubernetes API의 이 부분을 사용할 권한이 있어야 해요.

VPC CNI 권한은 aws-node라는 ClusterRole에 있어요. ClusterRole 객체는 네임스페이스로 그룹화되지 않는다는 점을 기억하세요. 다음은 클러스터의 aws-node를 보여줘요.

kubectl get clusterrole aws-node -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/instance: aws-vpc-cni
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: aws-node
    app.kubernetes.io/version: v1.19.4
    helm.sh/chart: aws-vpc-cni-1.19.4
    k8s-app: aws-node
  name: aws-node
rules:
- apiGroups:
  - crd.k8s.amazonaws.com
  resources:
  - eniconfigs
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  resources:
  - nodes
  verbs:
  - list
  - watch
  - get
- apiGroups:
  - ""
  - events.k8s.io
  resources:
  - events
  verbs:
  - create
  - patch
  - list
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints/status
  verbs:
  - get
- apiGroups:
  - vpcresources.k8s.aws
  resources:
  - cninodes
  verbs:
  - get
  - list
  - watch
  - patch

또한 각 EKS 클러스터의 컨트롤 플레인에서 새 컨트롤러가 실행돼요. 이 컨트롤러는 eks:network-policy-controller라는 ClusterRole의 권한을 사용해요. 다음은 클러스터의 eks:network-policy-controller를 보여줘요.

kubectl get clusterrole eks:network-policy-controller -o yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  labels:
    app.kubernetes.io/name: amazon-network-policy-controller-k8s
  name: eks:network-policy-controller
rules:
- apiGroups:
  - ""
  resources:
  - namespaces
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - services
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints
  verbs:
  - create
  - delete
  - get
  - list
  - patch
  - update
  - watch
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints/finalizers
  verbs:
  - update
- apiGroups:
  - networking.k8s.aws
  resources:
  - policyendpoints/status
  verbs:
  - get
  - patch
  - update
- apiGroups:
  - networking.k8s.io
  resources:
  - networkpolicies
  verbs:
  - get
  - list
  - patch
  - update
  - watch

네트워크 정책 로그 (Network policy logs)

VPC CNI가 네트워크 정책으로 연결을 허용하거나 거부하는 각 결정은 흐름 로그(flow logs)에 기록돼요. 각 노드의 네트워크 정책 로그에는 네트워크 정책이 있는 모든 Pod의 흐름 로그가 포함돼요. 네트워크 정책 로그는 /var/log/aws-routed-eni/network-policy-agent.log에 저장돼요. 다음은 network-policy-agent.log 파일의 예시예요.

{"level":"info","timestamp":"2023-05-30T16:05:32.573Z","logger":"ebpf-client","msg":"Flow Info: ","Src IP":"192.168.87.155","Src Port":38971,"Dest IP":"64.6.160","Dest Port":53,"Proto":"UDP","Verdict":"ACCEPT"}

네트워크 정책 로그는 기본적으로 비활성화되어 있어요. 네트워크 정책 로그를 활성화하려면 다음 단계를 따르세요.

참고

네트워크 정책 로그에는 VPC CNI aws-node DaemonSet 매니페스트의 aws-network-policy-agent 컨테이너에 vCPU 1개가 추가로 필요해요.

Amazon EKS 애드온

  1. Amazon EKS 콘솔을 엽니다.
  2. 왼쪽 탐색 창에서 Clusters를 선택한 다음, Amazon VPC CNI 애드온을 구성할 클러스터의 이름을 선택해요.
  3. Add-ons 탭을 선택해요.
  4. 애드온 상자 오른쪽 위의 확인란을 선택하고 Edit을 선택해요.
  5. Configure Amazon VPC CNI 페이지에서 Version 드롭다운 목록에서 v1.14.0-eksbuild.3 이상 버전을 선택해요.
  6. Optional configuration settings를 펼쳐요.
  7. Configuration values에 최상위 JSON 키 "nodeAgent"와, 키 "enablePolicyEventLogs"와 값 "true"를 가진 객체를 입력해요. 결과 텍스트는 유효한 JSON 객체여야 해요. 다음 예시는 네트워크 정책과 네트워크 정책 로그가 활성화되고, 네트워크 정책 로그가 CloudWatch Logs로 전송되는 모습을 보여줘요.
{
    "enableNetworkPolicy": "true",
    "nodeAgent": {
        "enablePolicyEventLogs": "true"
    }
}

AWS CLI

다음 AWS CLI 명령을 실행해요. my-cluster를 클러스터 이름으로, IAM 역할 ARN을 사용 중인 역할로 바꾸세요.

aws eks update-addon --cluster-name my-cluster --addon-name vpc-cni --addon-version v1.14.0-eksbuild.3 \
    --service-account-role-arn arn:aws:iam::123456789012:role/AmazonEKSVPCCNIRole \
    --resolve-conflicts PRESERVE --configuration-values '{"nodeAgent": {"enablePolicyEventLogs": "true"}}'

자체 관리형 애드온 (Helm)

helm으로 Amazon VPC CNI 플러그인 for Kubernetes를 설치했다면, 네트워크 정책 로그를 쓰도록 구성을 업데이트할 수 있어요. 다음 명령을 실행해 네트워크 정책을 활성화해요.

helm upgrade --set nodeAgent.enablePolicyEventLogs=true aws-vpc-cni --namespace kube-system eks/aws-vpc-cni

자체 관리형 애드온 (kubectl)

kubectl로 Amazon VPC CNI 플러그인 for Kubernetes를 설치했다면, 네트워크 정책 로그를 쓰도록 구성을 업데이트할 수 있어요. 편집기에서 aws-node DaemonSet을 여세요.

kubectl edit daemonset -n kube-system aws-node

VPC CNI aws-node DaemonSet 매니페스트의 aws-network-policy-agent 컨테이너 args:에서 명령 인수 --enable-policy-event-logs=false의 false를 true로 바꾸세요.

     - args:
        - --enable-policy-event-logs=true

네트워크 정책 로그를 Amazon CloudWatch Logs로 보내기

Amazon CloudWatch Logs 같은 서비스를 사용해 네트워크 정책 로그를 모니터링할 수 있어요. 다음 방법으로 네트워크 정책 로그를 CloudWatch Logs로 보낼 수 있어요.

EKS 클러스터의 경우 정책 로그는 /aws/eks/cluster-name>/cluster/ 아래에, 자체 관리형 K8S 클러스터의 경우 로그는 /aws/k8s-cluster/cluster/ 아래에 위치해요.

Amazon VPC CNI 플러그인 for Kubernetes로 네트워크 정책 로그 보내기

네트워크 정책을 활성화하면 aws-node Pod에 노드 에이전트용 두 번째 컨테이너가 추가돼요. 이 노드 에이전트는 네트워크 정책 로그를 CloudWatch Logs로 보낼 수 있어요.

참고

노드 에이전트가 보내는 것은 네트워크 정책 로그뿐이에요. VPC CNI가 만든 다른 로그는 포함되지 않아요.

사전 요구 사항

VPC CNI에 사용하는 IAM 역할에 다음 권한을 스탠자(stanza) 또는 별도 정책으로 추가해요.

{
    "Version":"2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "logs:DescribeLogGroups",
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

Amazon EKS 애드온 (AWS Management Console)

  1. Amazon EKS 콘솔을 엽니다.
  2. 왼쪽 탐색 창에서 Clusters를 선택한 다음, Amazon VPC CNI 애드온을 구성할 클러스터의 이름을 선택해요.
  3. Add-ons 탭을 선택해요.
  4. 애드온 상자 오른쪽 위의 확인란을 선택하고 Edit을 선택해요.
  5. Configure Amazon VPC CNI 페이지에서 Version 드롭다운 목록에서 v1.14.0-eksbuild.3 이상 버전을 선택해요.
  6. Optional configuration settings를 펼쳐요.
  7. Configuration values에 최상위 JSON 키 "nodeAgent"와, 키 "enableCloudWatchLogs"와 값 "true"를 가진 객체를 입력해요. 결과 텍스트는 유효한 JSON 객체여야 해요. 다음 예시는 네트워크 정책과 네트워크 정책 로그가 활성화되고, 로그가 CloudWatch Logs로 전송되는 모습을 보여줘요.
{
    "enableNetworkPolicy": "true",
    "nodeAgent": {
        "enablePolicyEventLogs": "true",
        "enableCloudWatchLogs": "true",
    }
}

Amazon EKS 애드온 (AWS CLI)

다음 AWS CLI 명령을 실행해요. my-cluster를 클러스터 이름으로, IAM 역할 ARN을 사용 중인 역할로 바꾸세요.

aws eks update-addon --cluster-name my-cluster --addon-name vpc-cni --addon-version v1.14.0-eksbuild.3 \
    --service-account-role-arn arn:aws:iam::123456789012:role/AmazonEKSVPCCNIRole \
    --resolve-conflicts PRESERVE --configuration-values '{"nodeAgent": {"enablePolicyEventLogs": "true", "enableCloudWatchLogs": "true"}}'

자체 관리형 애드온 (Helm)

helm으로 Amazon VPC CNI 플러그인 for Kubernetes를 설치했다면, 네트워크 정책 로그를 CloudWatch Logs로 보내도록 구성을 업데이트할 수 있어요. 다음 명령을 실행해 네트워크 정책 로그를 활성화하고 CloudWatch Logs로 보내요.

helm upgrade --set nodeAgent.enablePolicyEventLogs=true --set nodeAgent.enableCloudWatchLogs=true aws-vpc-cni --namespace kube-system eks/aws-vpc-cni

자체 관리형 애드온 (kubectl)

편집기에서 aws-node DaemonSet을 여세요.

kubectl edit daemonset -n kube-system aws-node

VPC CNI aws-node DaemonSet 매니페스트의 aws-network-policy-agent 컨테이너 args:에서 두 명령 인수 --enable-policy-event-logs=false와 --enable-cloudwatch-logs=false의 false를 true로 바꾸세요.

     - args:
        - --enable-policy-event-logs=true
        - --enable-cloudwatch-logs=true

Fluent Bit DaemonSet으로 네트워크 정책 로그 보내기

Fluent Bit을 DaemonSet으로 사용해 노드에서 로그를 보낸다면, 네트워크 정책의 네트워크 정책 로그를 포함하도록 구성을 추가할 수 있어요. 다음 예시 구성을 사용할 수 있어요.

    [INPUT]
        Name              tail
        Tag               eksnp.*
        Path              /var/log/aws-routed-eni/network-policy-agent*.log
        Parser            json
        DB                /var/log/aws-routed-eni/flb_npagent.db
        Mem_Buf_Limit     5MB
        Skip_Long_Lines   On
        Refresh_Interval  10

포함된 eBPF SDK

Amazon VPC CNI 플러그인 for Kubernetes는 노드에 eBPF SDK 도구 모음을 설치해요. eBPF SDK 도구를 사용해 네트워크 정책의 문제를 식별할 수 있어요. 예를 들어 다음 명령은 노드에서 실행 중인 프로그램을 나열해요.

sudo /opt/cni/bin/aws-eks-na-cli ebpf progs

이 명령을 실행하려면 아무 방법으로나 노드에 연결하면 돼요.

알려진 문제 및 해결 방법 (Known issues and solutions)

다음 섹션은 Amazon VPC CNI 네트워크 정책 기능의 알려진 문제와 그 해결 방법을 설명해요.

enable-policy-event-logs가 false로 설정되어도 네트워크 정책 로그가 생성됨

  • 문제: enable-policy-event-logs 설정이 false로 설정되어 있어도 EKS VPC CNI가 네트워크 정책 로그를 생성해요.
  • 해결책: enable-policy-event-logs 설정은 정책 "결정(decision)" 로그만 비활성화하며, 모든 Network Policy 에이전트 로깅을 비활성화하지는 않아요. 이 동작은 GitHub의 aws-network-policy-agent README에 문서화되어 있어요. 로깅을 완전히 비활성화하려면 다른 로깅 구성을 조정해야 할 수도 있어요.

네트워크 정책 맵 정리 문제

  • 문제: Pod가 삭제된 후에도 네트워크 policyendpoint가 여전히 존재하고 정리되지 않는 문제가 있어요.
  • 해결책: 이 문제는 VPC CNI 애드온 버전 1.19.3-eksbuild.1의 문제로 인해 발생했어요. 새 버전의 VPC CNI 애드온으로 업데이트하면 이 문제를 해결할 수 있어요.

네트워크 정책이 적용되지 않음

  • 문제: Amazon VPC CNI 플러그인에서 네트워크 정책 기능이 활성화되어 있는데도 네트워크 정책이 올바르게 적용되지 않아요.
  • kind: NetworkPolicy 네트워크 정책을 만들었는데 Pod에 영향이 없다면, policyendpoint 객체가 Pod와 같은 네임스페이스에 생성되었는지 확인하세요. 네임스페이스에 policyendpoint 객체가 없다면, 네트워크 정책 컨트롤러(EKS 클러스터의 일부)가 네트워크 정책 에이전트(VPC CNI의 일부)가 적용할 네트워크 정책 규칙을 만들 수 없었던 거예요.
  • 해결책: VPC CNI(ClusterRole: aws-node)와 네트워크 정책 컨트롤러(ClusterRole: eks:network-policy-controller)의 권한을 수정하고, Kyverno 같은 정책 적용 도구에서 이러한 작업을 허용하는 것이 해결책이에요. Kyverno 정책이 policyendpoint 객체 생성을 차단하지 않는지 확인하세요. 필요한 권한은 위의 "새로운 policyendpoints CRD 및 권한" 섹션을 참고하세요.

정책 삭제 후 strict 모드에서 Pod가 기본 거부 상태로 돌아가지 않음

  • 문제: 네트워크 정책이 strict 모드로 활성화되면 Pod는 기본 거부(default deny) 정책으로 시작해요. 정책이 적용되면 지정된 엔드포인트로 트래픽이 허용돼요. 그러나 정책이 삭제되면 Pod는 기본 거부 상태로 돌아가지 않고 기본 허용 상태가 돼요.
  • 해결책: 이 문제는 network policy agent 1.2.0 릴리스를 포함한 VPC CNI 릴리스 1.19.3에서 수정되었어요. 수정 후 strict 모드가 활성화되면 정책이 제거된 후에도 Pod는 예상대로 기본 거부 상태로 돌아가요.

Security Groups for Pods 시작 지연

  • 문제: EKS에서 Security Groups for Pods 기능을 사용할 때 Pod 시작 지연이 늘어나요.
  • 해결책: 이 지연은 VPC 리소스 컨트롤러가 Pod용 branch ENI를 만드는 데 사용하는 CreateNetworkInterface API의 API 스로틀링으로 인한 리소스 컨트롤러의 속도 제한 때문이에요. 이 작업에 대한 계정의 API 한도를 확인하고 필요하면 한도 증가를 요청하는 것을 고려하세요.

vpc.amazonaws.com/pod-eni 부족으로 인한 FailedScheduling

  • 문제: 다음 오류로 Pod가 스케줄링에 실패해요: FailedScheduling 2m53s (x28 over 137m) default-scheduler 0/5 nodes are available: 5 Insufficient vpc.amazonaws.com/pod-eni. preemption: 0/5 nodes are available: 5 No preemption victims found for incoming pod.
  • 해결책: 이전 문제와 마찬가지로, Pod에 Security Groups를 할당하면 Pod 스케줄링 지연이 늘어나고, 각 ENI를 추가하는 시간에 대한 CNI 임계값을 초과하여 Pod 시작이 실패할 수 있어요. 이는 Security Groups for Pods를 사용할 때 예상되는 동작이에요. 워크로드 아키텍처를 설계할 때 스케줄링 영향을 고려하세요.

IPAM 연결 문제 및 세그멘테이션 오류

  • 문제: IPAM 연결 문제, 스로틀링 요청, 세그멘테이션 오류를 포함한 여러 오류가 발생해요.
    • Checking for IPAM connectivity …
    • Throttling request took 1.047064274s
    • Retrying waiting for IPAM-D
    • panic: runtime error: invalid memory address or nil pointer dereference
  • 해결책: 이 문제는 AL2023에 systemd-udev를 설치하면 해당 파일이 파괴적인 정책으로 다시 작성되기 때문에 발생해요. 업데이트된 패키지가 있는 다른 releasever로 업데이트하거나 패키지 자체를 수동으로 업데이트할 때 발생할 수 있어요. AL2023 노드에 systemd-udev를 설치하거나 업데이트하지 마세요.

Failed to find device by name 오류

  • 문제: 오류 메시지: {"level":"error","ts":"2025-02-05T20:27:18.669Z","caller":"ebpf/bpf_client.go:578","msg":"failed to find device by name eni9ea69618bf0: %!w(netlink.LinkNotFoundError={0xc000115310})"}
  • 해결책: 이 문제는 최신 버전의 Amazon VPC CNI 네트워크 정책 에이전트(v1.2.0)에서 식별되고 수정되었어요. 최신 버전의 VPC CNI로 업데이트하면 이 문제를 해결할 수 있어요.

Multus CNI 이미지의 CVE 취약점

  • 문제: 향상된 EKS ImageScan CVE Report가 Multus CNI 이미지 버전 v4.1.4-eksbuild.2_thick의 취약점을 식별해요.
  • 해결책: 취약점이 없는 새 버전의 Multus CNI 이미지와 새 Network Policy Controller 이미지로 업데이트해요. 스캐너를 업데이트하면 이전 버전에서 발견된 취약점을 해결할 수 있어요.

로그의 Flow Info DENY 판정

  • 문제: 네트워크 정책 로그에 DENY 판정이 표시돼요: {"level":"info","ts":"2024-11-25T13:34:24.808Z","logger":"ebpf-client","caller":"events/events.go:193","msg":"Flow Info: ","Src IP":"","Src Port":9096,"Dest IP":"","Dest Port":56830,"Proto":"TCP","Verdict":"DENY"}
  • 해결책: 이 문제는 새 버전의 Network Policy Controller에서 해결되었어요. 로깅 문제를 해결하려면 최신 EKS 플랫폼 버전으로 업데이트해요.

Calico에서 마이그레이션한 후 Pod 간 통신 문제

  • 문제: EKS 클러스터를 버전 1.30으로 업그레이드하고 네트워크 정책을 위해 Calico에서 Amazon VPC CNI로 전환한 후, 네트워크 정책이 적용되면 Pod 간 통신이 실패해요. 네트워크 정책을 삭제하면 통신이 복원돼요.
  • 해결책: VPC CNI의 네트워크 정책 에이전트는 Calico만큼 많은 포트를 지정할 수 없어요. 대신 네트워크 정책에서 포트 범위를 사용하세요. 네트워크 정책의 각 ingress: 또는 egress: 선택자에서 프로토콜별 고유 포트 조합의 최대 개수는 24개예요. 포트 범위를 사용해 고유 포트 수를 줄이고 이 제한을 피하세요.

네트워크 정책 에이전트가 독립(standalone) Pod를 지원하지 않음

  • 문제: 독립 Pod에 적용된 네트워크 정책은 일관되지 않은 동작을 보일 수 있어요.
  • 해결책: Network Policy 에이전트는 현재 deployment/replicaset의 일부로 배포된 Pod만 지원해요. 네트워크 정책이 독립 Pod에 적용되면 동작에 일부 불일치가 있을 수 있어요. 이는 이 페이지 상단, 고려 사항(Considerations), GitHub의 aws-network-policy-agent 이슈 #327에 문서화되어 있어요. 일관된 네트워크 정책 동작을 위해 Pod를 deployment 또는 replicaset의 일부로 배포하세요.

더 알아보기 (Learn more)