본문으로 바로가기
반응형

Intro

앞전에 포스팅한 EKS 클러스터에 서브넷 추가 하기는 CNI custom networking으로 커스텀하게 CNI의 IP를 할당하는 방법이었습니다.

AWS에서 제공하는 예제를 사용하였구요 https://aws.amazon.com/ko/premiumsupport/knowledge-center/eks-multiple-cidr-ranges/

이 예제를 활용해서 제가 원하고자 하는 네트워크를 할당하기 위해 몇가지 테스트를 해보았고 몇가지 문제점도 찾아낼 수 있었습니다.

오늘은 그 이야기를 공유하고자 합니다. (해결하지 못한 내용이 있으므로 좋은 아이디어가 있으면 댓글로 공유해주세요)

AWS에서 가이드한 VPC CNI custom networking 예제 분석

우선 위에서 말씀드린 AWS에서 CNI custom networking 를 활용하여 서브넷을 추가하는 가이드를 간략히 설명드리면

CNI custom networking을 활성화 하도록 아래와 같이 파라미터를 AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG=true 설정합니다.

(해당 파라미터에대한 자세한 내용은 https://github.com/aws/amazon-vpc-cni-k8s/blob/master/README.md#aws_vpc_k8s_cni_custom_network_cfg 에서 제공해주고 있습니다.)

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

그리고 ENI_CONFIG_LABEL_DEF=failure-domain.beta.kubernetes.io/zone 으로 설정하는데 이는 Node instance에 자동으로 붙는 라벨 failure-domain.beta.kubernetes.io/zone 기준으로 IP를 할당한다는 것입니다.

kubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=failure-domain.beta.kubernetes.io/zone

이말이 무슨 말이냐면을 아래 쿠버네티스 명령어로 확인해보면 노드인스턴스 라벨에 failure-domain.beta.kubernetes.io/zone=ap-northeast-2a 와 같이 출력되는 것을 확인할 수 있습니다.

kubectl get nodes --show-labels | grep failure-domain.beta.kubernetes.io/zone

위에서 설정한 ENI Config Lable ENI_CONFIG_LABEL_DEF=ap-northeast-2a 과 같은 뜻으로
ENIConfig 라는 CRD 이름을 ENI_CONFIG_LABEL_DEF 에 설정한 이름과 동일 하게 만들어야 하며
ENIConfig에 들어가는 subnet id에 할당되는 ip가 노드인스턴스에 할당이 되는 것입니다. (아래를 CRD manifest를 보면 이해하기가 쉽습니다)

cat << EOF | kubectl apply -f -
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: eniconfigs.crd.k8s.amazonaws.com
spec:
  scope: Cluster
  group: crd.k8s.amazonaws.com
  version: v1alpha1
  names:
    plural: eniconfigs
    singular: eniconfig
    kind: ENIConfig
EOF
cat << EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata: 
  name: ap-northeast-2a
spec: 
  securityGroups: 
    - <sg-0dff111a1d11c1c11>
  subnet: <subnet-011b111c1f11fdf11>
EOF

그런데 여기서 문제가 이슈가 발생합니다. 노드 그룹에 생성되는 인스턴스가 AZ기준이 아닌 특정 커스텀한 기준을 잡고 ap-northeast-1, ap-northeast-2 두 서브넷으로 설정하고 싶으면 어떻게 해야할까요?

특정 노드그룹에 여러 서브넷을 설정하고 싶다면?

예를 들어서 필자는 다음과 같이 설정하고 싶습니다.

FRONTEND-NODEGROUP(k8s lable is nodename=frontend)

  • FRONTEND-SUBNET-a
  • FRONTEND-SUBNET-c

BACKEND-NODEGROUPP(k8s lable is nodename=backend)

  • BACCKEND-SUBNET-a
  • BACKEND-SUBNET-c

MANGE-NODEGROUPP(k8s lable is nodename=manage)

  • MANAGE-SUBNET-a
  • MANAGE-SUBNET-c

이 경우 기준을 노드에 k8s라벨을 넣어준 nodename 으로 설정할 것이고 nodename은 두개의 AZ를 포함해야 합니다.

따라서 아래와 같이 설정하였습니다. ENI_CONFIG_LABEL_DEF=nodename

kubectl set env daemonset aws-node -n kube-system ENI_CONFIG_LABEL_DEF=nodename

CRD도 아래와 같이 생성하였습니다.

cat << EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata: 
  name: frontend
spec: 
  securityGroups: 
    - <sg-0dff111a1d11c1c11>
  subnet: <subnet-011b111c1f11fdf00>,<subnet-011b111c1f11fdf01>
EOF

cat << EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata: 
  name: backend
spec: 
  securityGroups: 
    - <sg-0dff111a1d11c1c11>
  subnet: <subnet-011b111c1f11fdf10>,<subnet-011b111c1f11fdf11>
EOF

cat << EOF | kubectl apply -f -
apiVersion: crd.k8s.amazonaws.com/v1alpha1
kind: ENIConfig
metadata: 
  name: manage
spec: 
  securityGroups: 
    - <sg-0dff111a1d11c1c11>
  subnet: <subnet-011b111c1f11fdf20>,<subnet-011b111c1f11fdf21>
EOF

그런데 역시나 ENIConfig 필드 subnetsubnets 가 아닌것을 보니 다수의 subnet은 할당할 수가 없는 것을 확인하였습니다.

즉 ENIConfig 와 Subnet은 1:1 매핑이라는 것이고 하나의 AZ만 설정할 수 있다는 이야기입니다. (Subnet은 AZ당 1개만 생성 가능하니까요)

결론

VPC CNI custom networking을 사용하려면 AZ를 1개만 사용해야 한다 입니다.

왜 이렇게 만들었는지 모르겠습니다. 쿠버네티스 환경에서는 HA에 개념이 굳이 필요 없어서 일까요? (아시는분 있으면 댓글좀..)
AZ(가용영역)를 물리적으로 완전히 분리해서 HA다운 HA를 최대 장점으로 가져가는 AWS에서 왜 VPC CNI는 여러개의 서브넷으로 설정할 수 없는 걸까요?

오늘도 역시나 AWS문서를 그대로 따라하긴 했으나 이를 활용하는 것은 쉽지 않구나를 느끼면서 포스팅을 마치도록 하겠습니다.

반응형