Security group 을 pod 단위로 할당하기
AWS cloud 환경에서의 workload 기본 단위는 instance 이다. Instance 를 중심으로 Auto scaling, Security group, IAM role 등의 적용을 통해 application 을 제어한다.
Kubernetes 의 세계에서는 Pod 이 workload 의 기본 단위 이다. Pod 에 auto scaling 을 지정하거나 (Horizontal pod auto-scaler), IAM (kube2iam, kiam 등), Security Group (aws vpc cni) 을 지정할 수 있다.
이 글에서는 AWS Cloud 환경에서 kubernetes 에 Pod 단위의 Security group 을 어떻게 설정할 수 있는지 방법에 대해 간략히 다룬다.
먼저 현재 (2021–03–25) 기준으로 EKS 외의 환경에서는 Security groups for Pods 기능 (이하 SG for Pod) 이 제공되지 않는다. SG for Pod 은 내부적으로 Branch & Trunk Network Interface 기술을 통해 제공되는데, EC2 internal api 호출이 필요하다. EKS 의 control plane 에 설치되는 amazon-vpc-resource-controller 만 internal api 를 호출할 수 있고, 사용자가 worker node 에 직접 설치할 경우 api 호출에 실패하여 SG for Pod 기능을 사용할 수 없다.
그래서 현재 회사에서는 kOps 를 이용하여 kubernetes 를 구축하여 운영하고 있는데, SG for Pod 기능 사용을 위해 EKS 도입을 검토중이다.
— — — — — — — — — — — — — — — — — — — — — — — — —
(본 설치 가이드는 EKS 를 기준으로 작성 하였습니다)
SG for Pod 은 AWS VPC CNI 1.7.7 버전 이상부터 사용이 가능하다. 현재 EKS 1.19 는 1.7.5 를 default 로 구성해 주고 있으며, CNI version 은 아래 명령어로 확인한다.
kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2
CNI 를 upgrade 하는 방법은 아래 command 를 실행하면 된다
CNI_VER=1.7.7curl -o aws-k8s-cni.yaml https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/$CNI_VER/config/v1.7/aws-k8s-cni.yamlsed -i.bak -e 's/us-west-2/ap-northeast-2/' aws-k8s-cni.yamlkubectl apply -f aws-k8s-cni.yaml
ENI 관련 permission 을 EKS cluster role 에 추가한다. AWS Console 로 추가하면 편리하다.
arn:aws:iam::aws:policy/AmazonEKSVPCResourceController
aws-node daemonset 의 ENABLE_POD_ENI 옵션을 켜준다. 이 때 DISABLE_TCP_EARLY_DEMUX 도 같이 true 로 해야 한다. 이 옵션을 default (false) 로 놔둘 경우 kubelet 의 liveness, readiness prove 체크 중 packet 이 drop 되는 이슈가 있다고 한다 (issue)
kubectl set env daemonset aws-node -n kube-system ENABLE_POD_ENI=truekubectl 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"}]}}}}'
ENABLE_POD_ENI 를 설정할 경우 node 의 vpc.amazonaws.com/has-trunk-attached 라벨이 활성화가 되는데, 이를 통해 잘 적용 되었는지 확인할 수 있다.
kubectl get nodes -o wide -l vpc.amazonaws.com/has-trunk-attached=true
이 후 부터는 SecurityGroupPolicy 등록을 통해 SG for Pod 기능을 사용하면 된다.
kubectl apply -f - <<EOF
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
name: policy-test
spec:
podSelector:
matchLabels:
app: hello
securityGroups:
groupIds:
- sg-1234
EOF
아래는 간단히 SG for Pod 을 테스트 해볼 수 있는 예제 script 이다.
kubectl create ns sg-testkubectl create deployment hello-node --image=k8s.gcr.io/echoserver:1.4kubectl apply -f - <<EOF
apiVersion: vpcresources.k8s.aws/v1beta1
kind: SecurityGroupPolicy
metadata:
name: policy-test
spec:
podSelector:
matchLabels:
app: hello-node
securityGroups:
groupIds:
- sg-1234
EOFPOD_IP=$(kubectl get pods --selector=app=hello-node -o jsonpath='{.items[*].status.podIP}')# nmap 을 통해 붙을 수 있는 port 를 확인 한다.
nmap $POD_IP
References
* https://github.com/aws/amazon-vpc-cni-k8s
* https://github.com/aws/amazon-vpc-resource-controller-k8s
* SG for pod configuration official guide
* AWS VPC CNI design proposal
* WARM_ENI_TARGET, WARM_IP_TARGET, MINIMUM_IP_TARGET