Amazon EKS용 Kubernetes 네트워크 정책 문제 해결하기
Amazon EKS용 Kubernetes 네트워크 정책 문제 해결하기 (Troubleshooting Kubernetes network policies for Amazon EKS)
이 문서는 Amazon VPC CNI의 네트워크 정책 기능에 대한 문제 해결 안내서예요. 다음 내용을 다뤄요.
- 설치 정보, CRD 및 RBAC 권한 (새로운
policyendpointsCRD 및 권한) - 네트워크 정책 문제를 진단할 때 살펴볼 로그 (네트워크 정책 로그)
- 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-nodeDaemonSet매니페스트의aws-network-policy-agent컨테이너에 vCPU 1개가 추가로 필요해요.
Amazon EKS 애드온
- Amazon EKS 콘솔을 엽니다.
- 왼쪽 탐색 창에서 Clusters를 선택한 다음, Amazon VPC CNI 애드온을 구성할 클러스터의 이름을 선택해요.
- Add-ons 탭을 선택해요.
- 애드온 상자 오른쪽 위의 확인란을 선택하고 Edit을 선택해요.
- Configure
Amazon VPC CNI페이지에서 Version 드롭다운 목록에서v1.14.0-eksbuild.3이상 버전을 선택해요. - Optional configuration settings를 펼쳐요.
- 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)
- Amazon EKS 콘솔을 엽니다.
- 왼쪽 탐색 창에서 Clusters를 선택한 다음, Amazon VPC CNI 애드온을 구성할 클러스터의 이름을 선택해요.
- Add-ons 탭을 선택해요.
- 애드온 상자 오른쪽 위의 확인란을 선택하고 Edit을 선택해요.
- Configure
Amazon VPC CNI페이지에서 Version 드롭다운 목록에서v1.14.0-eksbuild.3이상 버전을 선택해요. - Optional configuration settings를 펼쳐요.
- 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객체 생성을 차단하지 않는지 확인하세요. 필요한 권한은 위의 "새로운policyendpointsCRD 및 권한" 섹션을 참고하세요.
정책 삭제 후 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를 만드는 데 사용하는
CreateNetworkInterfaceAPI의 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.047064274sRetrying waiting for IPAM-Dpanic: 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의 일부로 배포하세요.