이 글이 맞는 에러(Pod 안 워크로드 기준): open /var/run/secrets/kubernetes.io/serviceaccount/token: no such file or directory, API 응답 401 Unauthorized, the server has asked for the client to provide credentials. 403 Forbidden(User "system:serviceaccount:..." cannot ...)이면 인증은 통과한 것이니 RBAC Forbidden 진단으로 가세요.
| 원인 | 확인 명령 | 해결 |
|---|---|---|
| 토큰 자동 마운트 꺼짐(SA 또는 Pod) | kubectl -n <ns> get pod <pod> -o jsonpath='{.spec.automountServiceAccountToken}' | API를 부르는 Pod에만 automountServiceAccountToken: true |
| 앱이 시작할 때 토큰을 한 번만 읽음 | 재시작 직후엔 되다가 일정 시간 뒤 401 | 토큰 파일을 주기적으로 다시 읽기(client-go·Python 공식 클라이언트는 자동) |
| 1.24+에서 SA 토큰 Secret이 안 생김 | kubectl get secret에 토큰 Secret 없음 | kubectl create token <sa> --duration=1h |
| audience·issuer 불일치(IRSA 토큰 오용 등) | 토큰 aud 디코딩(아래 진단 명령 2) | API 호출엔 /var/run/secrets/kubernetes.io/serviceaccount/token 사용 |
403은 3편, 401·"토큰 파일 없음"은 이번 편입니다
먼저 결론부터 말하면, 401 Unauthorized와 "토큰 파일이 없다"는 RBAC 문제가 아닙니다. 이 둘은 아예 다른 층위입니다.
- 401 Unauthorized / 토큰 없음 → 인증(authentication) 실패. "너 누구야?"에 대답을 못 한 상태. RBAC RoleBinding을 아무리 고쳐도 절대 안 고쳐집니다.
- 403 Forbidden → 인가(authorization) 실패. 신원은 확인됐는데 권한이 없는 상태. 이건 K8s RBAC Forbidden 403 진단 계열의 접근이 필요합니다.
또 하나 경계를 그어둡니다. 기존에 발행한 kubectl Unauthorized(You must be logged in) 401 해결 6가지는 내 노트북의 kubeconfig 인증이 깨진 경우를 다룹니다. 이 글은 Pod 내부에서 돌아가는 워크로드가 API 서버를 호출할 때 쓰는 ServiceAccount 토큰이 주제입니다. 오퍼레이터, 사이드카, 인그레스 컨트롤러, in-cluster CI 러너처럼 컨테이너 안에서 rest.InClusterConfig()를 쓰는 코드가 대상입니다.
이 증상이 2022년 이후 급증한 배경은 명확합니다. Kubernetes 1.24에서 ServiceAccount에 대한 Secret 자동 생성이 폐지됐고, 그 이전부터 진행되던 BoundServiceAccountTokenVolume 전환으로 토큰이 만료되는 단기 자격증명으로 바뀌었기 때문입니다. 1.23 이하에서 잘 돌던 매니페스트를 1.24+ 클러스터에 그대로 올리면, 특히 secretName을 직접 참조하던 파이프라인이 조용히 깨집니다.
30초 판정표: 에러 원문 역인덱스
검색창에 친 문자열 그대로 아래 표에서 찾으세요. 각 행의 "점프" 열이 해당 처방 섹션입니다.
| 에러 원문 / 증상 | 1차 원인 갈래 | 점프 |
|---|---|---|
open /var/run/secrets/kubernetes.io/serviceaccount/token: no such file or directory | automount 비활성(SA 또는 Pod 레벨) | automount 우선순위 |
Unauthorized (본문 그대로 한 단어) | 토큰이 만료됐거나 앱이 옛 토큰을 캐싱 | 토큰 캐싱 |
the server has asked for the client to provide credentials | 토큰 자체가 요청에 안 붙음(경로 오인식·빈 파일) | automount 우선순위 |
token is expired / Token has expired | 토큰 만료(아래 표의 만료 설명 참고) + 앱의 재읽기 미구현 | 토큰 캐싱 |
serviceaccounts "xxx" not found | SA 미생성 또는 네임스페이스 불일치 | 진단 2줄 컷 |
SA를 만들었는데 kubectl get secret에 토큰 Secret이 안 보임 | 1.24+ 정책 변경(자동 생성 폐지) | 장기 토큰이 필요할 때 |
| 처방 다 했는데 여전히 401 | audience 불일치 / issuer 설정 / 노드 시계 오차 | 그래도 401일 때 |
버전별 동작 차이표와 진단 2줄 컷
이 경우 정답은 **"내 클러스터 마이너 버전부터 확인"**입니다. 같은 YAML이 버전에 따라 전혀 다르게 동작합니다.
| 버전 | 토큰 형태 | 만료 | SA Secret 자동 생성 | 갱신 주체 |
|---|---|---|---|---|
| ~1.20 | Secret 기반 레거시 JWT | 없음(무기한) | O (SA 생성 시 자동) | 없음 |
| 1.21 | projected 바운드 토큰 기본 마운트(BoundServiceAccountTokenVolume beta) | kubelet 요청 3607초, 연장 시 최대 1년(아래) | O | kubelet |
| 1.22~1.23 | 같음(GA) | 같음 | O | kubelet |
| 1.24~1.25 | projected 바운드 토큰 | 같음 | X (LegacyServiceAccountTokenNoAutoGeneration beta) — kubectl create token 사용 | kubelet |
| 1.26~1.28 | 같음 | 같음 | X (GA). 1.28부터 레거시 토큰 마지막 사용일 라벨 kubernetes.io/legacy-token-last-used GA | kubelet |
| 1.29 이상 | 같음 | 같음 | X. 자동 생성된 레거시 토큰 정리(1.29 beta, 1.30 GA) | kubelet + 정리 컨트롤러 |
기능 단계는 기능 게이트 목록 기준이고, 2026년 10월 현재 지원 중인 버전은 1.35·1.36·1.37입니다(Kubernetes Releases).
만료 시간 주의: kubelet은 기본 projected 토큰을 expirationSeconds: 3607로 요청하지만, kube-apiserver의 --service-account-extend-token-expiration(기본값 true)이 켜져 있으면 자동 주입 토큰의 만료가 최대 1년까지 늘어납니다(kube-apiserver 옵션, Managing Service Accounts). 그래서 기본 설정 클러스터에서 토큰을 디코딩하면 exp가 1시간 뒤가 아니라 훨씬 뒤로 보일 수 있습니다. 1시간 만료를 전제로 진단하지 말고 아래 명령으로 실제 exp를 확인하세요. 관리형 서비스는 이 플래그 값을 바꿔 둘 수 있으니 공급자 문서도 확인합니다.
레거시 토큰 정리 범위: 1.29부터 정리 컨트롤러는 자동 생성된 레거시 토큰 Secret(ServiceAccount의 secrets 필드가 가리키는 것)만 다룹니다. 기본 1년 동안 쓰이지 않으면 kubernetes.io/legacy-token-invalid-since 라벨로 무효 처리하고, 다시 1년이 지나면 삭제합니다(Managing Service Accounts). 사람이 직접 만든 kubernetes.io/service-account-token Secret은 정리 대상이 아니지만 만료도 없으므로, 그런 토큰에 기대는 파이프라인은 유출 시 피해가 큽니다.
진단 명령 3종 (복붙용)
1) SA 레벨 automount 설정 확인
kubectl -n <ns> get sa <sa-name> -o jsonpath='{.metadata.name}{" automount="}{.automountServiceAccountToken}{"\n"}'예상 정상 결과: my-sa automount= (비어 있으면 기본값 true라 마운트됨).
automount=false가 찍히면 → automount 갈래로 이동.
2) Pod 안에 토큰 파일이 실제로 있는지 + 만료 시각 디코딩
kubectl -n <ns> exec <pod> -- ls -l /var/run/secrets/kubernetes.io/serviceaccount/
kubectl -n <ns> exec <pod> -- cat /var/run/secrets/kubernetes.io/serviceaccount/token \
| cut -d. -f2 | tr '_-' '/+' \
| awk '{n=length($0)%4; if(n) $0=$0 substr("==",1,4-n); print}' \
| base64 -d | jq '.exp, .iat, .aud, .sub'예상 정상 결과: ca.crt, namespace, token 3개 파일이 보이고, JSON에 exp(만료 epoch), aud(대상 audience. 클러스터의 --api-audiences, 미지정 시 issuer 값이며 kubeadm 기본값은 https://kubernetes.default.svc.cluster.local, kubeadm 소스), sub(system:serviceaccount:<ns>:<sa>)가 출력됩니다.
분기:
No such file or directory→ automount 비활성. (a) 섹션.- 파일의
exp는 미래인데 앱은 401 → 앱이 갱신 전 토큰을 메모리에 들고 있을 가능성. (c) 섹션. - 파일 자체의
exp가 이미 과거 → kubelet이 토큰을 교체하지 못한 상태. 해당 노드의 kubelet 로그와 노드 시계를 확인합니다. aud가sts.amazonaws.com같은 외부 값만 있음 → API 서버용 audience가 아님. 실패 분기 섹션.base64: invalid input이나 jq 파싱 오류 → 토큰 파일이 비었거나 JWT가 아님. JWT 본문은 패딩 없는 base64url이라base64 -d에 그대로 넣으면 정상 토큰도 실패하므로, 위처럼tr과 패딩 보정을 거칩니다.- 이미지에
cat이 없으면(distroless)kubectl debug로 임시 컨테이너를 붙이거나kubectl create token으로 발급 자체를 먼저 확인합니다.
3) 토큰 발급 자체가 되는지 검증
kubectl -n <ns> create token <sa-name> --duration=30m정상이면 eyJ...로 시작하는 JWT가 출력됩니다. 여기서 serviceaccounts "xxx" not found가 나면 SA 자체가 없거나 네임스페이스를 잘못 본 것이고, 이건 RBAC이 아니라 오브젝트 부재 문제입니다.
원인별 처방
(a) automount 우선순위: Pod가 SA를 이깁니다
이 경우 정답은 **"Pod spec의 설정이 ServiceAccount 설정을 덮어쓴다"**를 기억하는 것입니다. SA에서 켜 뒀어도 Pod에서 껐으면 안 붙습니다.
SA automountServiceAccountToken | Pod spec automountServiceAccountToken | 결과 |
|---|---|---|
| 미지정(기본 true) | 미지정 | 마운트됨 ✅ |
false | 미지정 | 마운트 안 됨 ❌ |
false | true | 마운트됨 ✅ (Pod가 우선) |
미지정 / true | false | 마운트 안 됨 ❌ (Pod가 우선) |
두 값을 한 번에 보는 명령:
kubectl -n <ns> get pod <pod> -o jsonpath='{.spec.serviceAccountName}{" podAutomount="}{.spec.automountServiceAccountToken}{"\n"}'흔한 원인은 보안 하드닝(Kyverno/OPA 정책 등)으로 default SA의 automount를 일괄로 끈 경우입니다. Pod Security Standards(restricted 포함)는 이 필드를 검사하지 않으므로, PSS만 켰다고 토큰이 사라지지는 않습니다. 정책은 유지하되, API를 호출해야 하는 워크로드만 Pod 레벨에서 예외 처리하는 방식이 안전합니다.
spec:
serviceAccountName: my-operator-sa
automountServiceAccountToken: true # 정책으로 SA가 false여도 이 Pod만 예외(b) projected volume로 만료·audience 직접 제어
이 경우 정답은 **"automount에 맡기지 말고 projected volume을 명시"**입니다. 만료 시간과 audience를 코드가 기대하는 값으로 고정할 수 있습니다.
apiVersion: v1
kind: Pod
metadata:
name: api-caller
spec:
serviceAccountName: my-operator-sa
automountServiceAccountToken: false # 기본 마운트는 끄고
containers:
- name: app
image: my/app:1.0
volumeMounts:
- name: sa-token
mountPath: /var/run/secrets/tokens
readOnly: true
volumes:
- name: sa-token
projected:
sources:
- serviceAccountToken:
path: token
expirationSeconds: 3600 # 최소 600, API 서버 --service-account-max-token-expiration으로 상한이 걸릴 수 있음
# audience 생략 → API 서버 기본 audience(API 호출용). 다른 수신자용 토큰일 때만 지정
- configMap:
name: kube-root-ca.crt # 기본 마운트를 껐으므로 CA도 직접 넣음
items:
- key: ca.crt
path: ca.crtaudience를 생략하면 API 서버 식별자가 기본값이 됩니다(Projected Volumes). API 서버의 --api-audiences에 없는 값을 넣으면 그 토큰은 API 호출에서 401로 거부됩니다. 또 rest.InClusterConfig()는 /var/run/secrets/kubernetes.io/serviceaccount/의 token·ca.crt만 읽으므로(client-go 소스), 위처럼 경로를 바꾸면 앱에서 토큰·CA 경로를 직접 지정해야 합니다. 기본 클라이언트를 그대로 쓰려면 mountPath를 /var/run/secrets/kubernetes.io/serviceaccount로 두세요.
반대로 audience를 지정한 토큰은 그 대상에만 유효합니다. EKS IRSA나 GKE Workload Identity가 바로 이 메커니즘을 씁니다 — 클라우드 STS용 audience 토큰을 별도 경로에 주입하죠. 그래서 IRSA용 토큰 경로를 API 호출에 재사용하면 401이 납니다. 두 토큰은 목적이 다릅니다.
(c) 앱이 토큰을 한 번만 읽고 캐싱하는 함정
이 경우 정답은 **"파일을 주기적으로 다시 읽어라"**입니다. kubelet은 토큰 파일을 만료 전에 갱신해 주지만, 애플리케이션이 프로세스 시작 시 한 번 읽고 메모리에 들고 있으면 갱신본을 영원히 못 봅니다. 결과는 토큰이 실제로 만료되는 시점(직접 지정한 expirationSeconds, 자동 주입 토큰은 연장 설정에 따라 최대 1년)에 Unauthorized 또는 token is expired. kubelet은 토큰이 TTL의 80%를 넘었거나 24시간이 지나면 교체하고, 다시 읽는 것은 애플리케이션 책임입니다(Configure Service Accounts).
- client-go:
rest.InClusterConfig()는BearerTokenFile을 설정하고, 클라이언트가 이 파일을 1분 주기로 다시 읽습니다(client-go 소스). 이 경우 보통 문제가 없습니다. - 직접
os.ReadFile로 읽어 헤더에 붙이는 코드 / curl 스크립트 / 자체 HTTP 클라이언트: 갱신을 못 봅니다. 여기가 대부분의 사고 지점입니다.
Go에서 매 요청마다 다시 읽는 최소 패턴:
const tokenPath = "/var/run/secrets/kubernetes.io/serviceaccount/token"
type reloadingTransport struct{ base http.RoundTripper }
func (t *reloadingTransport) RoundTrip(req *http.Request) (*http.Response, error) {
b, err := os.ReadFile(tokenPath) // 매 요청 재읽기 (tmpfs라 비용 낮음)
if err != nil {
return nil, fmt.Errorf("SA 토큰 읽기 실패: %w", err)
}
r := req.Clone(req.Context())
r.Header.Set("Authorization", "Bearer "+strings.TrimSpace(string(b)))
return t.base.RoundTrip(r)
}Bash/사이드카에서 호출한다면 변수에 담아두지 말고 매번 $(cat ...)로 읽는 것만으로 해결됩니다.
curl -sS --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \
-H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \
https://kubernetes.default.svc/api/v1/namespaces/default/pods파이썬 공식 kubernetes 클라이언트의 config.load_incluster_config()는 기본값 try_refresh_token=True로 토큰 파일을 1분마다 다시 읽습니다(소스). 다만 토큰 문자열을 직접 꺼내 다른 HTTP 클라이언트 헤더에 넣는 코드는 위 Go 예시처럼 매번 다시 읽어야 합니다.
(d) CI·외부 시스템용 장기 토큰이 필요할 때
이 경우 정답은 **"수동 Secret 대신 kubectl create token 주기 갱신"**입니다.
# CI 파이프라인 스텝마다 짧게 발급 (권장)
TOKEN=$(kubectl -n ci create token ci-runner-sa --duration=1h)| 방식 | 만료 | 유출 시 회수 | 감사 추적 | 권장 |
|---|---|---|---|---|
kubectl create token --duration | 지정한 짧은 기간 | 만료로 자연 소멸 | 발급 이벤트 남음 | ✅ |
수동 kubernetes.io/service-account-token Secret | 사실상 무기한 | Secret 삭제로 즉시 회수 | 사용 추적 어려움 | ⚠️ 최후 수단 |
| 클라우드 워크로드 아이덴티티(IRSA/Pod Identity/GKE WI) | 단기 자동 갱신 | IAM 정책으로 통제 | 클라우드 감사로그 | ✅ (클라우드 한정) |
--duration은 API 서버의 --service-account-max-token-expiration 설정에 의해 상한이 걸릴 수 있습니다. 요청한 값보다 짧게 발급될 수 있으니 발급 후 exp를 디코딩해 실제 값을 확인하세요.
수동 Secret이 정말 불가피하다면(예: 토큰 갱신을 지원하지 않는 레거시 외부 시스템) 최소 권한 전용 SA를 별도로 만들고, 만료가 없다는 점을 리스크 등록부에 명시하고, 정기 로테이션 일정을 잡아두는 것이 최소한의 방어선입니다.
보안 관점: 끄기, 회수, 추적
끄기. default SA의 automount를 끄는 것은 좋은 기본값입니다. API를 호출하지 않는 대다수 워크로드에 자격증명을 뿌리지 않게 되니까요.
kubectl -n <ns> patch serviceaccount default -p '{"automountServiceAccountToken": false}'파급 효과: 이 네임스페이스에서 default SA를 쓰면서 API를 호출하던 워크로드가 즉시 깨집니다. 적용 전에 해당 네임스페이스의 Pod들이 어떤 SA를 쓰는지 훑어보세요.
kubectl -n <ns> get pods -o custom-columns='POD:.metadata.name,SA:.spec.serviceAccountName'회수. 여기가 중요합니다 — 바운드 토큰은 개별 무효화가 안 됩니다.
| 토큰 유형 | 유출 시 회수 방법 |
|---|---|
| projected 바운드 토큰 | 토큰별 취소 API는 없음. 토큰이 묶인 Pod를 삭제하면 그 토큰은 무효가 됩니다. SA 삭제·재생성은 그 SA의 모든 토큰을 무효화하며, 이 SA를 쓰는 Pod 전부 재시작이 필요합니다. 만료를 기다리는 방법은 위 연장 설정 때문에 최대 1년일 수 있습니다 |
| 레거시 Secret 토큰 | 해당 Secret 삭제 → 즉시 무효 |
| 노드에 바인딩된 토큰 | 해당 Pod/노드 삭제 시 자동 무효화(바인딩 대상 소멸) |
바운드 토큰은 .spec.boundObjectRef로 Pod에 묶이기 때문에, Pod가 사라지면 토큰도 유효성을 잃습니다. 사고 대응 시 "Pod 삭제"가 곧 부분적 회수 조치가 되는 셈입니다.
추적. 감사로그(audit log)에서 특정 SA의 사용 이력을 뽑는 쿼리 패턴:
# 감사로그 JSON 라인에서 특정 SA의 호출만 추출
jq -c 'select(.user.username == "system:serviceaccount:prod:my-operator-sa")
| {ts: .requestReceivedTimestamp, verb, uri: .requestURI, ip: .sourceIPs[0], code: .responseStatus.code}' \
audit.log | head -50responseStatus.code가 401이면 인증 실패, 403이면 인가 실패 — 로그 한 줄에서 이번 글의 주제인지 3편의 주제인지 바로 갈립니다. 예상치 못한 sourceIPs가 보이면 토큰 유출을 의심할 근거가 됩니다.
그래도 401일 때: 실패 분기 체크리스트
위 처방을 다 했는데도 401이면 순서대로 확인하세요.
- audience 불일치. 토큰의
aud가 API 서버가 허용하는 값인지 확인합니다.kubectl create token <sa> | cut -d. -f2 | tr '_-' '/+' | awk '{n=length($0)%4; if(n) $0=$0 substr("==",1,4-n); print}' | base64 -d | jq .aud로 기본 audience를 확인하고, Pod의 토큰과 비교하세요. IRSA/Workload Identity를 쓰는 클러스터에서 클라우드용 토큰을 API 호출에 잘못 쓰는 사례가 흔합니다. - API 서버 설정.
--service-account-issuer,--api-audiences,--service-account-key-file값이 발급/검증 양쪽에서 일관적인지 봅니다. 관리형 클러스터(EKS/GKE/AKS)는 직접 수정 불가이므로, 이 단계에서 이상하면 클라우드 공식 문서 확인이 필요합니다. - 노드 시계 오차.
iat/nbf가 미래로 잡히면 API 서버가 거부합니다.kubectl exec <pod> -- date -u와 컨트롤 플레인 시각을 비교하고, 노드의 NTP(chronyd/systemd-timesyncd) 동기화 상태를 확인하세요. 수 분 단위 오차만으로도 재현됩니다. - 인증 웹훅/프록시. 사내 인증 프록시나 서비스 메시가
Authorization헤더를 덮어쓰거나 제거하는지 확인합니다. mTLS 사이드카가 헤더를 재작성하는 구성에서 종종 발생합니다. - 토큰 파일 개행/공백. 셸로 조립한 헤더에서 개행이 섞이면 헤더가 깨집니다.
tr -d '\n'또는TrimSpace를 반드시 넣으세요.
재발 방지
- 배포 템플릿에
automountServiceAccountToken을 명시적으로 적어 기본값 변화에 흔들리지 않게 합니다. - API를 호출하는 앱은 "토큰 재읽기" 여부를 코드리뷰 체크리스트에 넣습니다.
- 스테이징에서
expirationSeconds: 600같은 짧은 만료로 돌려 만료 처리 버그를 조기에 노출시킵니다. - 클러스터 업그레이드 전, 수동 SA 토큰 Secret과
secretName참조를 전수 조사합니다.
kubectl get secrets -A --field-selector type=kubernetes.io/service-account-token여기에 결과가 나온다면 1.24+ 환경에서 레거시 방식에 의존 중이라는 뜻입니다. 마이그레이션 대상 목록으로 삼으세요.
자주 묻는 질문 (FAQ)
Q1. 1.24로 올렸더니 SA를 만들어도 Secret이 안 생깁니다. 버그인가요?
버그가 아니라 의도된 변경입니다. 1.24부터 ServiceAccount 생성 시 토큰 Secret을 자동 생성하지 않습니다. 토큰이 필요하면 kubectl create token <sa>로 단기 토큰을 발급하거나, Pod에서는 projected volume(기본 automount)을 사용하세요.
Q2. 401과 403 중 어느 쪽인지 로그만 보고 구분하는 방법은?
HTTP 상태 코드로 갈립니다. 401은 "누군지 모르겠다"(토큰 없음·만료·서명 검증 실패), 403은 "누군지는 알겠는데 권한이 없다"입니다. 403 메시지에는 보통 User "system:serviceaccount:ns:sa" cannot list resource ...처럼 신원이 찍혀 있습니다. 신원이 찍혔으면 인증은 성공한 것이므로 RBAC을 보면 됩니다.
Q3. 토큰이 주기적으로 바뀌는데 그때마다 앱을 재시작해야 하나요? 아닙니다. kubelet이 만료 전에 토큰 파일을 갱신합니다. 앱이 파일을 다시 읽기만 하면 됩니다. 재시작이 필요한 상황이라면 그건 캐싱 버그이므로, 위의 재읽기 패턴을 적용하는 것이 정답입니다.
Q4. expirationSeconds를 아주 길게(예: 1년) 설정할 수 있나요?
요청은 할 수 있지만 API 서버 정책 상한에 의해 잘릴 수 있고, 보안상 권장되지 않습니다. 단기 자격증명이 제로트러스트 모델의 기본 전제이기 때문입니다. 장기 자격증명이 정말 필요한 외부 연동이라면 토큰 대신 클라우드 워크로드 아이덴티티나 주기적 재발급 파이프라인을 쓰는 편이 낫습니다.
Q5. 토큰이 유출됐습니다. 즉시 무효화할 방법이 있나요? 바운드 토큰은 개별 취소 API가 없습니다. 현실적인 선택지는 (1) 해당 SA를 삭제 후 재생성해 기존 토큰 전부를 무효화하고 관련 Pod를 재시작하거나, (2) 토큰이 Pod에 바인딩돼 있다면 그 Pod를 삭제하거나, (3) 만료를 기다리는 것입니다(자동 주입 토큰은 연장 설정 때문에 최대 1년일 수 있습니다). 레거시 Secret 토큰이라면 Secret을 지우면 즉시 회수됩니다. 병행해서 감사로그로 유출 기간 동안의 호출 이력을 반드시 확인하세요.
Q6. default SA의 automount를 끄면 어떤 게 깨지나요?
그 네임스페이스에서 default SA를 쓰면서 API 서버를 호출하던 모든 Pod가 토큰 파일을 잃습니다. 대표적으로 일부 모니터링 에이전트, 서비스 디스커버리를 하는 앱, 자체 리더 선출 로직을 가진 앱이 영향을 받습니다. 적용 전에 네임스페이스의 Pod-SA 매핑을 조회하고, 필요한 Pod에는 Pod 레벨 automountServiceAccountToken: true로 예외를 주세요.
Q7. EKS에서 IRSA를 쓰는데 API 서버 호출이 401입니다.
IRSA가 주입하는 토큰(AWS_WEB_IDENTITY_TOKEN_FILE)은 audience가 sts.amazonaws.com으로, AWS STS 전용입니다. Kubernetes API 호출에는 /var/run/secrets/kubernetes.io/serviceaccount/token을 써야 합니다. 두 경로를 혼동하지 않았는지 먼저 확인하세요.
다음 5편에서는 네트워크 레벨 차단 — NetworkPolicy와 mTLS 실패 진단을 다룹니다. 인증도 인가도 통과했는데 연결 자체가 막히는 경우, connection refused와 i/o timeout을 어떻게 갈라내고 정책 규칙을 역추적할지 같은 방식의 판정표로 정리하겠습니다.
글마다 출처와 확인 범위가 다릅니다. 아래에 확인일·확인 범위·출처가 기록된 글만 그 범위에서 확인된 것입니다. 기록이 없는 글은 적용 전 사용 중인 버전의 공식 문서로 직접 확인하고, 오류는 이메일로 알려주세요. 편집 정책 · 이메일로 제보
이 글에는 사람이 확인한 날짜·범위 기록이 아직 없습니다.
댓글
첫 번째 댓글을 남겨보세요.