DevOps

[AWS]EKS 세팅 Trouble Shooting 정리

Hazel_song 2022. 5. 31. 15:40
728x90

[AWS]EKS 시리즈

1. EKS 세팅 실습하기(링크)
2. EKS 세팅 트러블슈팅 정리(현재글)
3. EKS 서비스 배포(링크)

Error 1-1: add-on coredns status : degraded

error message : InsufficientNumberOfReplicas
description : it doesn't have the desired number of replicas

-> 해당 글을 참고했다.

kubectl describe deployment coredns --namespace kube-system

위의 명령어를 통해 coredns에 대해서 자세하게 살펴봄

replica가 두개 필요한데 사용불가한 상태이다.

 

아래 명령어로 replicas 조절 가능

* replicas = 파드를 유지할 개수

kubectl scale -n kube-system deployment/coredns --replicas={숫자}

아래 명령어로 재시작해주면 된다고 하는데 재시작 해도 degraded 상태

kubectl rollout restart -n kube-system deployment coredns

 

 

위의 명령어 실행해주니

아래는 coredns가 사용가능한 상태일때의 condition이다.

 

replicaset 수를 0으로 조정하고 재시작한다음 다시 2개로 조정하고 재시작하니까 해결!

? replicas가 coredns와 어떤 관계가 있는 건지?
replicaset에 대해서
coredns에 대해서
즉 위의 에러 메시지는 coredns가 pod에 실행되어야 하는데 그에 맞는 적절한 replicas가 없어서 발생하는 에러라고 이해했다.

? replicas(파드를 유지할 개수) 2개 미만으로 하니 해결되었다. 2개 이상부터 문제가 생겼다.. 흠

 

참고자료

https://serverfault.com/questions/1077378/aws-eks-add-on-coredns-status-as-degraded-and-node-group-creation-failed-is-una

https://may9noy.tistory.com/237

https://jonnung.dev/kubernetes/2020/05/11/kubernetes-dns-about-coredns/

 

Error 1-2: add-on coredns status : pending

 

aws 문서를 참고해서 DNS 엔드포인트가 노출되고 coreDNS 포드를 가리키는지 확인했다.

kubectl -n kube-system get endpoints kube-dns

아래와 같은 결과가 떴다.

왼쪽과 같이 endpoint가 없다.

 

아래 명령어로 pod의 상세 내역을 보고 해당 상태에 대한 사유(event)를 찾아본다.

kubectl describe -n {namespace} pod {pod-name}

no nodes available to schedule pods 

위의 에러는 스케줄링할 노드가 없을 때 발생하는 에러이다. 즉 pod를 스케줄링 할 노드가 없다는 의미인 것이다.

kubectl get nodes 와 kubectl describe nodes 명령을 사용해 노드가 정상적으로 동작하는지 확인해야 한다. 

-> 확인해보니까 no resources found라고 뜬다. 

 

즉  node group 부터 생성해야 coredns를 스케줄링할 노드가 생기게 되는 것이고, 노드그룹을 생성하고 다시 확인해보는 것으로 

 

 

참고자료

https://aws.amazon.com/ko/premiumsupport/knowledge-center/eks-pod-status-troubleshooting/

https://kubernetes.io/docs/tasks/debug/debug-application/debug-pods/#my-pod-stays-pending

 

 

Error 2: node  not ready

각 노드를 클릭해서 로그를 확인해보니 아래와 같은 에러 메시지

runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized 

Unhealthy nodes in the kubernetes cluster

ssh 접속해서 컨테이너와 노드 그룹 현황 파악

-> 노드(instance)는 금방 생성되지만, 노드 그룹은 생성되는데 시간이 조금 걸린다. creating 상태가 끝나고 난다음에도 ready 상태가 되지 않으면 아래의 ssh 명령어로 container 접속하기

    1. eks cluster connect : aws eks --region ap-northeast-2 update-kubeconfig --name jyg-data-eks-test
    2. node  현황 파악 :  kubectl get pod --all-namespaces

aws-node와 proxy가 적어도 하나는 running 상태여야 하는데, aws-node가 둘다 waiting 상태

describe 명령어로 aws-node의 로그를 파악

"msg":"timeout: failed to connect service \":50051\" within 5s

위의 에러메시지가 출력

 

aws-node 포드가 실행상태인지 확인

kubectl get pods -n kube-system -l k8s-app=aws-node -o wide

running과 crashloofbackoff이 무한 반복중

restarts가 0이 되어야 완벽하게 실행된 것.

 

?? cni가 제대로 실행되지 않기 때문에 worker node를 사용할 수 없는 것인가? (링크 참고)
cni가 전체적으로 k8s의 네트워크 인터페이스역할을 한다.
아마도 해당 기능이 제대로 실행되지 않으니 각 노드와 서비스들이 통신하지 못하면서 장애가 발생한듯 하다.

 

해결방법 (1) CNI 교체

vpc-cni로 aws에서 제공해주는 aws-node말고 외부 툴을 설치해서 사용해보는 방법으로 해결해보려 한다(해당 블로그 참고)

-> 이러한 방법으로 cni를 외부 플러그인으로 바꾸어 주었기 때문에 생성시에 만든 OIDC 자격증명 공급자가 필요없게 되었다.

 

AWS CNI 단점
1. VPC CNI 사용자 지정 네트워킹을 통해 Pod에 할당할 수 있는 IP주소가 제한되어 Worker Node에 Pod를 배포할 수 있는 수가 제한이 됨.
2. 만약 WorkerNode 중 특정 Node만 인스턴스 유형과 사양을 높다면 해당 Node에 과부하가 걸릴 수 있음
이러한 이유 때문에 실제 EKS를 사용하는 경우Worker Node와 Pod 수가 다수가 되는 환경이라면 IP할당 문제 때문에 AWS CNI보다 IP 할당 제약이 없는 On-premise환경에서 사용되는 CNI가 필요할 수도 있음.
또한 Networking 성능 이슈, 방화벽(Network Policy) 성능에 따라 별도의 CNI를 사용해야하는 상황이 있을 수 있음.
그렇기 때문에 EKS도 고정적으로 AWS CNI를 사용하지 않고  On-premise CNI를 사용할 수 있음.

 

자세한 진행상황 및 명령어는 위의 블로그를 그대로 따라 진행하면 된다. 

나는 내가 직접 진행하면서 마주쳤던 장애와 진행 흐름 사항을 정리하려 한다.

 

위와 같은 이유로 인해서 AWS CNI가 아니라 별도의 CNI를 구축해줌.

CNI에도 종류가 많다. 이에 대해서는 해당 블로그 글을 참고

flannel cni에 대한 글이 많아서 해당 cni로 교체해주는 것으로 트러블슈팅을 했는데, 위의 표를 보니 flannel cni가 보안지원이 하나도 안돼서 calico cni로 교체하는 방식도 작업햇다.

 

1. calico CNI 교체 : 추천

느낀점은 급하게 트러블 슈팅을 하려고 하기 보다는 그 기능이 무슨 역할을 하는지 그래서 장애 원인은 무엇인지를 더 꼼꼼하게 파악해야겠다는 것이다.

기본적으로 aws공식문저 자체에서 calico cni를 세팅하는 방법에 대해서 안내하고 있다. 그리고 위의 표를 보면 알다시피, 웬만한 기능까지 다 제공하고 있다.

calico 자체가 managed kubernetes CNI인 EKS, AKS,GKE,IKS 또는 self managed kubernetes distribution인 kubernets 등 광범위한 플랫폼을 지원하고 있다.

그렇다보니 기본적으로 eks에서 calico cni로 네트워크 인터페이스를 교체해서 사용하는 방법도 너무 간단하다.

-> flannel cni로 교체하는 방법을 먼저 해서 그런가 이때랑 비교하면 엄청 간단하다.

이에 더해서 aws vpc cni보다 더 유연한 네트워크를 구성할 수 있다. 

 

1. aws자체에서 제공해주는 vpc cni인 aws node를 삭제해준다.

-> aws 콘솔 - add-on 에서 vpc-cni를 삭제 해줘도되고

-> cli로 아래 명령어를 통해 삭제해줘도 된다.

kubectl delete daemonset -n kube-system aws-node

 

2. eks 클러스터에 calico cni 설치

kubectl apply -f https://docs.projectcalico.org/manifests/calico-vxlan.yaml

3. eks 클러스터에서 pod 상태 확인

kubectl get pod --all-namespaces

모든 pod 가 실행이 되었다!

 

결국 coredns, node 모두 네트워크 인터페이스 쪽 문제로 통신에 문제가 생겨서 제대로 실행이 안되고 있었던 것 같다.
flannel cni로 세팅할 때는 엄청 많은 작업이 필요했는데 aws에서 calico cni를 사용할수 있도록 내부적으로 기능을 제공하다보니 세팅이 좀 더 쉬운가 보다.

 

 

2. flannel cni 교체

일반적으로 온프렘 환경에서 k8s를 구동하는 경우 그냥 flannel을 설치해주고 실행하면 된다.

즉 아마 일반적으로 구글에서 검색했을 때 볼수있는 해결책으로 

flannel을 설치만 해주면

Error registering network: failed to acquire lease: node pod cidr not assigned

위와 같은 애러가 발생할 것이다.

eks의 경우 kubeadm init 명령을 사용할 수 없으므로 별도로 CoreOs를 구축하고 그 안에 etcd를 세팅한 다음에, eks 내에서 만들어준 flannel pod가 해당 etcd를 바라보도록 해야한다.

 

1. 우선 기존에 aws에서 기본적으로 설치해주는 aws cni(aws-node)를 삭제해야 한다.

ssh 쉘로도 진행가능하지만, 콘솔로도 진행 가능하다. 

클러스터 콘솔 > add-on > vpc-cni remove

 

2. CoreOs 인스턴스를 세팅해준다.

위의 블로그를 참고해서 aws cli명령어로 서버를 세팅해주니 public elastic IP가 자동할당되지 않는 상태로 서버가 만들어 져서 또 ip 설정해주고 그러는게 조금 귀찮았다...

 

개인적으로 가능하면, aws 콘솔로 인스턴스를 만드는 것을 추천한다.

처음에 aws cli로 서버를 만들고 그냥 private ip로 접속해서 etcdctl을 설치하려고 하니 자꾸 connection time out이 발생했다.
고민하다가 설마 싶어서 콘솔로 인스턴스를 만들어주고 설치하니 잘되었다.

콘솔로 인스턴스를 만들때 AMI를 선택할 때

-> 위의 화면에서 browe more AMIs를 클릭해주고

-> community AMIs > Fedora linuz/unix를 선택해주자

그러면 설정가능한 fedora os ami 리스트들이 뜬다.

그중에서 coreos 중 아무거나 선택해주자.(coreos가 뭔지는 위의 블로그 링크를 참고하자)

 

coreos에 대해서 간단히 설명하자면 일반 리눅스와는 다르게 컨테이너 런타임 구동에 특화된 최초의 클라우드 기반 운영체제이다.

 

3. etcdctl 설치하기

export ETCD_VER=v3.4.0

curl -o etcd-${ETCD_VER}-linux-amd64.tar.gz  https://storage.googleapis.com/etcd/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz

tar xzvf etcd-${ETCD_VER}-linux-amd64.tar.gz

sudo mv etcd-${ETCD_VER}-linux-amd64/etcdctl /usr/local/bin/etcdctl

sudo mv etcd-${ETCD_VER}-linux-amd64/etcd /usr/local/bin/etcd

etcdctl

etcd --version

 

 

4. etcd 토큰 발급

export TOKEN=$(curl -sw "\n" 'https://discovery.etcd.io/new?size=1' | cut -d "/" -f 4)

 

5. etcd 생성

cat > etcd_conf.yaml << EOF | sed 's/[\]//g' > etcd_conf.yaml

위의 명령어로 파일을 오픈해준 다음,

advertise-client-urls:       http://{PUBLIC_IPV4}:2379
initial-advertise-peer-urls: http://{PRIVATE_IPV4}:2380
listen-client-urls:          http://0.0.0.0:2379
listen-peer-urls:            http://{PRIVATE_IPV4}:2380
discovery:                   https://discovery.etcd.io/{TOKEN}
EOF

위의 부분에서 {}괄호 부분에 알맞은 정보들을 입력

-> ipv는 fedora coreos의 ip주소들이다.

 

6. etcd 실행

etcd --config-file ./etcd_conf.yaml

 

7. etcdctl 실행

위에서 실행한 터미널 창은 그대로 두고, 새로운 터미널 창을 열어서 실행한다. 

10.244.0.0/16로 flannel ip 대역을 설정하기 위한 작업이다.

export ETCDCTL_API=3
etcdctl put /coreos.com/network/config '{"Network":"10.244.0.0/16", "SubnetLen": 24, "Backend": {"Type": "vxlan", "VNI": 1}}'

 

export ETCDCTL_API=2

-> 해당 명령어 실행 후 set을 하려니 자꾸 에러가 났다. 적합한 json,,,endpoint.,,가 아니라고,,

그래서 해당 부분은 건너뛰었다.

 

 

8. eks에 flannel 배포

kubectl 명령이 가능한 인스턴스에서 작업한다.

(나의 경우는 private에 세팅한 eks 노드에 접속하기 위해 bastion server를 public에 구축해 주었으므로 bastion server에서 해당 작업을 진행했다.)

 

curl -o flannel.yaml https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

위의 명령어로 flannel.yaml 파일을 설치.

 

vi flannel.yaml

위의 명령어로 해당 파일에 접속해서 파일을 수정해준다.

수정본은 위의 블로그를 참고. 블로그에서 정리된 그대로 해주니까 특별히 에러가 없었다.

 

9. flannel.yaml 배포

kubectl apply -f flannel.yaml

 

그리고 파드 상태를 확인하니 cni 역할을 하는 flannel이 잘 running 되고 있다.

 

10. flannel log 확인

kubectl logs {flannel pod name} -n kube-system

위의 명령어를 통해 flannel log 확인

Installing signal handlers

정도까지만 떠도 잘 진행되는 것이다.

 

해결방법(2) : aws CNI 에러 해결(~ing)

-> 해당 방법은 계속해서 해결 중이다...클러스터 초기 생성에는 vpc-cni가 active 상태이나, 노드 그룹을 만들어서 노드를 생성하면 service와 연결이 실패하는 등 장애가 발생한다.

 

aws-node 에러 메시지 다시 분석해보기

 probe failed: {"level":"info","ts":"2022-06-02T06:47:34.717Z","caller":"/usr/local/go/src/runtime/proc.go:225","msg":"timeout: failed to connect service \":50051\" within 5s"}

-> 위에 해결했던 coredns degraded warning 다시 발생

-> vpc - cni도 degraded warning 발생

-> vpc cni가 eks의 api server에 도달하지 못해서 발생하는 에러 인듯하다.

 

 

참고자료

flannel cni

https://sup2is.tistory.com/100

https://nirsa.tistory.com/292

https://aws.amazon.com/ko/premiumsupport/knowledge-center/eks-node-status-ready/

https://aws.amazon.com/ko/premiumsupport/knowledge-center/eks-cni-plugin-troubleshooting/

 

vpc cni

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

 

calico cni

https://www.goglides.dev/bkpandey/replace-aws-vpc-cni-with-calico-on-aws-eks-cluster-4ae7

https://kim-dragon.tistory.com/166

https://itnext.io/benchmark-results-of-kubernetes-network-plugins-cni-over-10gbit-s-network-updated-august-2020-6e1b757b9e49

 

Error 3: coredns status : waiting - ContainerCreating

-> flannel cni로 설정할 경우 발생하는 장애

 

위의 문제들이 해결되니, coredns가 pending 상태에서 벗어났지만 waiting 상태가 해결되지 않았다.

이를 위해서 flannel을 삭제하고 재설치해주었다.

 

다시 삭제한 이유는, 기존에 파드가 생성된 이후에 cni를 재설정해주면 해당 설정이 제대로 적용되지 않아서 네트워크 문제가 발생할수도 있다는 글을 봤기 때문이다.

그런데도 coredns는 계속 waiting상태였고, 아래와 같은 이벤트 메시지를 자세히 보니 cni로 설정해준 flannel과의 네트워크 작업에서 문제가 발생함을 알게 되었다.

FailedCreatePodSandBox
(combined from similar events): Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "7a27483fe5c16048874b96873d7cdac3296316402e4a7545f4a203277902f5a2" network for pod "coredns-6d9b6d68bb-2tg54": networkPlugin cni failed to set up pod "coredns-6d9b6d68bb-2tg54_kube-system" network: open /run/flannel/subnet.env: no such file or directory

worker node ec2 안에 접속해서 /run/flannel/subnet.env 만들어주기(해당 블로그 참고)

sudo vim /run/flannel/subnet.env
FLANNEL_NETWORK={flannel network ip}/16
FLANNEL_SUBNET={flannel.network ip}/24
FLANNEL_MTU=1450
FLANNEL_IPMASQ=true

성공!

모든 파드가 running 상태이다.

 

 

더 /다시 공부해야 할 부분

1. coredns/cni/proxy 등 k8s의 구성요소들에 대해서 즉 k8s의 기본 개념에 대해서 다시 공부해봐야겠다고 느꼈다.

2. 특히 aws에서 자체 제공해주는 cni로 인해 어떠한 문제가 발생했기에 노드그룹이 생성되는 것이 실패하는 결과까지 불러온 것일까?

3. flannel cni 포함 써드파티 cni들에 대해서 

4. coredns와 cni 네트워크 통신에 대해서(이 부분도 내가 해당 장애를 잘 이해한건지 모르겠다) 그리고 내가 해준 작업들이 어떠한 영향을 끼쳐서 해결하게 된건지?

5. 기본적으로 생성된 각 파드들과 / 이후 작업을 위해 만들어질 파드들의 통신 과정? 방법에 대해서 공부해야겠다. 

내가 계속 겪은 에러들의 기본적인 원인이 네트워크 통신이라는 생각이 들었기 때문이다.

 

참고자료

https://aws.amazon.com/ko/premiumsupport/knowledge-center/eks-failed-create-pod-sandbox/

https://kubernetes.io/ko/docs/concepts/cluster-administration/networking/

 

728x90