Amazon EKS에서 kubectl 명령을 실행할 수 없는 이유는 무엇인가요?
최종 업데이트 날짜: 2021년 11월 24일
Amazon Elastic Kubernetes Service(Amazon EKS)에서 kubectl exec, kubectl logs, kubectl attach 또는 kubectl port-forward와 같은 kubectl 명령을 정상적으로 실행할 수 없습니다.
해결 방법
Amazon EKS 클러스터에서 kubectl exec, kubectl logs, kubectl attach, kubectl port-forward와 같은 명령을 실행하지 못하는 가장 일반적인 이유는 API 서버가 작업자 노드에서 실행 중인 kubelet과 올바르게 통신하지 못하기 때문입니다.
이 문제를 해결하려면 다음을 확인하세요.
- 포드가 보조 클래스 없는 도메인 간 라우팅(CIDR) 범위에서 실행 중입니다.
- 제어 영역 및 노드에 사용되는 보안 그룹이 인바운드 및 아웃바운드 규칙에 대한 모범 사례를 사용합니다.
- aws-auth ConfigMap에 노드와 연결된 Kubernetes 사용자 이름과 함께 올바른 AWS Identity and Access Management(IAM) 역할이 있습니다.
- 새 인증서를 제출하기 위한 요구 사항이 충족되었습니다.
포드가 보조 클래스 없는 도메인 간 라우팅(CIDR) 범위에서 실행 중임
Amazon EKS는 클러스터가 생성된 후 Virtual Private Cloud(VPC)에 추가된 추가 CIDR 블록에서 서브넷에서 시작된 노드와 곧바로 통신할 수 없습니다. 기존 클러스터에 CIDR 블록을 추가하여 발생하는 업데이트된 범위를 Amazon EKS가 인식하는 데 5시간까지 걸릴 수 있습니다. 자세한 내용은 클러스터 VPC 고려 사항을 참조하세요.
포드가 보조 CIDR 범위에서 실행 중인 경우 다음을 수행합니다.
- 이러한 명령이 작동할 때까지 최대 5시간 기다립니다.
- 자동화를 성공적으로 완료하려면 각 서브넷에 5개 이상의 사용 가능한 IP 주소가 있어야 합니다.
다음 예제 정책을 사용하여 VPC의 모든 서브넷에 대해 사용 가능한 IP 주소를 확인합니다.
[ec2-user@ip-172-31-51-214 ~]$ aws ec2 describe-subnets --filters "Name=vpc-id,Values=vpc-078af71a874f2f068" | jq '.Subnets[] | .SubnetId + "=" + "\(.AvailableIpAddressCount)"'
"subnet-0d89886ca3fb30074=8186"
"subnet-0ee46aa228bdc9a74=8187"
"subnet-0a0186a277b8b6a51=8186"
"subnet-0d1fb1de0732b5766=8187"
"subnet-077eff87a4e25316d=8187"
"subnet-0f01c02b04708f638=8186"
제어 영역 및 노드에 사용되는 보안 그룹에 필요한 최소한의 인바운드 및 아웃바운드 규칙이 있음
API 서버가 작업 노드에서 실행되는 동안 kubelet에 대한 API 호출을 수행하려면 필요한 최소한의 인바운드 및 아웃바운드 규칙이 있어야 합니다. 제어 영역 및 노드에 사용되는 보안 그룹에 필요한 최소한의 인바운드 및 아웃바운드 규칙이 있는지 확인하려면 Amazon EKS 보안 그룹 고려 사항을 참조하세요.
aws-auth ConfigMap에 노드와 연결된 Kubernetes 사용자 이름과 함께 올바른 IAM 역할이 있음
노드와 연결된 Kubernetes 사용자 이름을 가진 올바른 IAM 역할이 aws-auth ConfigMap에 적용되어야 합니다. aws-auth ConfigMap을 클러스터에 적용하려면 클러스터의 사용자 또는 IAM 역할 관리를 참조하세요.
새 인증서를 제출하기 위한 요구 사항이 충족됨
Amazon EKS 클러스터에서는 노드의 kubelet이 자체적으로 제공 인증서를 제출하고 교체해야 합니다. 제공 인증서를 사용할 수 없으면 인증서 오류가 발생합니다.
1. 다음 명령을 실행하여 kubelet 서버 인증서의 유효성을 검증합니다.
cd /var/lib/kubelet/pki/# use openssl command to validate kubelet server cert
sudo openssl x509 -text -noout -in kubelet-server-current.pem
출력은 다음과 유사합니다.
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
1e:f1:84:62:a3:39:32:c7:30:04:b5:cf:b0:91:6e:c7:bd:5d:69:fb
Signature Algorithm: sha256WithRSAEncryption
Issuer: CN=kubernetes
Validity
Not Before: Oct 11 19:03:00 2021 GMT
Not After : Oct 11 19:03:00 2022 GMT
Subject: O=system:nodes, CN=system:node:ip-192-168-65-123.us-east-2.compute.internal
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:7f:44:c6:95:7e:0f:1e:f8:f8:bf:2e:f8:a9:40:
6a:4f:83:0a:e8:89:7b:87:cb:d6:b8:47:4e:8d:51:
00:f4:ac:9d:ef:10:e4:97:4a:1b:69:6f:2f:86:df:
e0:81:24:c6:62:d2:00:b8:c7:60:da:97:db:da:b7:
c3:08:20:6e:70
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
A8:EA:CD:1A:5D:AB:DC:47:A0:93:31:59:ED:05:E8:7E:40:6D:ED:8C
X509v3 Authority Key Identifier:
keyid:2A:F2:F7:E8:F6:1F:55:D1:74:7D:59:94:B1:45:23:FD:A1:8C:97:9B
X509v3 Subject Alternative Name:
DNS:ec2-3-18-214-69.us-east-2.compute.amazonaws.com, DNS:ip-192-168-65-123.us-east-2.compute.internal, IP Address:192.168.65.123, IP Address:3.18.214.69
2. kubelet 로그에서 인증서 오류를 검토합니다. 오류가 표시되지 않으면 새 인증서를 제출하기 위한 요구 사항이 충족된 것입니다.
kubelet 로그 인증서 오류의 예:
kubelet[8070]: I1021 18:49:21.594143 8070 log.go:184] http: TLS handshake error from 192.168.130.116:38710: no serving certificate available for the kubelet
참고: 더 자세한 로그를 확인하려면 --v=4 플래그가 있는 상세 로그를 사용하도록 kubelet을 켠 다음 작업자 노드에서 kubelet을 다시 시작하세요. kubelet 상세 로그는 다음과 유사합니다.
#kubelet verbosity can be increased by updating this file ...max verbosisty level --v=4
sudo vi /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
# Normal kubelet verbosisty is 2 by default
cat /etc/systemd/system/kubelet.service.d/10-kubelet-args.conf
[Service]
Environment='KUBELET_ARGS=--node-ip=192.168.65.123 --pod-infra-container-image=XXXXXXXXXX.dkr.ecr.us-east-2.amazonaws.com/eks/pause:3.1-eksbuild.1 --v=2
#to restart the demon and kubelet
sudo systemctl daemon-reload
sudo systemctl restart kubelet
#make sure kubelet in running state
sudo systemctl status kubelet
# to stream logs for kubelet
journalctl -u kubelet -f
3. 오류가 보이면, 작업자 노드에서 kubelet 구성 파일(/etc/kubernetes/kubelet/kubelet-config.json)을 확인한 다음, RotateKubeletServerCertificate 및 serverTLSBootstrap 플래그가 True로 나열되어 있는지 확인하세요.
"featureGates": {
"RotateKubeletServerCertificate": true
},
"serverTLSBootstrap": true,
4. 다음 eks:node-bootstrapper 명령을 실행하여 kubelet에 인증서 서명 요청(CSR)을 제출하는 데 필요한 역할 기반의 액세스 제어(RBAC) 시스템 권한이 있는지 확인합니다.
$ kubectl get clusterrole eks:node-bootstrapper -o yaml
apiVersion: rbac.authorization.k8s.io/v1
출력은 다음과 유사합니다.
kind: ClusterRole
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"rbac.authorization.k8s.io/v1","kind":"ClusterRole","metadata":{"annotations":{},"labels":{"eks.amazonaws.com/component":"node"},"name":"eks:node-bootstrapper"},"rules":[{"apiGroups":["certificates.k8s.io"],"resources":["certificatesigningrequests/selfnodeserver"],"verbs":["create"]}]}
creationTimestamp: "2019-11-17T05:01:38Z"
labels:
eks.amazonaws.com/component: node
name: eks:node-bootstrapper
resourceVersion: "168"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterroles/eks%3Anode-bootstrapper
uid: 564b6a3a-08f7-11ea-9d07-06e275d1e5e0
rules:
- apiGroups:
- certificates.k8s.io
resources:
- certificatesigningrequests/selfnodeserver
verbs:
- create
필요한 RBAC 권한에는 다음이 포함됩니다.
- apiGroups: ["certificates.k8s.io"]
resources: ["certificatesigningrequests/selfnodeserver"]
verbs: ["create"]
5. 다음 명령을 실행하여 클러스터 역할 eks:node-bootstrapper가 system:bootstrappers 및 system:nodes에 바인딩되어 있는지 확인합니다. 이렇게 하면 kubelet이 자체적으로 제공 인증서를 제출하고 교체할 수 있습니다.
$ kubectl get clusterrolebinding eks:node-bootstrapper -o yaml
apiVersion: rbac.authorization.k8s.io/v1
출력은 다음과 유사합니다.
kind: ClusterRoleBinding
metadata:
labels:
eks.amazonaws.com/component: node
name: eks:node-bootstrapper
resourceVersion: "167"
selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/eks%3Anode-bootstrapper
uid: 564a00de-08f7-11ea-9d07-06e275d1e5e0
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: eks:node-bootstrapper
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:bootstrappers
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: system:nodes