본문 바로가기
Orchestration/Kubernetes

EKS Pod 전용 Security group (SecurityGroupPolicy)

by wlsdn3004 2023. 5. 18.
728x90
반응형

 

일반적으로 EKS에서 Pod의 트래픽은 EKS Worker Node Security group의 In/Out 규칙을 따른다.

하지만 Pod용 Security groups을 적용하면 이때부터 EKS Worker Node Security group의 규칙을 따르지 않고 Pod 전용 Security group의 규칙을 따르게 된다.

 

 

사용방법은 간단하다.

apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
  name: policy-test
spec:
  podSelector:
    matchLabels:
      app: static-client
  securityGroups:
    groupIds:
    - {security-groups id}
---
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
  name: policy-test
spec:
  securityGroups:
    groupIds:
    - {security-groups id}
  serviceAccountSelector:
    matchLabels:
      app: static-client

위처럼 SecurityGroupPolicy의 podSelector와 serviceAccountSelector를 사용하여 Pod에 할당할 수 있다.

 

 

Pod 전용 Security group을 사용하려면 아래 조건을 고려해야 한다.

  • VPC CNI 플러그인 버전 1.7.7 이상부터 지원한다.
  • t type의 EC2 instance 유형은 지원하지 않는다.
  • EKS Worker Node의 ENI 및 IP를 1개 이상 할당할 수 있어야 한다.
  • SecurityGroupPolicy생성 후 Pod가 생성되어야 한다. 만약 Pod가 미리 생성되어 있으면 재생성 작업이 필요하다.

 

 

실습


 

EKS 클러스터 역할에 AmazonEKSVPCResourceController 관리형 정책 확인한다.

 

위 정책이 없다면 AWS Console 또는 아래 aws cli 명령어를 통해 정책을 추가한다.

$ cluster_role=$(aws eks describe-cluster --name {my-cluster-name} --query cluster.roleArn --output text | cut -d / -f 2)
$ aws iam attach-role-policy --policy-arn arn:aws:iam::aws:policy/AmazonEKSVPCResourceController --role-name $cluster_role

 

현재 VPC CNI 플러그인 버전이 1.7.7 이상인지 확인한다.

$ kubectl describe daemonset aws-node --namespace kube-system | grep amazon-k8s-cni: | cut -d : -f 3

 

aws-node 데몬셋이 ENI를 사용하여 Pod에 네트워크 인터페이스를 제공할 수 있게 아래와 같이 설정한다.

$ kubectl set env daemonset aws-node -n kube-system ENABLE_POD_ENI=true

 

위 설정을 하면 EKS worker node labels에 "vpc.amazonaws.com/has-trunk-attached=true" 라는 label이 들어가고 worker node의 ENI에 trunk type의 인터페이스가 추가된다.

$ kubectl get no --show-labels | grep -w "vpc.amazonaws.com/has-trunk-attached"
...
vpc.amazonaws.com/has-trunk-attached=true
[참고]
사용하고 있는 노드에  ENI 개수를 모두 사용하고 있으면 trunk type의 ENI를 추가로 할당할 수 없어 worker node의 labels에 "vpc.amazonaws.com/has-trunk-attached: true" 내용이 들어가지 않는다. 그럴 땐 노드를 재생성하여 생성될 때 trunk type의 eni가 바인딩될 수 있게 하면 된다.

 

ENABLE_POD_ENI=true로 설정된 경우 kubelet이 TCP를 사용하여 branch network interfaces의 Pods에 연결할 수 있도록 DISABLE_TCP_EARLY_DEMUX=true로 설정해야 한다. 관련 내용은 아래 링크를 참고하자.

https://github.com/aws/amazon-vpc-cni-k8s/issues/1260

https://github.com/aws/amazon-vpc-cni-k8s/pull/1212

$ kubectl patch daemonset aws-node -n kube-system \
  -p '{"spec": {"template": {"spec": {"initContainers": [{"env":[{"name":"DISABLE_TCP_EARLY_DEMUX","value":"true"}],"name":"aws-vpc-cni-init"}]}}}}'

 

위 절차대로 설정이 완료되면 SecurityGroupPolicy를 사용하여 Pod용 Security group을 사용할 수 있다.

[참고]
SecurityGroupPolicy가 생성되고 Pod가 생성되어야 Security group policy를 사용하여 AWS Security group에 할당되어 사용할 수 있게 된다. 만약 SecurityGroupPolicy를 통해 Security group을 사용하고 있는 상태에서 사용하고 있는 SecurityGroupPolicy가 삭제되더라도 기존에 사용하던 Security group을 계속 사용할 수 있고, pod가 restart 될 때 SecurityGroupPolicy가 없는 것을 감지하고 Secuity group을 사용할 수 없게 되어 다시 EKS Worker Node의 Security group의 규칙을 따르게 된다.

 

podSelector를 사용하여 SecurityGroupPolicy를 적용하려면 아래와 같이 적용하면 된다.

## security group policy
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
  name: policy-test
spec:
  podSelector:
    matchLabels:
      app: static-client
  securityGroups:
    groupIds:
    - {security-groups id}

 

## deployment
apiVersion: v1
kind: Service
metadata:
  name: static-client
spec:
  selector:
    app: static-client
  ports:
    - port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: static-client
  name: static-client
spec:
  replicas: 1
  selector:
    matchLabels:
      app: static-client
  template:
    metadata:
      labels:
        app: static-client
    spec:
      containers:
        - name: static-client
          image: wlsdn3004/curl:latest

 

적용 후 security group policy가 생성되었는지 확인한다.

$ kubectl get sgp
NAME          SECURITY-GROUP-IDS
policy-test   ["sg-0ed765ed6f1eafe68"]

 

kubectl describe로 파드의 Message를 확인해 보면 위에서 적용한 security group의 eni에 할당된 걸 확인할 수 있다.

$ kubectl describe deploy static-client-xxxxxxx
Events:
  Type    Reason                  Age   From                     Message
  ----    ------                  ----  ----                     -------
#...  
  Normal  SecurityGroupRequested  9s    vpc-resource-controller  Pod will get the following Security Groups [sg-0ed765ed6f1eafe68]
  Normal  ResourceAllocated       9s    vpc-resource-controller  Allocated [{"eniId":"eni-0d7d8c0aebf15063d","ifAddress":"06:84:0a:7d:ba:9c","privateIp":"192.168.6.173","vlanId":1,"subnetCidr":"192.168.6.0/24"}] to the pod

 

이제부터 위에서 적용한 Pod 전용 Security group의 규칙을 따르게 된다.

반응형

댓글