Amazon EKS Pod에 대한 보안 그룹 정책 사용
Pods에 대한 보안 그룹을 사용하려면 기존 보안 그룹이 있어야 합니다. 다음 단계에서는 Pod의 보안 그룹 정책을 사용하는 방법을 보여 줍니다. 달리 명시되지 않는 한, 변수가 터미널에 걸쳐 지속되지 않는 다음 단계에서 사용되므로 동일한 터미널에서 모든 단계를 완료합니다.
Amazon EC2 인스턴스에 Pod가 있는 경우 이 절차를 사용하기 전에 플러그인을 구성해야 합니다. 자세한 내용은 Amazon EKS Pods의 보안 그룹에 대해 Amazon VPC CNI plugin for Kubernetes 구성 단원을 참조하십시오.
-
리소스를 배포할 Kubernetes 네임스페이스를 생성합니다. 사용하려는 네임스페이스의 이름으로
my-namespace
를 바꿀 수 있습니다.kubectl create namespace my-namespace
-
Amazon EKS
SecurityGroupPolicy
를 클러스터에 배포합니다.-
다음 콘텐츠를 디바이스에 복사합니다. 서비스 계정 레이블에 따라 Pods를 선택하려는 경우
podSelector
를serviceAccountSelector
로 바꿀 수 있습니다. 두 선택기 중 하나만 지정해야 합니다. 비어 있는podSelector
(예:podSelector: {}
)는 네임스페이스의 모든 Pods를 선택합니다.my-role
을 자신의 역할 이름으로 변경할 수 있습니다. 비어 있는serviceAccountSelector
는 네임스페이스의 모든 서비스 계정을 선택합니다.my-security-group-policy
를 자신의SecurityGroupPolicy
에 대한 이름으로 바꾸고SecurityGroupPolicy
를 생성하려는 네임스페이스로my-namespace
를 바꿀 수 있습니다.my_pod_security_group_id
를 기존 보안 그룹의 ID로 바꿔야 합니다. 기존 보안 그룹이 없으면 하나를 생성해야 합니다. 자세한 내용은 Amazon EC2 사용 설명서의 Linux 인스턴스용 Amazon EC2 보안 그룹을 참조하세요. 보안 그룹 ID는 1~5개를 지정할 수 있습니다. 둘 이상의 ID를 지정하면 모든 보안 그룹의 모든 규칙 조합이 선택한 Pods에 적용됩니다.cat >my-security-group-policy.yaml <<EOF apiVersion: vpcresources.k8s.aws/v1beta1 kind: SecurityGroupPolicy metadata: name: my-security-group-policy namespace: my-namespace spec: podSelector: matchLabels: role: my-role securityGroups: groupIds: - my_pod_security_group_id EOF
중요
Pods에 대해 지정한 보안 그룹 또는 그룹은 다음 기준을 충족해야 합니다.
-
존재해야 합니다. 존재하지 않을 경우 선택기와 일치하는 Pod를 배포하면 Pod가 생성 프로세스에 계속 남아 있습니다. Pod에 대해 설명하면
An error occurred (InvalidSecurityGroupID.NotFound) when calling the CreateNetworkInterface operation: The securityGroup ID '
와 유사한 오류 메시지가 표시됩니다.sg-05b1d815d1EXAMPLE
' does not exist -
보안 그룹에서는 프로브를 구성한 모든 포트를 통해 노드에 적용된 보안 그룹의 인바운드 통신(
kubelet
의 경우)을 허용해야 합니다. -
CoreDNS를 실행하는 Pods(또는 Pods가 실행되는 노드)에 할당된 보안 그룹에 대한
TCP
및UDP
포트 53을 통한 아웃바운드 통신을 허용해야 합니다. CoreDNS Pods의 보안 그룹에서는 지정하는 보안 그룹의 인바운드TCP
및UDP
포트 53 트래픽을 허용해야 합니다. -
통신하려면 필요한 다른 Pods와 통신하는 데 필요한 인바운드 및 아웃바운드 규칙이 있어야 합니다.
-
Fargate에서 보안 그룹을 사용하는 경우 Pods가 Kubernetes 컨트롤 플레인과 통신할 수 있는 규칙이 있어야 합니다. 이 작업을 수행할 수 있는 가장 쉬운 방법은 클러스터 보안 그룹을 보안 그룹 중 하나로 지정하는 것입니다.
보안 그룹 정책은 새로 예약된 Pods에만 적용되며, 실행 중인 Pods에는 영향을 주지 않습니다.
-
-
정책을 배포합니다.
kubectl apply -f my-security-group-policy.yaml
-
-
이전 단계에서 지정한
podSelector
의my-role
값과 일치하는 레이블을 사용하여 샘플 애플리케이션을 배포한다.-
다음 콘텐츠를 디바이스에 복사합니다.
예제 값
을 사용자 값으로 바꾼 다음 수정된 명령을 실행합니다.my-role
을 바꾸는 경우 이전 단계에서 선택기에 지정한 값과 동일한지 확인합니다.cat >sample-application.yaml <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment namespace: my-namespace labels: app: my-app spec: replicas: 4 selector: matchLabels: app: my-app template: metadata: labels: app: my-app role: my-role spec: terminationGracePeriodSeconds: 120 containers: - name: nginx image: public.ecr.aws/nginx/nginx:1.23 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-app namespace: my-namespace labels: app: my-app spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 80 EOF
-
다음 명령을 사용하여 애플리케이션을 배포합니다. 애플리케이션을 배포할 때
role
레이블과 일치하는 Amazon VPC CNI plugin for Kubernetes과 이전 단계에서 지정한 보안 그룹이 Pod에 적용됩니다.kubectl apply -f sample-application.yaml
-
-
샘플 애플리케이션을 통해 배포된 Pods를 봅니다. 이 주제의 나머지 부분에서는 이 터미널을
TerminalA
로 언급합니다.kubectl get pods -n my-namespace -o wide
예제 출력은 다음과 같습니다.
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES my-deployment-5df6f7687b-4fbjm 1/1 Running 0 7m51s 192.168.53.48 ip-192-168-33-28.region-code.compute.internal <none> <none> my-deployment-5df6f7687b-j9fl4 1/1 Running 0 7m51s 192.168.70.145 ip-192-168-92-33.region-code.compute.internal <none> <none> my-deployment-5df6f7687b-rjxcz 1/1 Running 0 7m51s 192.168.73.207 ip-192-168-92-33.region-code.compute.internal <none> <none> my-deployment-5df6f7687b-zmb42 1/1 Running 0 7m51s 192.168.63.27 ip-192-168-33-28.region-code.compute.internal <none> <none>
참고
Pods가 멈춘 경우 다음 팁을 시도해 보세요.
-
Pods가
Waiting
상태에서 멈춘 경우kubectl describe pod
를 실행합니다.my-deployment-xxxxxxxxxx-xxxxx
-nmy-namespace
Insufficient permissions: Unable to create Elastic Network Interface.
(권한 부족: 탄력적 네트워크 인터페이스를 생성할 수 없습니다.)가 표시되면 이전 단계에서 IAM 클러스터 역할에 IAM 정책을 추가했는지 확인합니다. -
Pods가
Pending
상태로 멈춰 있는 경우 노드 인스턴스 유형이 limits.go에 나열되어 있고 인스턴스 유형에서 지원하는 최대 브랜치 네트워크 인터페이스 수와 노드 그룹의 노드 수를 곱한 값이 아직 충족되지 않았는지 확인합니다. 예를 들어 m5.large
인스턴스는 9개의 브랜치 네트워크 인터페이스를 지원합니다. 노드 그룹에 5개의 노드가 있는 경우 노드 그룹에 대해 최대 45개의 브랜치 네트워크 인터페이스를 생성할 수 있습니다. 배포하려는 46 번째 Pod는 연결된 보안 그룹이 있는 다른 Pod가 삭제될 때까지Pending
상태로 남아 있습니다.
kubectl describe pod
를 실행할 때 다음 메시지와 유사한 메시지가 표시될 경우 무시해도 됩니다. 이 메시지는 Amazon VPC CNI plugin for Kubernetes가 호스트 네트워킹을 설정하려고 할 때 네트워크 인터페이스가 생성되는 동안 실패할 경우 나타날 수 있습니다. 플러그인은 네트워크 인터페이스가 생성될 때까지 이 이벤트를 기록합니다.my-deployment-xxxxxxxxxx-xxxxx
-nmy-namespace
Failed to create Pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "e24268322e55c8185721f52df6493684f6c2c3bf4fd59c9c121fd4cdc894579f" network for Pod "my-deployment-5df6f7687b-4fbjm": networkPlugin cni failed to set up Pod "my-deployment-5df6f7687b-4fbjm-c89wx_my-namespace" network: add cmd: failed to assign an IP address to container
인스턴스 유형에서 실행할 수 있는 최대 Pods 수를 초과할 수 없습니다. 각 인스턴스 유형에서 실행할 수 있는 최대 Pods 수 목록은 GitHub의 eni-max-pods.txt
를 참조하세요. 연결된 보안 그룹이 있는 Pod를 삭제하거나 Pod가 실행되고 있는 노드를 삭제하면 VPC 리소스 컨트롤러가 브랜치 네트워크 인터페이스를 삭제합니다. 보안 그룹에 대해 Pods를 사용하는 Pods가 있는 클러스터를 삭제하면 컨트롤러가 브랜치 네트워크 인터페이스를 삭제하지 않으므로 직접 삭제해야 합니다. 네트워크 인터페이스를 삭제하는 방법에 대한 자세한 내용은 Amazon EC2 사용 설명서의 네트워크 인터페이스 삭제를 참조하세요. -
-
별도의 터미널에서 Pods 중 하나에 셸을 적용합니다. 이 주제의 나머지 부분에서는 이 터미널을
TerminalB
로 언급합니다.5df6f7687b
-4fbjm
kubectl exec -it -n my-namespace my-deployment-5df6f7687b-4fbjm -- /bin/bash
-
TerminalB
의 셸에서 샘플 애플리케이션이 작동하는지 확인합니다.curl my-app
예제 출력은 다음과 같습니다.
<!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> [...]
애플리케이션이 실행되는 모든 Pods는 사용자가 생성한 보안 그룹과 연결되기 때문에 이 결과가 표시됩니다. 해당 그룹에는 보안 그룹이 연결되는 모든 Pods 간에 모든 트래픽을 허용하는 규칙이 포함되어 있습니다. DNS 트래픽은 해당 보안 그룹에서 노드와 연결된 클러스터 보안 그룹으로 아웃바운드 트래픽이 허용됩니다. 노드가 Pods에서 이름 조회를 수행한 CoreDNS Pods를 실행하고 있습니다.
-
보안 그룹에서 클러스터 보안 그룹으로의 DNS 통신을 허용하는 보안 그룹 규칙을
TerminalA
에서 제거합니다. 이전 단계에서 클러스터 보안 그룹에 DNS 규칙을 추가하지 않은 경우$my_cluster_security_group_id
를 사용자가 규칙을 생성한 보안 그룹의 ID로 바꿉니다.aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids $my_tcp_rule_id aws ec2 revoke-security-group-ingress --group-id $my_cluster_security_group_id --security-group-rule-ids $my_udp_rule_id
-
TerminalB
에서 다시 애플리케이션에 액세스하려고 시도합니다.curl my-app
예제 출력은 다음과 같습니다.
curl: (6) Could not resolve host: my-app
Pod에서 클러스터 보안 그룹을 연결해 주는 CoreDNS Pods에 더 이상 액세스할 수 없기 때문에 이 시도는 실패합니다. 클러스터 보안 그룹에는 Pod에 연결된 보안 그룹에서 DNS 통신을 허용하는 보안 그룹 규칙이 더 이상 없습니다.
이전 단계에서 Pods 중 하나에 대해 반환된 IP 주소를 사용하여 애플리케이션에 액세스하려고 시도하는 경우 보안 그룹이 연결되어 있는 Pods 간에 모든 포트가 허용되고 이름 조회가 필요 없기 때문에 응답이 계속 표시됩니다.
-
실험이 끝나면 생성한 샘플 보안 그룹 정책, 애플리케이션 및 보안 그룹을 제거할 수 있습니다.
TerminalA
에서 다음 명령을 실행합니다.kubectl delete namespace my-namespace aws ec2 revoke-security-group-ingress --group-id $my_pod_security_group_id --security-group-rule-ids $my_inbound_self_rule_id wait sleep 45s aws ec2 delete-security-group --group-id $my_pod_security_group_id