Kubernetes Engine 문제 해결
본 문서는 Kubernetes Engine 서비스와 관련된 주요 문제와 해결 방법을 정리한 문서입니다.
- Cluster Failed: 리소스 부족
- Cluster Failed: 내부 처리 오류
- kubectl: Namespace is forbidden
- Kubelet: Nameserver limits exceeded
- kubectl: Please enter Username
- kubectl: Unable to connect to the server
- CSI Provisioner deployment, pod
- helm: kubernetes cluster unreachable
- Istio: failed to call webhook
- Gateway API 마이그레이션 문제 해결
Cluster Failed: 리소스 부족
Cluster의 상태가 Failed로 변경된 후 다음의 에러가 발생합니다.
Error from server (Forbidden): the targeted Availability Zone "region-name", does not currently have sufficient capacity to support the cluster.
해당 에러는 클러스터 생성 시, 지정한 가용 영역 중 일부에 클러스터를 지원할 수 있는 충분한 용량이 확보되지 않은 경우 발생합니다.
▶️ 해결 방법: 클러스터가 상주할 수 없는 가용 영역이 있습니다. 서브넷이 속한 가용 영역을 다시 확인 후 클러스터를 재생성합니다.
Cluster Failed: 내부 처리 오류
Cluster의 상태가 Failed로 변경된 후 다음의 에러가 발생합니다.
Error from server (Forbidden): Cluster processing has failed because of an internal error, exception or failure
해당 에러는 클러스터 생성 시, 내부 시스템 오류 또는 예외 상황으로 인해 클러스터 생성이 실패한 경우 발생합니다.
▶️ 해결 방법: 클러스터 정보를 포함하여 헬프데스크로 문의합니다.
kubectl: Namespace is forbidden
kubectl 제어 설정을 모두 완료했지만, kubectl 명령어를 사용하면 다음의 에러가 발생합니다.
Error from server (Forbidden): namespaces is forbidden: User "<user_email@example.com>" cannot list resource "namespaces" in API group "" at the cluster scope
해당 에러는 사용자가 액세스 키를 발급할 때 선택한 프로젝트와 제어해야 할 클러스터의 프로젝트가 일치하지 않을 때 발생합니다.
▶️ 해결 방법: 액세스키 생성 시 프로젝트를 지정할 때 제어할 클러스터가 속한 프로젝트를 지정해야 합니다. 자세한 액세스 키 생성 방법은 액세스 키 발급을 참고하시기 바랍니다.
Kubelet: Nameserver limits exceeded
Kubernetes Engine 클러스터에서 노드 풀을 생성한 후, kublet log 부분에 다음의 에러가 발생합니다.
카카오클라우드의 Kubernetes Engine을 통해 생성된 노드는 Linux(Ubuntu) 기반으로 3개의 DNS nameserver 레코드까지 추가가 가능하며,
Kubernetes는 1개의 DNS nameserver 레코드를 사용해야 합니다.
이러한 제약 상황에서 만약 노드가 이미 3개의 네임서버를 사용하고 있다면, Nameserver limit exceeded 에러가 발생합니다.
Jul 15 16:42:22 {Node-name} kubelet[6020]: E0715 16:42:22.417041 6020 dns.go:153] "Nameserver limits exceeded" err="Nameserver limits were exceeded, some nameservers have been omitted, the applied nameserver line is: ~ ~ ~"
▶️ 해결 방법: 노드 풀 생성 시 [고급 설정] > [사용자 스크립트] 등을 통해 네임서버를 resolv.conf 파일에 추가했는지 확인하고, nameserver 레코드 수를 조정합니다.
DNS 서버 레코드 제한에 대한 이슈는 쿠버네티스 공식 가이드를 참고해 주세요.
kubectl: Please enter Username
kubectl 제어 설정을 모두 완료했지만 kubectl 명령어를 사용하면 다음의 에러가 발생합니다.
Please enter Username:
이 에러는 kubeconfig 파일의 내용 중 contexts > context > cluster > user에 설정된 클러스터의 이름과 users > name에 설정된 이름과 싱크가 맞지 않아 발생합니다.
▶️ 해결 방법: contexts > context > cluster > user에 설정된 클러스터의 이름과 users > name에 설정된 이름을 동일하게 설정합니다.
kubectl: Unable to connect to the server
kubectl 제어 설정을 모두 완료했지만, kubectl 명령어를 사용하면 다음의 에러가 발생합니다.
Unable to connect to the server: getting credentials: exec: executable kic-iam-auth failed with exit code 1
사용자 인증은 kubeconfig 파일의 users > user > exec > env에 설정된 액세스 키의 정보를 활용합니다. 위 에러는 이 액세스 키의 정보가 일치하지 않아 발생합니다.
▶️ 해결 방법: 사용자 인증 설정을 참고하여 사용자 인증을 재설정합니다.
CSI Provisioner deployment, pod
cinder-csi 설치 완료 후 파드 상태가 CrashLoopBackOff로 표시되며, 다음의 에러가 발생합니다.
E0123 07:54:11.985138 1 openstack.go:102] Failed to open OpenStack configuration file: open /etc/kubernetes/cloud.conf: no such file or directory
E0123 07:54:11.985145 1 openstack.go:144] GetConfigFromFiles [/etc/kubernetes/cloud.conf] failed with error: open /etc/kubernetes/cloud.conf: no such file or directory
이 에러는 helm chart 설치 시 필요한 파라미터를 추가하지 않아 발생합니다.
▶️ 해결 방법: helm install cinder-csi 실행 시 필수 파라미터를 입력하여 재설치합니다.
helm install cinder-csi cpo/openstack-cinder-csi \
--version 2.3.0 \
--set secret.enabled=true \ #필수 파라미터
--set secret.name=cloud-config \ #필수 파라미터
--namespace kube-system
helm: kubernetes cluster unreachable
helm 설치하여 CLI를 통해 명령어 실행 시 Kubernetes cluster unreachable 에러가 발생합니다.
Kubernetes cluster unreachable: Get "http://localhost:8080/version": dial tcp [::1]:8080: connect: connection refused
helm은 쿠버네티스 클러스터와 연결에 필요한 정보를 등록해야 하지만 클러스터 정보를 가지고 있는 kubeconfig를 찾지 못해 에러가 발생합니다.
▶️ 해결 방법: kubeconfig.yaml 파일을 $KUBECONFIG 변수로 등록하는 방법과 --kubeconfig 옵션을 사용하는 방법은 다음과 같습니다.
-
$KUBECONFIG환경 변수를 등록합니다.export KUBECONFIG="{kubeconfig path} -
--kubeconfig옵션을 사용합니다.helm --kubeconfig={Download_Path/kubeconfig.yaml} list
Istio: failed to call webhook
이 오류는 Kubernetes Engine 클러스터에 Istio를 구성할 때 API 서버가 istiod의 Admission Webhook 엔드포인트와 통신할 수 없으면 발생합니다.
Error creating: Internal error occurred: failed calling webhook "namespace.sidecar-injector.istio.io": failed to call webhook: Post "https://istiod.istio-system.svc:443/inject?timeout=10s": context deadline exceeded
Kubernetes 1.32 및 1.33 클러스터에서는 컨트롤 플레인 노드가 컨테이너 네트워크에 포함되어 있지 않아 Admission Webhook 서버와 통신하지 못할 수 있습니다.
이 해결 방법은 Kubernetes 1.32 및 1.33 클러스터에 적용합니다. API 서버가 istiod 파드에 접근할 수 있도록 istiod Deployment의 Pod spec에 hostNetwork: true와 dnsPolicy: ClusterFirstWithHostNet을 추가합니다.
kubectl edit deployment -n istio-system istiod
spec:
template:
spec:
hostNetwork: true
dnsPolicy: ClusterFirstWithHostNet
Kubernetes 1.34 이상 클러스터에서는 Konnectivity를 통해 API 서버와 Admission Webhook 서버가 통신하므로, Admission Webhook 서버 파드에 hostNetwork: true를 설정할 필요가 없습니다.
dnsPolicy 설정 정보
dnsPolicy 값별 동작은 다음과 같습니다.
| 설정 값 | 설명 |
|---|---|
Default | 노드의 /etc/resolv.conf 파일에 있는 설정을 사용하여 DNS 쿼리를 처리합니다. |
ClusterFirst | 클러스터 도메인 접미사(예: .cluster.local)와 일치하지 않는 DNS 쿼리를 상위 네임 서버로 전달합니다. |
ClusterFirstWithHostNet | hostNetwork: true를 사용하는 Pod가 클러스터 DNS 설정을 유지하도록 합니다. hostNetwork: true를 사용하는 Pod에 dnsPolicy: ClusterFirst를 설정하면 실제로는 Default 정책처럼 동작하므로, ClusterFirstWithHostNet을 명시적으로 설정해야 합니다. |
None | Pod가 Kubernetes 환경의 DNS 설정을 사용하지 않도록 합니다. 사용자 정의 DNS 서버가 필요한 Pod에 사용합니다. |
자세한 설명은 Kubernetes DNS 정책 문서를 참고하세요.
Gateway API 마이그레이션 문제 해결
Ingress에서 Gateway API로 마이그레이션하거나 Gateway API 리소스를 운영하면서 자주 발생하는 문제와 해결 방법입니다.
HTTPRoute의 Accepted 상태가 False인 경우
HTTPRoute의 상태와 이벤트를 확인하여 원인을 파악합니다.
kubectl --kubeconfig=$KUBE_CONFIG describe httproute <route-name> -n <namespace>
| Reason | 원인 | 해결 방법 |
|---|---|---|
InvalidListener | Gateway의 리스너가 유효하지 않음 (예: TLS Secret 누락) | Gateway의 리스너 Conditions를 확인하고, TLS Secret이 올바르게 생성되어 있는지 확인합니다. |
NotAllowedByListeners | HTTPRoute의 호스트명이 Gateway 리스너의 hostname과 불일치 | HTTPRoute의 hostnames와 Gateway 리스너의 hostname을 비교하여 일치시킵니다. |
NoMatchingParent | parentRefs에 지정한 Gateway를 찾을 수 없음 | Gateway의 이름과 네임스페이스가 올바른지 확인합니다. |
RefNotPermitted | 다른 네임스페이스의 Gateway를 참조할 권한이 없음 | Gateway의 allowedRoutes.namespaces.from이 All로 설정되어 있거나, ReferenceGrant가 생성되어 있는지 확인합니다. |
Gateway의 PROGRAMMED 상태가 False인 경우
Gateway의 상태와 이벤트를 확인하여 원인을 파악합니다.
kubectl --kubeconfig=$KUBE_CONFIG describe gateway <gateway-name> -n <namespace>
| Reason | 원인 | 해결 방법 |
|---|---|---|
AddressNotAssigned | 로드 밸런서 프로비저닝 실패 | kubectl get svc -n <gateway-namespace>로 EXTERNAL-IP 상태를 확인합니다. <pending> 상태가 지속되면 로드 밸런서 프로비저닝에 문제가 있을 수 있습니다. |
InvalidCertificateRef | TLS Secret이 존재하지 않거나 형식이 올바르지 않음 | kubectl get secret <name> -n <namespace>로 존재 여부를 확인하고, kubernetes.io/tls 타입인지 확인합니다. |
InvalidGatewayClass | GatewayClass가 존재하지 않거나 Accepted 상태가 아님 | kubectl get gatewayclass로 상태를 확인합니다. |
백엔드 서비스로 트래픽이 전달되지 않는 경우
HTTPRoute와 백엔드 서비스의 연결 설정을 확인합니다.
-
HTTPRoute의
backendRefs에 지정한 서비스 이름과 포트가 올바른지 확인합니다.백엔드 서비스 확인kubectl --kubeconfig=$KUBE_CONFIG get svc -n <namespace> -
HTTPRoute와 백엔드 서비스가 동일한 네임스페이스에 있는지 확인합니다. 다른 네임스페이스의 서비스를 참조하려면 ReferenceGrant가 필요합니다.
-
HTTPRoute의 Conditions에서
ResolvedRefs상태를 확인합니다.ResolvedRefs 상태 확인kubectl --kubeconfig=$KUBE_CONFIG get httproute <route-name> -n <namespace> -o jsonpath='{.status.parents[0].conditions[?(@.type=="ResolvedRefs")]}'
ingress2gateway 변환 결과가 예상과 다른 경우
변환 명령과 입력 리소스 설정을 확인합니다.
--providers플래그에 올바른 프로바이더를 지정했는지 확인합니다 (예:ingress-nginx,istio,kong등).- 자동 생성된 Gateway 리소스의
gatewayClassName과namespace가 실제 환경과 일치하는지 확인하고, 필요에 따라 수정합니다.