본문 바로가기

EKS/EKS Cluster

EKS - VPC CNI Udpate

CNI는 Container Network Interface로 제가 Secondary IP 리밋을 주는 글을 작성했을 때, 

 

Docs 링크와 같이 간단하게 설명을 주었습니다.

 

VPC CNI가 1.6.3 / 1.7.5 두개의 버전을 현재 공식적으로 권유하고 있으며

 

최근 EKS를 생성할 때는 위의 두 버전 중 하나를 골라 구성할 수 있도록 바뀌었습니다.

 

IP 할당에 관한 이슈들이 생겼을때 AWS에서는 VPC CNI1.7.5로의 업데이트도 권유합니다.

 

먼저 CNI 버전이 낮다면, 각 클러스터 버전에서 가장 맞는 kube-proxy와 coredns 버전을 맞춰주시기 바랍니다.

 

아래 Docs를 참조하면 가능하며, 간단하게 그 방법을 소개하겠습니다.

 

docs.aws.amazon.com/ko_kr/eks/latest/userguide/cni-upgrades.html

 

Kubernetes 업그레이드용 Amazon VPC CNI 플러그인 - Amazon EKS

이 페이지에 작업이 필요하다는 점을 알려 주셔서 감사합니다. 실망시켜 드려 죄송합니다. 잠깐 시간을 내어 설명서를 향상시킬 수 있는 방법에 대해 말씀해 주십시오.

docs.aws.amazon.com

 

docs.aws.amazon.com/ko_kr/eks/latest/userguide/update-cluster.html

 

Amazon EKS 클러스터 Kubernetes 버전 업데이트 - Amazon EKS

Amazon EKS는 가용성 높은 제어 플레인을 실행하지만, 업데이트 중에 심각하지 않은 서비스 중단이 발생할 수도 있습니다. 예를 들어, API 서버를 종료하고 새 Kubernetes 버전을 실행하는 새로운 API 서

docs.aws.amazon.com

 

먼저 VPC CNI를 업데이트하기 전에,

EKS Endpoint 접근이 Public인지 Prviate인지 설정을 체크해주셔야합니다.

Public / Public & Private으로 되어있을 경우,

Cluster 및 Node SG에서 0.0.0.0/0 443 Out,

Node SG -> Cluster SG 443 IN 이 존재해야 EKS API Endpoint로의 통신이 가능합니다.

Private만으로 되어있을 경우에도 0.0.0.0/0 443 Out으로 통신이 가능하나

(기본적으로 EKS Endpoint는 사용자가 직접 구성하는 EC2 VPC Enpoint와 다르기 때문)

사용자가 구성한 EC2 VPC Endpoint 구성이 있을 경우, 해당 EC2 VPC Endpoint를 사용하게 됩니다.

따라서 Cluster 및 Node SG 443 OUT -> EC2 VPC Endpoint SG 443 IN이 세팅되어있어야 합니다.

 

 

위와 같이 말씀드리는 이유는 해당내역이 Docs에 구체적으로 서술되어있지 않아,

Support를 통해 위와 같이 답변을 받아 처리하였고, 많은 시간을 소비했기 때문입니다. 

 

요즘 구성된 클러스터가 아닌 이전에 구성된 EKS 클러스터에서 CNI 1.6.3을 사용하고 있었는데,

해당 방화벽 오픈 없이 여전히 Master - Worker 통신 및 서비스가 잘 되는 상태입니다.

 

하지만 업데이트를 하거나, 최근에 구성한 EKS의 경우에는 아래와 같은 에러가 발생합니다.

 

aws-node pod error

 

 

kubelet log

 

Dec 22 04:40:33 ip-xx-xxx-xxx-xxx kubelet: E1222 04:40:33.955593    4579 kubelet.go:2195] Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

Dec 22 04:40:37 ip-xx-xxx-xxx-xxx kubelet: I1222 04:40:37.587320    4579 trace.go:116] Trace[1837814751]: "Reflector ListAndWatch" name:k8s.io/kubernetes/pkg/kubelet/kubelet.go:517 (started: 2020-12-22 04:40:07.586950506 +0000 UTC m=+6088.204216316) (total time: 30.000351801s):
Dec 22 04:40:37 ip-xx-xxx-xxx-xxx kubelet: Trace[1837814751]: [30.000351801s] [30.000351801s] END
Dec 22 04:40:37 ip-xx-xxx-xxx-xxx kubelet: E1222 04:40:37.587334    4579 reflector.go:178] k8s.io/kubernetes/pkg/kubelet/kubelet.go:517: Failed to list *v1.Service: Get https://{your eks cluster endpoint}/api/v1/services?limit=500&resourceVersion=0: dial tcp xx.xxx.xxx.xxx:443: i/o timeout
Dec 22 04:40:37 ip-xx-xxx-xxx-xxx kubelet: W1222 04:40:37.662806    4579 transport.go:260] Unable to cancel request for *exec.roundTripper
Dec 22 04:40:37 ip-xx-xxx-xxx-xxx kubelet: E1222 04:40:37.662879    4579 controller.go:136] failed to ensure node lease exists, will retry in 7s, error: Get https://{your eks cluster endpoint}/apis/coordination.k8s.io/v1/namespaces/kube-node-lease/leases/ip-xx-xxx-xxx-xxx.ap-northeast-2.compute.internal?timeout=10s: context deadline exceeded (Client.Timeout exceeded while awaiting headers)

 

따라서 EC2 VPC Endpoint를 사용하는데,

최근에 만든 EKS Cluster이거나 기존에 방화벽을 열어두지 않고 사용하던 클러스터에서 업데이트를 한다면

방화벽을 꼭 열어주시기 바랍니다.

 

정확한 원인은 아니지만,

KubeProxy가 EKS Cluster Endpoint를 못찾아서 발생하는 에러들도 있다고 Github들에 나와있으니

Endpoint로 통신하는 구조인 EKS에서는 EC2 VPC Endpoint를 사용할 경우, 방화벽 연동이 필수가 된 것 같습니다.

 

현재 AWS Docs에서 권유하는 버전은 아래와 같습니다.

 

AWS Docs 참조

 

1.18로 업그레이드 하는 기준으로 말씀드리겠습니다.

 

EKS Cluster 및 노드 버전의 경우는 콘솔을 통해서 업데이트 해주시면 되니 생략하도록 하겠습니다.

 

1.17이하 부터 사용하여 업데이트 한 경우라면, 아래와 같은 부분이 남아있습니다.

 

kubectl get configmap coredns -n kube-system -o yaml |grep upstream

 

 

따라서 edit을 하여 upstream이 있는 부분을 삭제해주시면 됩니다.

 

kubectl edit configmap coredns -n kube-system -o yaml

 

그리하여, 아래와 같이 만들어 주신 후 저장해주시면 됩니다.

 

 

이제 버전을 수정하겠습니다.

 

CoreDNS 버전을 아래와 같이 검색하겠습니다.

저는 현재 아래와 같습니다.

 

kubectl get deployment coredns --namespace kube-system -o=jsonpath='{$.spec.template.spec.containers[:1].image}'

 

 

아래 명령어를 수행하여 버전을 업그레이드 해주시면 됩니다.

리전의 경우 자신의 EKS Cluster Region에 맞게 수정해주시면 됩니다.

kubectl set image --namespace kube-system deployment.apps/coredns \
            coredns=602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/coredns:v1.7.0-eksbuild.1

 

Kube-Proxy 버전을 검색한 후 업데이트 하겠습니다.

 

kubectl get daemonset kube-proxy --namespace kube-system -o=jsonpath='{$.spec.template.spec.containers[:1].image}'

 

 

저는 맞지 않기 때문에 업데이트 해주도록 하겠습니다.

(영어 Docs를 보면 1.18.9를 적용하라 되어있어, 1.18.9를 적용하겠습니다.)

 

kubectl set image daemonset.apps/kube-proxy \
    -n kube-system \
    kube-proxy=602401143452.dkr.ecr.ap-northeast-2.amazonaws.com/eks/kube-proxy:v1.18.9-eksbuild.1

 

이제, 마지막으로 VPC CNI를 업데이트 하도록 하겠습니다.

 

버전체크는 아래 쉘에서 수행하시면 되고,

 

kubectl describe daemonset aws-node --namespace kube-system | grep Image | cut -d "/" -f 2

 

아래 명령어로 업데이트 해주시면 됩니다.

 

curl -o aws-k8s-cni.yaml https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/v1.7.5/config/v1.7/aws-k8s-cni.yaml
sed -i -e 's/us-west-2/ap-northeast-2/' aws-k8s-cni.yaml
kubectl apply -f aws-k8s-cni.yaml

 

이후 CNI Helper라는 것을 적용하시면, 관련하여 Cloudwatch에서 모니터링 하실 수 있습니다.

 

역시, CW VPCE를 사용하실 경우 방화벽 443을 서로 연동해주셔야합니다.

 

docs.aws.amazon.com/ko_kr/eks/latest/userguide/cni-metrics-helper.html

 

CNI 지표 헬퍼 - Amazon EKS

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다. CNI 지표 헬퍼 CNI 지표 헬퍼는 네트워크 인터페이스 및 IP 주소 정보를 스크

docs.aws.amazon.com

Docs 대로 따라하면 문제가 없습니다.

 

먼저 WorkerNode Role에 CW PutMetric 정책을 연결해주시면 됩니다.

 

cat << EOF > CNIMetricsHelperPolicy.json
#!/bin/bash
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "cloudwatch:PutMetricData",
      "Resource": "*"
    }
  ]
}
EOF

 

aws iam create-policy --policy-name CNIMetricsHelperPolicy \
--description "Grants permission to write metrics to CloudWatch" \
--policy-document file://CNIMetricsHelperPolicy.json

 

aws iam attach-role-policy \
--policy-arn arn:aws:iam::<111122223333>:policy/CNIMetricsHelperPolicy \
--role-name <eksctl-prod-nodegroup-standard-wo-NodeInstanceRole-GKNS581EASPU>

 

kubectl apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/release-1.7/config/v1.7/cni-metrics-helper.yaml

 

이렇게 끝나면 사용자 네임스페이스에 Kubernetes가 뜨게되고, CloudWatch에서 아래와 같이 보실 수 있습니다.

 

 

VPC CNI Update를 하며 있었던 이슈와 방법, CNI Helper에 대해서 알아봤습니다.