Kubernetes 클러스터 구축기 글에서 3대의 VM으로 쿠버네티스 클러스터를 구축하는 과정을 공유했습니다. 그런데 이 k8s에 Pod를 올리고, 관리하기 위해 매번 마스터 노드로 접속해야 할까요? 운영 서버인 마스터 노드에 접속하는 것은 위험성도 존재합니다. 내 컴퓨터 또는 개발용 서버에서 접속할 수 있다면 좋겠습니다.
k9s는 터미널 기반 UI를 제공하여 쿠버네티스 클러스터 상태나 로그를 편리하게 확인할 수 있는 도구입니다. 로컬 개발 환경에 k9s를 설치하고 RBAC 설정을 통해 안전하게 쿠버네티스 클러스터에 원격으로 접속할 수 있습니다. 이번 글에서는 제 맥북에 k9s를 설치하고 쿠버네티스 클러스터의 원격 접속 환경을 구성하는 과정을 정리했습니다.
설치
설치는 어렵지 않습니다. macOS에서는 Homebrew를 통해 간단하게 설치할 수 있고, 다른 패키지 관리도구를 통해 설치하고나 직접 빌드할 수도 있습니다1.
1brew install derailed/k9s/k9s
Kubernetes 원격 접속
Kubernetes를 설치하면 admin 관리자 계정이 기본적으로 존재합니다. 하지만 admin 계정은 그 이름처럼 강력한 권한을 갖고 있습니다. admin 계정 대신 지금 필요한 권한만 부여한 서비스 계정을 생성하여 접속하보겠습니다.
다만, 아직은 서비스 계정 없이 admin 계정만 존재하므로 이 단계는 k8s 마스터노드에서 진행해야 합니다.
서비스 계정 추가
1# sa-user1.yaml
2apiVersion: v1
3kind: ServiceAccount
4metadata:
5 name: user1
6 namespace: default
7---
8apiVersion: v1
9kind: Secret
10type: kubernetes.io/service-account-token
11metadata:
12 name: user1-token
13 annotations:
14 kubernetes.io/service-account.name: user1
- 여기서 토큰은 비밀번호/APIKEY와 유사하게 이후 접속 과정에서 사용됩니다.
1➜ kubectl apply -f serviceaccount/sa-user1.yaml
2serviceaccount/user1 created
3secret/user1-token created
4
5➜ kubectl get sa
6NAME SECRETS AGE
7default 0 93d
8user1 0 2s
역할(Role) 추가
방금 추가한 계정이 어떤 일을 할 수 있는 계정인지 역할을 정의하고 엮어주겠습니다2. 우선은 view-읽기만 가능한 역할을 할당해줍니다. 이 계정은 현재 클러스터에 어떤 것들이 있는지 볼 수는 있지만, 실수로 리소스 삭제 명령을 실행하더라도 권한이 없어 실제로는 삭제가 되지 않기 때문에 사고를 방지할 수 있습니다.
1# sa-user1-role.yaml
2---
3apiVersion: rbac.authorization.k8s.io/v1
4kind: ClusterRoleBinding
5metadata:
6 name: user1-cluster-view-binding
7subjects:
8 - kind: ServiceAccount
9 name: user1
10 namespace: default
11roleRef:
12 kind: ClusterRole
13 name: view
14 apiGroup: rbac.authorization.k8s.io
1➜ kubectl apply -f serviceaccount/sa-user1-role.yaml
2clusterrolebinding.rbac.authorization.k8s.io/user1-cluster-view-binding created
3
4➜ kubectl auth can-i list pods --all-namespaces --as=system:serviceaccount:default:user1
5yes
토큰 발급
서비스 계정 추가 단계에서 토큰도 정의했습니다. 이제 이 계정으로 접속할 때 사용할 토큰을 발급합니다.
1➜ kubectl create token user1 --bound-object-kind Secret --bound-object-name user1-token
2# 아주.. 길고.. 알 수 없는.. 토큰...
- 이 출력값은 다음 단계에서 사용되므로 메모장에 복사해둡니다.
kubeconfig 작성
이 단계에서 ~/.kube/config 파일은 로컬 개발 환경에 만들고 접속에 필요한 정보를 입력해줍니다. 다만, 필요한 정보를 수집하기 위한 명령어는 마스터 노드에서 실행해야 될 수 있습니다.
1apiVersion: v1
2kind: Config
3clusters:
4- cluster:
5 certificate-authority-data: <BASE64_CA>
6 server: https://<API_SERVER_IP>:6443
7 name: my-k8s
8contexts:
9- context:
10 cluster: my-k8s
11 user: user1
12 name: user1@my-k8s
13users:
14- name: user1
15 user:
16 token: <EXTRACTED_TOKEN>
17current-context: user1@my-k8s
- cluster의
ca정보는 마스터노드에서kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}'명령어로 얻을 수 있습니다. server주소는 마스터노드에서kubectl cluster-info명령어로 확인할 수 있습니다.clusters > cluster의name은 원하시는대로 설정하면 됩니다. 다만, 이후context > cluster와는 일치해야합니다.context > name과current-context의 관계도 동일합니다.token에는 메모장에 복사해둔 토큰을 입력합니다.
k9s 실행
1➜ k9s
2# 만약 다른 context가 있고 바꿔서 접속하려는 경우 --context user2@my-k8s 와 같이 옵션 추가하여 실행

접속은 잘 되었으나, default namespace에는 배포된 것이 없어서 아무것도 보이지 않습니다.
키보드에서 0을 눌러 모든 namespace 기준으로 보면 아래와 같이 현재 실행 중인 pod가 잘 보입니다.

“Installation,” k9scli.io, Accessed: Mar. 8, 2026. [Online]. Available: https://k9scli.io/topics/install/ ↩︎
“RBAC,” k9scli.io, Accessed: Mar. 8, 2026. [Online]. Available: https://k9scli.io/topics/rbac/ ↩︎
Comments