쿠버네티스를 사용하면서 가장 중요하지만 잘 모르는 부분이 config 내용이다. 이 내용에 대해서 알아보자.
kubeconfig
쿠버네티스를 설치하면 다음과 같은 파일이 설치된다.
|
1 |
sudo ls -lh /etc/kubernetes/admin.conf |
이 파일은 이제 쿠버네티스에 설정을 담은 파일이다. 이 파일에는 쿠버네티스를 사용하기 위한 kube-apiserver 접속 주소와 인증 정보를 가지고 있다.
이 파일만 있으면 어떤 계정에서도 접속하는데 사용할 수 있다.
일반 계정에서 kubectl 사용하기
kubectl 명령어는 이 파일을 참조 하는데, 일반계정에서 사용하기 위해서는 다음과 같이 해주면 된다.
|
1 2 3 4 5 6 7 8 |
# 1. 일반 계정 홈 디렉토리에 .kube 폴더 생성 mkdir -p $HOME/.kube # 2. root 계정의 config 파일을 일반 계정으로 복사 sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config # 3. 복사한 파일의 소유권을 일반 계정으로 변경 sudo chown $(id -u):$(id -g) $HOME/.kube/config |
로그인 시에 자동으로 적용하기 위해서 .bashrc 파일에 다음과 같이 추가해준다.
|
1 2 3 |
# 사용하는 쉘 확인 후 profile에 추가 (Bash 기준) echo "export KUBECONFIG=\$HOME/.kube/config" >> ~/.bashrc source ~/.bashrc |
쿠버네티스 정보 확인
쿠버네티스 정보를 확인하는 방법이라고 함은 설정 정보를 확인하는 것과 같다.
|
1 2 3 4 5 6 7 8 9 10 11 |
# nodes 정보 확인 $ kubectl get ndoes NAME STATUS ROLES AGE VERSION k8s-master Ready control-plane 16d v1.36.3 k8s-worker Ready <none> 16d v1.36.3 # 클러스터 정보 $ kubectl cluster-info Kubernetes control plane is running at https://192.168.96.190:6443 CoreDNS is running at https://192.168.96.190:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'. |
위 정보는 아주 간단한 내용을 담고 있는데, 노드(Node) 는 두개의 노드로 구성되며, 하나는 Control-plane 이고 하는 worker 노드다. 컨트롤 플레인의 주소는 https://192.168.96.120:6443 인데, 이것이 api-server 주소다.
보다 자세한 정보는 다음과 같이 확인이 가능하다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# 현재 설정 정보 확인 하기 $ kubectl config view apiVersion: v1 clusters: - cluster: certificate-authority-data: DATA+OMITTED server: https://192.168.96.190:6443 name: kubernetes contexts: - context: cluster: kubernetes user: kubernetes-admin name: kubernetes-admin@kubernetes current-context: kubernetes-admin@kubernetes kind: Config users: - name: kubernetes-admin user: client-certificate-data: DATA+OMITTED client-key-data: DATA+OMITTED # 등록된 콘텍스트 목록 보기 $ kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE * kubernetes-admin@kubernetes kubernetes kubernetes-admin |
출력되는 설정 정보는 $HOME/.kube/config 파일이 내용을 보여주고 있다. 이 파일의 주요한 내용은 Clusters, Users, Contexts 세가지 섹션으로 구성된다.
Clusters (어디로 갈 것인가?)
- 접속할 쿠버네티스 클러스터 API 서버의 IP 주소 및 도메인(URL) 정보입니다.
- 보안 통신을 위한 CA 인증서 데이터(
certificate-authority-data)가 포함됩니다. - name 은 클러스터 이름 입니다.
certificate-authority-data 는 브라우저에 Root CA 인증서와 같은 기능을 한다. 서버에 접속을 하는데, 공개키가 내장되어 있는 Root CA 인증서다. 브라우저는 자체적으로 전세계 Root CA 인증서를 내장하고 있지만 kubectl 는 명령어로 인증을 받아야 해서 인자로 Root CA 인증서를 가지고 있어야 한다.
이것은 base64 로 인코딩이 된 것이라서 다음과 같이 확인을 할 수 있다.
|
1 2 3 |
$ kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' # 파일로 저장 kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 --decode > k8s-ca.crt |
파일 내용을 확인해보면 흥미로운 점을 확인할 수 있다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
$ openssl x509 -in k8s-ca.crt -noout -text Certificate: Data: Version: 3 (0x2) Serial Number: 7618924527804391204 (0x69bbdb7dc24a9f24) Signature Algorithm: sha256WithRSAEncryption Issuer: CN=kubernetes Validity Not Before: Jul 29 14:08:15 2026 GMT Not After : Jul 26 14:13:15 2036 GMT Subject: CN=kubernetes Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:d4:40:87:f1:4a:88:36:55:9f:da:44:17:ed:3d: a6:43:87:4a:61:fd:22:c9:c9:c6:bf:37:a4:d9:2a: 96:d3:35:72:56:f3:ce:f3:02:be:ea:55:a7:5b:e7: 7c:f5:84:a6:9c:02:9b:cb:92:ff:b1:68:02:a9:a5: 9b:ea:37:e8:f5:cf:55:6a:0e:de:8a:50:44:41:5a: 57:8f:ee:44:7f:2f:f5:c2:62:93:25:bc:7e:09:63: 37:e7:4d:cc:9d:f6:51:bf:0f:0d:7c:6e:15:ab:bf: ea:54:fc:b8:80:e2:6b:63:a3:4f:dc:12:42:e4:59: e7:2f:c7:da:0b:39:18:20:6a:76:b5:b1:b9:dd:cb: 04:44:eb:73:f0:f9:ca:4f:68:18:49:57:85:85:dc: 96:52:77:ff:c7:7f:3c:94:1d:19:8d:50:b1:f0:2f: 7b:ad:c0:cf:a1:b8:ae:fb:8a:90:28:b3:85:4c:6c: 55:d6:ee:26:10:5d:84:de:b4:6f:ff:9f:97:9b:99: af:99:08:27:fb:68:a8:67:98:53:ef:59:27:d3:71: 76:06:88:a9:66:9c:1f:02:4a:15:17:00:06:e7:66: f9:c5:27:8c:81:4e:91:ec:5b:65:5e:4d:4a:2f:02: ba:da:30:96:58:03:96:ee:f1:2f:10:6d:ad:50:44: d6:85 Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Encipherment, Certificate Sign X509v3 Basic Constraints: critical CA:TRUE X509v3 Subject Key Identifier: 69:C0:4F:A0:5E:6E:AC:8E:E6:10:C2:7C:C0:CB:8C:94:33:59:4E:49 X509v3 Subject Alternative Name: DNS:kubernetes Signature Algorithm: sha256WithRSAEncryption Signature Value: 66:22:de:7a:ac:00:8b:e5:13:92:a7:c9:ed:ef:54:5d:3a:1d: 5a:dc:bc:c5:cb:01:cd:7d:c2:58:13:40:2f:a7:b2:4d:41:24: 4f:c3:22:d7:1c:57:59:a9:c1:13:9c:87:f9:1c:d3:99:15:14: 93:c4:6d:41:d5:64:b4:3d:1a:04:2b:83:bf:43:02:85:12:9f: b1:ac:2e:a2:67:37:6c:45:61:01:85:a1:d4:52:4c:9f:47:2c: 7e:6a:bc:d9:92:c0:c7:a8:75:1e:65:ba:52:e9:08:9c:41:9d: 81:bb:9d:bc:ee:cc:c0:0c:c7:42:36:15:97:cd:c7:f3:5f:59: c0:4a:4b:fe:d4:04:6d:c7:4a:2a:17:ec:b4:c8:d8:a1:4b:08: fc:cf:09:12:40:e2:c3:bb:c0:8b:6e:05:59:d4:5b:57:12:56: 74:40:1a:e4:4b:6e:65:07:d4:c1:c6:72:bd:9b:d8:8d:3c:2b: 0d:fa:05:71:8a:66:79:42:1c:34:d4:85:20:fa:03:75:9a:11: d7:aa:d9:93:c6:8a:a2:4c:c0:76:14:05:d5:9b:27:07:73:4b: 79:23:bb:12:fa:0e:5c:0c:0e:c2:40:34:aa:01:21:77:f2:1c: 2f:b0:54:09:05:d5:f9:d9:a2:e1:59:dd:c5:56:66:a2:4c:90: d0:18:d6:37 |
CN(Common Name) 이 kubernetes 이다. Issuer(발급자) 와 Subject(소유자) 가 모두 CN=kubernetes 로 일치한다. 이는 다음과 같은 의미다.
- 이는 이 인증서가 다른 상위 기관(예: DigiCert 등)에서 받아온 것이 아니라, “내가 내 신원을 보증한다”라고 선언하는 Self-Signed Certificate(자체 서명 인증서, 즉 Root CA 인증서)라는 것을 명확하게 증명합니다.
- 이 클러스터 시스템 안에서 모든 인증서 체인의 최상위 뿌리가 되는 이름이 바로
kubernetes로 정의된 것입니다.
SAN 의 DNS 가 kubernetes 인 것도 흥미롭다. 이것은 쿠버네티스 내부 시스템(특히 클러스터 내부 DNS) 과 마스터 노드가 통신할 때 사용하는 아주 특수한 ‘내부용 도메인 이름’ 이다. 다음과 같은 의미가 있다.
- 쿠버네티스 내부 통신용: 쿠버네티스 클러스터 내부의 파드(Pod)들이나 내부 컴포넌트들은 API 서버를 찾아갈 때
https://kubernetes또는https://cluster.local이라는 주소를 사용합니다. - 인증 실패 방지: 만약 파드가 내부에서
https://kubernetes로 API 서버에 접속했는데, API 서버가 보여준 인증서에 이 이름(kubernetes)이 등록되어 있지 않다면 “주소가 일치하지 않는다”며 보안 에러가 납니다. 이를 방지하기 위해 SAN(Subject Alternative Name)에DNS:kubernetes를 명시해 둔 것입니다.
실제로 클러스터를 처음 구성하면 내부 default 네임스페이스에 kubernetes라는 이름의 서비스(Service)가 자동으로 생성되며, 이것이 API 서버의 IP로 연결해 주는 이정표 역할을 한다. 실제로 default 네임스페이스에 service 를 보면 다음과 같이 되어 있다.
|
1 2 3 4 |
$ kubectl get service -A NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 16d kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 16d |
그렇다면 Pod -> Control Plane 과 통신할때에 https://kubernetes 로 호출해서 통신을 한다는 것인데, 그러면 Pod 도 RootCA 인증서를 가지고 있어야 한다. 그 Root CA 인증서는 kube config 에 있는 위 파일 내용이다. Pod 는 자동으로 이 인증서를 받는 것인가? 아니다.
쿠버네티스가 파드(Pod)를 생성할 때, 마스터 노드가 가지고 있는 Root CA 인증서를 파드 내부의 특정 경로에 자동으로 넣어준다(주입해 준다). 파드가 직접 어딘가에서 다운로드해 오는 것이 아니라, 쿠버네티스가 파드를 만들면서 미리 가방에 넣어 배송해 주는 방식이다. 다음과 같은 과정으로 이루어진다.
- 비밀의 열쇠: Service Account (서비스 어카운트)
쿠버네티스에서 실행되는 모든 파드는 기본적으로 ServiceAccount(서비스 계정)라는 신분증을 하나씩 할당받는다. 우리가 파드를 만들 때 특별히 지정하지 않으면, 자동으로 default라는 이름의 서비스 계정이 부여된다.
쿠버네티스는 파드를 띄울 때 이 서비스 계정과 연결된 인증 정보들을 파드 내부의 파일 시스템에 볼륨 마운트(Volume Mount) 형식으로 밀어 넣는다.
- 파드 내부의 어느 경로에 들어 가나?
파드 내부에 들어가 보면 아래의 고정된 경로에 인증서와 토큰이 항상 준비되어 있다:
경로: /var/run/secrets/kubernetes.io/serviceaccount/
이 디렉토리를 열어보면 정확히 3개의 파일이 들어있습니다:
1. ca.crt: 바로 이것이 우리가 앞서 보았던 그 Root CA 인증서!
2. token: 파드가 API 서버에 로그인할 때 쓸 일회용 암호문(JWT 토큰).3.namespace: 이 파드가 속한 네임스페이스 이름이 적힌 텍스트.
- 실제 통신이 일어나는 전체 시나리오
파드 안에서 돌아가는 애플리케이션(예: 쿠버네티스 오픈소스 도구, 컨테이너 내부 스크립트 등)이 API 서버에 요청을 보낼 때의 과정이다.
1. 탐색: 애플리케이션이 https://kubernetes 주소로 요청을 보냄
2. 비교: API 서버가 자신의 신분증을 보여주면, 애플리케이션은 자동으로 파드 내부의 /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 파일을 읽어와 서버의 신원을 검증합니다. (Root CA 인증서 획득 성공!)
3. 인증: 서버 검증이 끝나면, 파드는 같은 경로에 있는 token 파일을 꺼내 API 서버에게 던지며 “나 default 권한 가진 파드인데, 정보 좀 줘!” 하고 자신을 증명함.
토큰은 https 를 통해서 다음과 같이 자신의 신원을 증명하는데 쓰인다. 이것은 JWT 방식을 이용하는데, 이 JWT 는 비밀키로 암호화를 하게 된다. 이때 쓰이는 비밀키, 공개키가 있어야 하는데, 다음과 같은 디렉토리에 두개의 파일을 사용하게 된다.
|
1 2 3 |
ls -lh /etc/kubernetes/pki/sa.* -rw------- 1 root root 1.7K Jul 29 14:14 /etc/kubernetes/pki/sa.key -rw------- 1 root root 451 Jul 29 14:14 /etc/kubernetes/pki/sa.pub |
즉 , JWT 토큰의 암복화는 쿠버네티스의 Service Account 의 비밀키, 공개키를 가지고 하게 되는데, 그 과정은 다음과 같다.
1. 토큰을 만들 때 (발급 과정)
쿠버네티스 마스터 노드(정확히는 kube-controller-manager)가 새로운 서비스 어카운트용 토큰을 구워낼 때, 쿠버네티스 서비스 어카운트 전용 비밀키(sa.key)를 사용해 토큰에 디지털 도장(서명)을 찍는다.
- 비밀키의 역할: “이 토큰은 정식 쿠버네티스 마스터가 발행한 진짜 토큰이다”라는 것을 증명하는 마스터 도장.
- 만약 이 비밀키가 없다면, 해커가 토큰을 마음대로 위조해서 “나 관리자 토큰인데?” 하고 클러스터를 해킹할 수 있기 때문에 반드시 이 키로 암호화 서명을 해야 한다.
2. 토큰을 쓸 때 (검증 과정)
파드가 이 토큰을 들고 API 서버(kube-apiserver)로 가서 “정보 좀 주세요”라고 요청하면, API 서버는 서비스 어카운트 공개키(sa.pub)를 꺼내 토큰의 도장을 확인한다.
- 공개키의 역할: 마스터가 찍은 도장이 진짜인지 가짜인지 검사하는 돋보기 역할을 한다.
- 도장이 진짜로 확인되면, API 서버는 비로소 파드의 신원을 믿고 요청을 승인한다.
이제 어떻게 동작하는지를 전체적으로 알게 되었다. 지금까지 논의는 파드 -> 컨트롤 플레인에 어떻게 데이터 통신을 하는지에 대한 것이다.
- https://kubernetes 로 연결 이때 Root CA 를 이용해 접속을 요청.
- 토큰을 이용해서 자격을 증명한다. 이는 http 헤더에 Authorization: Bearer eyJhbGci0i…. 형식으로 보내게 되는데, 이 토콘은 서비스 어카운트 비밀키로 암호화 된것이며 서버에서는 서비스 어카운트 공개키로 해독을 해서 판독한다.
JWT 안에는 다음과 같은 내용들이 들어 있다.
|
1 2 3 4 5 6 7 8 |
{ "iss": "kubernetes/serviceaccount", "kubernetes.io/serviceaccount/namespace": "default", "kubernetes.io/serviceaccount/secret.name": "default-token-xxxx", "kubernetes.io/serviceaccount/service-account.name": "default", "kubernetes.io/serviceaccount/pod.name": "my-nginx-pod", "sub": "system:serviceaccount:default:default" } |
Users (누가 갈 것인가?)
- 클러스터에 인증(Authentication)할 사용자 정보와 자격 증명입니다.
- 클라이언트 인증서 키 데이터, 토큰(Token), 또는 ID/비밀번호 등이 들어있습니다.
- name 은 user 이름이다.
이 내용은 관리자가 박에서 PC 를 켜고 kubectl 명령어를 칠때 토큰 외에 또 하나의 강력한 인증수단 ‘클라이언트 인증서’를 사용한다.
name: kubernetes-admin 이라고 되어 있는데, 이것이 일종의 kubernetes 내에 계정이라고 보면된다. 그런데, 우리가 알고 있는 계정이라고 하면 계정을 가지고 있는 데이터베이스가 따로 있지만 쿠버네티스에서는 그러한 사용자를 관리하는 데이터베이스가 따로 없고 클라이언트 인증서에 사용자 계정 정보를 담게 된다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
$ kubectl config view --raw -o jsonpath='{.users[0].user.client-certificate-data}' | base64 --decode > kubernetes-admin.crt $ openssl x509 -in kubernetes-admin.crt -noout -text Certificate: Data: Version: 3 (0x2) Serial Number: 5080176178023095253 (0x468069516777dbd5) Signature Algorithm: sha256WithRSAEncryption Issuer: CN=kubernetes Validity Not Before: Jul 29 14:08:15 2026 GMT Not After : Jul 29 14:13:15 2027 GMT Subject: O=kubeadm:cluster-admins, CN=kubernetes-admin Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:b3:a7:c5:0d:42:0f:a9:56:9d:c5:e2:08:ac:59: db:d7:08:e6:92:0d:c2:b7:d3:f7:14:5f:91:f9:7f: 41:ff:b4:ce:86:74:26:fa:b7:1c:61:84:2a:87:93: 8e:39:97:e4:66:c0:8d:60:42:05:3a:d2:11:b6:b8: 5a:7a:47:01:29:fd:b3:89:19:45:24:8e:6e:dc:b5: 79:41:90:35:de:3b:a7:a4:d6:57:ff:64:9e:cc:4e: cf:dd:f3:74:28:06:b1:09:57:18:59:81:2c:f5:81: e2:b3:c9:89:ec:88:b4:66:9f:ae:0b:07:01:8a:97: e7:22:08:04:46:5f:3d:11:53:dc:2c:01:7c:3e:ce: 66:55:17:d1:19:42:2c:45:44:15:12:07:87:ce:4d: 54:01:23:7d:b3:e3:29:9d:e9:ab:af:ce:9f:68:ca: cd:17:0d:ff:c3:88:af:f3:c7:a8:b9:2d:21:db:94: 9d:ef:a1:5c:a6:cc:06:00:27:39:92:26:19:6c:5d: b2:92:62:1b:c2:f0:c0:92:67:83:8c:11:8b:43:be: d3:5b:69:73:da:72:41:2b:6e:bd:1a:fa:43:d2:89: 75:6d:e3:3c:50:67:7d:21:74:2c:50:ef:5a:14:de: df:97:2c:46:4c:b9:fb:48:15:29:7d:be:0f:10:ca: 60:3d Exponent: 65537 (0x10001) X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Client Authentication X509v3 Basic Constraints: critical CA:FALSE X509v3 Authority Key Identifier: 69:C0:4F:A0:5E:6E:AC:8E:E6:10:C2:7C:C0:CB:8C:94:33:59:4E:49 Signature Algorithm: sha256WithRSAEncryption Signature Value: 34:aa:03:a5:2b:a6:be:5f:7e:a6:20:fc:f3:43:d6:ad:07:5c: 02:c1:52:f0:db:f1:31:33:2e:11:98:ac:5f:23:8e:6e:c4:30: a3:f6:e4:53:87:6e:b9:de:5c:fb:22:dc:59:8f:d9:5a:a1:c5: d0:c1:b5:66:23:0a:9c:da:c7:86:b8:61:b3:01:e7:5e:67:ca: 1d:ed:76:14:65:21:67:38:bf:89:aa:83:72:e5:70:ec:93:0c: a1:ec:2d:24:4c:c5:14:60:12:c7:88:70:dd:86:5f:ab:49:28: 5a:eb:ba:9d:85:8f:ba:03:fb:56:c9:ae:7c:f8:43:0c:bd:49: 75:1d:cd:b4:9d:35:aa:6f:ad:63:db:f1:0e:d1:7e:35:56:3f: 45:66:c6:5c:f0:c8:c7:4f:f0:73:b5:a9:fc:63:e2:0a:e2:e0: 24:e6:a1:72:ce:56:1c:f5:8d:69:56:4b:1d:ba:91:6e:d9:8c: 07:a4:06:0f:96:a5:95:0c:44:69:54:ba:2b:ae:d2:a8:48:56: fe:df:5c:0d:d2:8d:33:18:32:9a:6b:ba:aa:41:97:5d:02:85: 08:9a:29:48:3d:9f:b5:61:0f:8c:08:0f:1c:18:8d:35:68:68: 23:2f:85:eb:34:f3:2b:16:27:19:df:4e:2e:9c:7e:e1:eb:7c: 25:22:f1:60 |
Subject: O=kubeadm:cluster-admins, CN=kubernetes-admin 이것이 계정 정보다. 다음과 같은 의미를 가진다.
CN(Common Name) = kubernetes-admin: 쿠버네티스가 인식하는 이 사용자의 진짜 계정 IDO(Organization) = kubeadm:cluster-admins: 이 사용자가 속한 그룹(Group) 이름입니다.- 권한의 비밀: 쿠버네티스 안에는 “만약 어떤 유저가
kubeadm:cluster-admins그룹 소속이라면, 클러스터 전체를 마음대로 제어하는 관리자 권한(cluster-admin)을 준다”라는 **RBAC 규칙(ClusterRoleBinding)**이 기본적으로 설치되어 있다. 이 글자 덕분에 전지전능한 최고 관리자 권한을 누릴 수 있는 것.
또, Issuer: CN=kubernetes 라고 되어 있는데, 그 의미는 다음과 같다.
- 이 인증서를 누가 도장 찍어 발급해 주었는지(Issuer)를 보니 **
CN=kubernetes** - 바로 이전 단계에서 우리가 분석했던 그 10년짜리 Root CA 인증서의 이름(
Subject: CN=kubernetes)과 정확히 일치한다. 즉, 마스터 노드의 Root CA가 본인의 비밀키로 이 유저 신분증을 직접 서명해 준 정식 인증서라는 것을 뜻한다.
kubeadm:cluster-admins 그룹은 쿠버네티스에 클러스터 역할 바인딩(ClusterRoleBinding) 에 정의 되어 있다. 다음과 같이 확인할 수 있다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
$ kubectl get clusterrolebinding kubeadm:cluster-admins -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kubeadm:cluster-admins # 👈 이 연결 고리의 이름 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole # 👈 역할을 연결합니다. name: cluster-admin # 👈 신과 같은 최고 권한(Role) subjects: - apiGroup: rbac.authorization.k8s.io kind: Group # 👈 대상은 개인이 아닌 '그룹'입니다. name: kubeadm:cluster-admins # 👈 방금 인증서에서 본 그 그룹 이름! |
그렇다면 cluster-admin 은 어떤 권한을 가지고 있을까? 다음과 같이 확인할 수 있다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
$ kubectl get clusterrole cluster-admin -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" creationTimestamp: "2026-07-29T14:14:22Z" labels: kubernetes.io/bootstrapping: rbac-defaults name: cluster-admin resourceVersion: "69" uid: e584d0c8-6b77-4e10-b1b0-312d57697330 rules: - apiGroups: - '*' resources: - '*' verbs: - '*' - nonResourceURLs: - '*' verbs: - '*' |
모든게 와일드 카드로 되어 있다. 모든 것을 할 수 있는 권한을 가지고 있어서 결국에는 관리자 권한을 가진것과 같다.
여기서 중요한게 Users 의 인증서는 클라이언트 인증서라는 것이다. 클라이언트 인증서는 서버의 RootCA 의 비밀키로 서명을 해준 인증서가 된다. 그리고 인증은 클라이언트가 서버를 서버가 클라이언트를 서로 인증하는 mTLS 방식이다.
Contexts (어떤 계정으로 어느 클러스터에 갈 것인가?)
- ‘Cluster’와 ‘User’를 하나로 묶어주는 연결 고리입니다.
- “나는
developer계정(User)을 가지고production-cluster(Cluster)에 접속하겠다”와 같은 맵핑 정보를 정의합니다. - 특정 네임스페이스(Namespace)를 기본값으로 지정할 수도 있습니다.
이것은 일종의 프로필과 같다. AWS Configure 할때에 프로필을 만드는 것과 같다고 보면 된다. 앞서 설명한 Cluster, User 를 name을 붙여서 만들어 준다.
$HOME/.kube/config 파일에 대해서 알아 봤다. 이 파일을 잘 뜯아보면 쿠버네티스가 어떻게 동작하는지, 기초적인 인증에 대해서 다 알게 된다. 중요한 내용임에도 잘 모르는 사람들이 많아서 정리해봤다.