[쿠버네티스] 인증/인가 - X.509 인증서를 사용한 사용자 추가 및 인증

목차


쿠버네티스는 사용자를 “인증”하는 방식만 알면 되고, 사용자 정보를 자체를 저장하지 않습니다.

X.509 인증서 를 사용하는 방식은 사용자 인증서를 만들고 클러스터에 등록해서 인증하는 방식입니다.

✅ 1. 사용자 인증서 및 키 생성

1. 개인 키 (Private Key) 생성

RSA 알고리즘으로 개인 키 생성 하게 되면 dev-user.key 파일이 생성됩니다.

개인 키는 인증서 서명 요청(CSR)을 만들 때 필요하며 이후 쿠버네티스 API 서버와 통신 시 이 키로 서명된 인증서를 사용해 본인을 증명

openssl genrsa -out dev-user.key 2048

2. CSR (Certificate Signing Request, 인증서 서명 요청) 생성

개인 키를 기반으로 사용자 정보를 포함하는 CSR을 생성합니다. 아래 명령어를 이용하면 dev-user.csr 파일이 생성됩니다.

CN=dev-user: 사용자의 이름
O=dev-group: 그룹 이름 (RBAC에서 사용 가능)

openssl req -new \
-key dev-user.key \
-out dev-user.csr \
-subj "/CN=dev-user/O=dev-group"

✅ 2. 클러스터 CA로 인증서 서명

이 단계는 Kubernetes 클러스터의 CA 인증서와 키가 필요합니다. 클러스터 CA 를 사용하여 CSR에 서명해 X.509 인증서를 발급합니다. 아래 명령어를 이용하면 dev-user.crt 파일이 생성됩니다.

보통 kubeadm 으로 설치한 경우에는 /etc/kubernetes/pki/ca.crt, /etc/kubernetes/pki/ca.key 경로에 있습니다

sudo openssl x509 -req \
-in dev-user.csr \
-CA /etc/kubernetes/pki/ca.crt \
-CAkey /etc/kubernetes/pki/ca.key \
-CAcreateserial \
-out dev-user.crt \
-days 365

이제 dev-user.crt와 dev-user.key가 준비되었습니다.

✅ 3. kubeconfig 파일에 사용자 추가

방법 1. 기존 config에 수동으로 추가

users:
- name: dev-user
user:
client-certificate: /path/to/dev-user.crt
client-key: /path/to/dev-user.key

contexts:
- name: dev-context
context:
cluster: your-cluster
user: dev-user
namespace: default

current-context: dev-context

방법 2. kubectl config 명령어로 추가

아래 명령어를 이용하여 위에서 생성한 인증서와 개인키를 kubeconfig 파일에 dev-user 이름으로 인증정보를 등록합니다.

# 인증서와 개인키를 등록
kubectl config set-credentials dev-user \
--client-certificate=/path/to/dev-user.crt \
--client-key=/path/to/dev-user.key

위에서 등록된 인증정보를 이용해 클러스터에 접근할 수 있도록 context 정보를 kubeconfig 파일에 추가해줍니다.

# 클러스터와 namespace 그리고 user 정보를 등록합니다.
kubectl config set-context dev-context \
--cluster=your-cluster-name \
--namespace=default \
--user=dev-user

최종 config 모습

위 정보들을 ./kube/config 파일에 반영하면 아래와 같은 모습입니다.

config
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRV ....생략.... QVRFLS0tLS0K
server: <kubernetes api server 주소>
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: dev-user
namespace: default
name: home-kubernetes
current-context: home-kubernetes
kind: Config
preferences: {}
users:
- name: dev-user
user:
client-certificate: /Users/dongwoo-yang/.kube/cert/dev-user.crt
client-key: /Users/dongwoo-yang/.kube/cert/dev-user.key

✅ 4. 사용자 권한 부여 (RBAC 설정)

dev-role.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list"]
dev-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods-binding
namespace: default
subjects:
- kind: User
name: dev-user # <-- 여기의 이름은 인증서의 CN과 같아야 함
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io

✅ 5. 테스트

부여한 권한이 제대로 작동하는지 확인합니다. 저는 pod 에 대한 조회 권한을 보여 했으므로 아래 명령어를 이용했을때 pod 목록이 나와야 합니다.

kubectl --context=dev-context get pods -n <네임스페이스>

제가 default 네임스페이스에는 리소스를 생성하지 않아 Role 과 RoleBinding 의 namespace 만 리소스가 있는 monitoring 으로 변경 후 다시 적용했고 위 명령어를 이용해 조홰했더니 pod 목록이 정상적으로 나오는 것을 확인할 수 있었습니다.

❯ k get pod -n monitoring   
NAME READY STATUS RESTARTS AGE
grafana-bc77b49c6-x5zbh 1/1 Running 0 40d
loki-0 2/2 Running 0 39d
loki-canary-zkd5s 1/1 Running 0 39d
loki-chunks-cache-0 2/2 Running 0 39d
loki-gateway-6447bff65b-9q5fq 1/1 Running 0 39d
loki-minio-0 1/1 Running 0 39d
loki-results-cache-0 2/2 Running 0 39d
prometheus-alertmanager-0 1/1 Running 0 35d
prometheus-kube-state-metrics-648ddc549f-9xnjm 1/1 Running 0 35d
prometheus-prometheus-node-exporter-tfjgp 1/1 Running 0 35d
prometheus-prometheus-pushgateway-76bc7454df-4j44q 1/1 Running 0 35d
prometheus-server-8cd958945-lhxtp 3/3 Running 0 33d
promtail-952sx 1/1 Running 0 39d

권한제어 Validation 테스트

현재 생성된 User 는 Pods 에 대한 조회 권한 밖에 없습니다. 해당 권한을 넘어가는 명령어를 실행함으로써 권한 제어가 제대로 작동하는지 확인합니다.

kubectl apply -f dev-role-monitoring.yaml

새로운 Role 을 생성하도록 했는데, Validation 이 정상적으로 작동하는 것을 확인할 수 있었습니다.

Error from server (Forbidden): error when retrieving current configuration of:
Resource: "rbac.authorization.k8s.io/v1, Resource=roles", GroupVersionKind: "rbac.authorization.k8s.io/v1, Kind=Role"
Name: "pod-reader-monitoring", Namespace: "monitoring"
from server for: "dev-role-monitoring.yaml": roles.rbac.authorization.k8s.io "pod-reader-monitoring" is forbidden: User "dev-user" cannot get resource "roles" in API group "rbac.authorization.k8s.io" in the namespace "monitoring"
Share