홈/인프라/kubectl Unauthorized(You must be logged in) 401 해결 6가지
인프라kubectl 401 해결You must be logged in Unauthorized

kubectl Unauthorized(You must be logged in) 401 해결 6가지

kubectl 'You must be logged in to the server (Unauthorized)' 401 에러를 토큰 만료, context 오인, EKS aws-iam-authenticator token expired 등 6가지 원인별 복붙 명령으로 5분 안에 해결하세요. 401과 403 차이도 표로 정리.

kubectl Unauthorized(You must be logged in) 401 해결 6가지
목차
  1. 401 vs 403: 가장 먼저 잡고 가야 할 개념
  2. 원인별 진단·해결 6가지 (복붙 명령 위주)
  3. 5분 빠른 진단 플로우
  4. 예방이 곧 트러블슈팅 — 토큰 자동 갱신과 context 분리
  5. 참고: 공식 문서
  6. 자주 묻는 질문 (FAQ)

kubectl "You must be logged in to the server (Unauthorized)" 해결 6가지

어제까지 멀쩡히 돌아가던 kubectl get pods가 오늘 갑자기 이렇게 뱉어냅니다.

TEXT
error: You must be logged in to the server (Unauthorized)

손에 땀이 나죠. 하지만 결론부터 말하면 이건 "권한이 없다(403)"가 아니라 "당신이 누구인지 클러스터가 증명하지 못했다(401)" 라는 인증(authentication) 영역의 문제입니다. 즉 RBAC 설정을 뒤지기 전에 내 신분증(토큰·인증서)이 유효한지부터 봐야 합니다.

이 시리즈(K8s_Troubleshooting_Guide)의 앞 편들이 스케줄링·이미지·네트워크 같은 워크로드 영역을 다뤘다면, 12편인 이번 글은 authn/authz 영역으로 넘어옵니다. 에러 문구를 그대로 검색해서 들어오셨다면, 5분 안에 원인을 특정하고 복붙 명령으로 복구하는 것을 목표로 갑니다.

401 vs 403: 가장 먼저 잡고 가야 할 개념

트러블슈팅의 절반은 "어느 동네 문제인지" 구분하는 데서 끝납니다.

에러 메시지HTTP 코드의미원인 영역1차 점검 대상
You must be logged in to the server (Unauthorized)401내가 누구인지 증명 실패 (인증)authn토큰/인증서 만료, context, 클라우드 자격증명
Forbidden ... cannot list resource ...403누군지는 알지만 권한 없음 (인가)authzRBAC Role/RoleBinding

핵심 비유: 401은 출입증 자체가 만료·분실된 상태, 403은 출입증은 있는데 그 방에 들어갈 권한이 없는 상태입니다. 이 글은 401에 집중하고, 403(RBAC)은 아래 5번 원인에서 경계선만 짚어줍니다.

비슷해 보이지만 원인이 다른 문구도 함께 구분해 두세요.

실제 출력 문구유력 원인1차 조치
You must be logged in to the server (Unauthorized)토큰·자격증명 만료(kubeadm이면 client 인증서 만료 포함), 잘못된 user아래 (1)~(4)
You must be logged in to the server (the server has asked for the client to provide credentials)자격증명이 비었거나 exec 플러그인 실패kubeconfig의 exec 블록, AWS_PROFILE 점검
Unable to connect to the server: x509: certificate has expired or is not yet valid대개 API 서버의 serving 인증서 만료 또는 클라이언트·서버 시계 오차. client 인증서 만료는 보통 이 문구가 아니라 Unauthorized로 나타남서버 인증서 만료일, kubeadm certs check-expiration, timedatectl
Error from server (Forbidden): ... cannot ...인증은 성공, 인가(RBAC) 실패(5)
Unable to connect to the server: dial tcp ...엔드포인트·네트워크 문제클러스터 엔드포인트 확인

원인별 진단·해결 6가지 (복붙 명령 위주)

(1) kubeconfig 토큰/인증서 만료

가장 흔한 범인입니다. 단기 만료(STS) 토큰이 보편화되면서 "몇 시간 뒤 갑자기" 패턴이 잦아졌습니다.

Bash
# 진단: 현재 사용자에 박힌 token / 인증서 정보 확인
kubectl config view --raw --minify

출력에서 user: 아래 token:이 있거나 exec: 블록이 있는지 봅니다. 정적 토큰이 박혀 있다면 만료됐을 가능성이 큽니다. 해결은 발급처에서 토큰을 재발급받아 갱신하는 것입니다(클라우드면 3번으로).

⚠️ --raw는 토큰과 인증서 원문을 그대로 출력합니다. 화면 공유나 이슈·채팅에 붙여넣을 때는 반드시 가리세요. 구조만 볼 때는 --raw 없이 kubectl config view --minify로 충분합니다.

(2) 잘못된 context/cluster 지정

멀티 클러스터 환경에서 dev 자격증명으로 prod를 찌르는 사고가 의외로 많습니다.

Bash
# 진단
kubectl config current-context          # 지금 어디를 보고 있나
kubectl config get-contexts             # * 표시가 현재 context

# 해결
kubectl config use-context <원하는-context-이름>

get-contexts 출력의 CLUSTER/AUTHINFO 컬럼이 의도한 값인지 확인하세요. 엉뚱한 context였다면 이것만으로 끝납니다.

(3) 클라우드 IAM 토큰 만료 (EKS / GKE)

EKS는 aws-iam-authenticator 또는 aws eks get-token(exec credential plugin)으로 STS 단기 토큰을 발급합니다. AWS 세션이 만료되면 토큰 발급 단계에서 AWS CLI 에러가 나거나 곧바로 401이 뜹니다.

Bash
# EKS: kubeconfig 자격증명 갱신
aws eks update-kubeconfig --region <리전> --name <클러스터명>

# 프로파일을 따로 쓴다면
aws eks update-kubeconfig --region <리전> --name <클러스터명> --profile <프로파일>

# GKE
gcloud container clusters get-credentials <클러스터명> --region <리전>

EKS에서 가장 흔한 함정: aws sts get-caller-identity로 AWS 자격증명 자체가 유효한지 먼저 확인하세요. AWS 세션이 죽어 있으면 update-kubeconfig를 해도 토큰 발급 단계에서 똑같이 401이 납니다.

Bash
aws sts get-caller-identity   # 여기서 에러나면 AWS 자격증명부터 갱신

자격증명은 유효한데도 401이라면 그 IAM 신원이 클러스터에 매핑돼 있는지 확인합니다. EKS는 aws-auth ConfigMap이나 EKS Access Entry에 등록된 신원만 받아들입니다. 클러스터 관리자에게 aws sts get-caller-identity의 ARN(역할을 맡았다면 역할 ARN)이 등록돼 있는지 확인을 요청하세요.

Bash
# 관리자 권한이 있는 쪽에서 확인
aws eks list-access-entries --cluster-name <클러스터명>
kubectl -n kube-system get configmap aws-auth -o yaml

(4) client-certificate 권한·만료 확인

온프레미스 kubeadm 클러스터는 보통 client certificate 인증을 씁니다. 인증서는 기본 1년 만료라 까먹기 딱 좋습니다.

Bash
# 인증서 만료일 디코딩
openssl x509 -in ~/.kube/client.crt -noout -enddate
# 출력 예) notAfter=Jun 16 09:00:00 2026 GMT

# kubeconfig에 base64로 박혀 있다면
kubectl config view --raw -o jsonpath='{.users[0].user.client-certificate-data}' | base64 -d | openssl x509 -noout -enddate

notAfter가 지났다면 만료입니다. 인증서 파일 경로/권한(ls -l로 600 권장)도 함께 점검하고, kubeadm이라면 kubeadm certs renew 계열로 갱신합니다.

x509: certificate has expired or is not yet valid가 나온다면 client 인증서보다 API 서버 인증서와 시계를 먼저 봅니다. kubectl이 서버가 내민 인증서를 검증하다 실패했다는 뜻이기 때문입니다.

Bash
# API 서버가 내미는 인증서의 유효기간 (kubeadm 기본 포트 6443)
echo | openssl s_client -connect <apiserver-host>:6443 2>/dev/null | openssl x509 -noout -dates

# 컨트롤 플레인 노드에서 전체 인증서 점검·갱신
sudo kubeadm certs check-expiration
sudo kubeadm certs renew all
# 갱신한 인증서는 컨트롤 플레인 static Pod를 재시작해야 반영됨:
# /etc/kubernetes/manifests/의 매니페스트를 잠시 다른 곳으로 옮겼다가 Pod가 내려간 뒤 되돌림

# 갱신된 admin.conf를 kubeconfig로 복사
sudo cp /etc/kubernetes/admin.conf $HOME/.kube/config

Kubernetes 문서: kubeadm 인증서 관리

(5) RBAC 미부여 — 여기서 401이 아니라 403이 뜬다

여기가 401과 403의 경계선입니다. 인증은 됐는데 권한이 없으면 401이 아니라 403이 떠야 정상입니다. 즉 401이라면 RBAC는 보통 범인이 아닙니다.

Bash
# 내가 특정 동작을 할 수 있는지 확인
kubectl auth can-i list pods
kubectl auth can-i get pods --namespace prod

출력이 no면 403(인가) 문제, 그런데도 메시지가 401이라면 인증 단계에서 이미 막힌 것이니 1~4번으로 돌아가세요.

Bash
kubectl auth whoami      # 클러스터가 나를 누구로 인식하는지 (kubectl 1.28+)

whoami가 예상과 다른 사용자라면 권한이 아니라 인증·context 문제입니다.

(6) 시스템 시계 오차

JWT/STS 토큰에는 NotBefore/Expiry가 박혀 있어, 클라이언트 시계가 어긋나면 멀쩡한 토큰도 "아직 유효하지 않음" 또는 "만료됨"으로 검증 실패합니다. VM·컨테이너 환경에서 의외로 자주 발생합니다.

Bash
# 진단
timedatectl              # System clock synchronized: yes 인지 확인

# 해결 (NTP 동기화)
sudo timedatectl set-ntp true
sudo systemctl restart systemd-timesyncd

System clock synchronized: no거나 실제 시각과 수 분 이상 차이 나면 동기화 후 재시도하세요.

5분 빠른 진단 플로우

막혔을 때 위에서 아래로 순서대로 내려가면 됩니다.

  1. context 확인 → kubectl config current-context 로 엉뚱한 곳을 보고 있는지 (원인 2)
  2. 토큰/인증서 만료 확인 → kubectl config view --raw --minify + openssl x509 -enddate (원인 1·4)
  3. 클라우드면 자격증명 갱신 → aws sts get-caller-identity → aws eks update-kubeconfig ... 또는 gcloud ... get-credentials (원인 3)
  4. 시계 확인 → timedatectl 동기화 여부 (원인 6)
  5. 여기까지 통과하면 권한 영역 → kubectl auth can-i ... 로 403 여부 확인 (원인 5)

실무 팁: 401 신고를 받으면 context 확인(원인 2)과 aws sts get-caller-identity(원인 3)부터 보는 습관을 들이면 복구가 빨라집니다.

예방이 곧 트러블슈팅 — 토큰 자동 갱신과 context 분리

복구도 중요하지만, 재발을 막는 게 진짜 실력입니다.

  • exec credential plugin으로 자동 갱신: 정적 토큰을 박지 말고, kubeconfig의 user.exec로 매 요청 시 토큰을 새로 받게 하세요. EKS 권장 방식입니다.
YAML
users:
- name: my-eks
  user:
    exec:
      apiVersion: client.authentication.k8s.io/v1beta1
      command: aws
      args:
        - eks
        - get-token
        - --cluster-name
        - my-cluster
        - --region
        - ap-northeast-2
  • 클러스터별 context·kubeconfig 분리: prod와 dev를 한 파일에 섞지 말고 KUBECONFIG=~/.kube/prod:~/.kube/dev 식으로 분리하거나, 셸 프롬프트에 현재 context를 노출(kube-ps1)해 오발사고를 줄이세요.

  • KUBECONFIG 병합 우선순위 확인: 여러 파일을 병합하면 같은 이름의 user·context는 목록에서 먼저 나온 파일의 값이 채택됩니다. 재발급했는데도 401이면 echo $KUBECONFIG로 파일 순서를 보고, kubectl config view --minify로 실제 채택된 user를 대조하세요.

  • CI/CD 러너는 단기 토큰으로: Kubernetes 1.24부터 ServiceAccount 토큰 Secret이 자동 생성되지 않고, Pod에는 만료가 있는 bound 토큰이 주입됩니다. 러너가 오래전에 복사해 둔 토큰에 의존하지 말고, 실행마다 kubectl create token <SA이름> --duration=1h(TokenRequest API)로 발급받거나 클라우드의 OIDC 연동을 쓰세요.

핵심 명령 요약: current-context로 위치 확인 → config view --raw/openssl x509로 만료 확인 → aws eks update-kubeconfig로 갱신 → timedatectl로 시계 점검 → auth can-i로 권한 구분.

다음 편 예고: K8s_Troubleshooting_Guide 13편 — 403 Forbidden과 RBAC 권한 설계 트러블슈팅에서 이번에 살짝 짚은 인가(authz) 영역을 본격적으로 파고듭니다.

참고: 공식 문서

이 글에서 다루는 동작·설정·에러의 1차 출처는 다음 공식 문서입니다. 버전별 옵션과 정확한 동작은 여기서 확인하세요.

자주 묻는 질문 (FAQ)

Q. aws eks update-kubeconfig를 했는데도 그대로 401이에요. A. AWS 세션 자체가 만료된 경우입니다. aws sts get-caller-identity로 자격증명이 살아 있는지 먼저 확인하고, 만료됐으면 SSO 로그인(aws sso login)이나 키 갱신 후 다시 update-kubeconfig 하세요.

Q. 프로파일·리전이 여러 개라 헷갈립니다. A. --profile과 --region을 명시하고, exec plugin args에도 동일한 값을 넣으세요. AWS_PROFILE 환경변수와 kubeconfig의 exec 설정이 다르면 엉뚱한 자격증명으로 토큰을 받아 401이 납니다.

Q. 401인데 RBAC 문제일 수도 있나요? A. 거의 아닙니다. RBAC 미부여는 인증을 통과한 뒤 발생하므로 보통 403으로 표시됩니다. 401이면 토큰·인증서·context·시계 문제일 확률이 높으니 5분 플로우의 1~4번부터 점검하세요.

확인 정보
✦ ✦ ✦
출처·검증 안내

글마다 출처와 확인 범위가 다릅니다. 아래에 확인일·확인 범위·출처가 기록된 글만 그 범위에서 확인된 것입니다. 기록이 없는 글은 적용 전 사용 중인 버전의 공식 문서로 직접 확인하고, 오류는 이메일로 알려주세요. 편집 정책 · 이메일로 제보

이 글에는 사람이 확인한 날짜·범위 기록이 아직 없습니다.

발행 · ·업데이트 ·
주제 관련 공식 문서(자동 연결 · 문장별 근거 아님)Kubernetes 공식 문서 ↗AWS 공식 문서 ↗

댓글

첫 번째 댓글을 남겨보세요.