Kubernetes의 Service Account와 kubeconfig 파일을 사용하여, kubernetes 클러스터 외부에서 접근하는 방법을 알아보도록 하겠습니다.
Service Account 생성
Kubernetes 1.24 부터 ServiceAccount 생성시 Secret을 자동으로 생성하지 않습니다.
Kubernetes 1.24 이상
# 생성
$ kubectl create sa test-sa
# 조회
$ kubectl get sa test-sa -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2024-09-11T05:01:12Z"
name: test-sa
namespace: default
resourceVersion: "6948234123"
uid: 234d3212-a859-44f6-8bfd-sdfsd123123
Kubernetes 1.23 이하
Kubernetes 1.23 이하 버전 사용시 Secret을 생성하지 않아도 됩니다. ServiceAccount 생성시 자동 생성됩니다.
# 생성
$ kubectl create sa test-sa
# 조회
$ kubectl get sa test-sa -o yaml
apiVersion: v1
kind: ServiceAccount
metadata:
creationTimestamp: "2024-09-11T05:01:12Z"
name: test-sa
namespace: default
resourceVersion: "6948234123"
uid: 234d3212-a859-44f6-8bfd-sdfsd123123
# secret이 생성되어 ServiceAccount에 secret이름이 연결되어있습니다.
secrets:
- name: test-sa-token-nsrc8
Secret 생성
Kubernetes 1.24 부터 Secret을 생성해야 합니다. Secret 생성시 kubernetes.io/service-account.name
annotation으로 생성한 ServiceAccount name을 설정해야 합니다.
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
name: test-sa-token
annotations:
# ServiceAccount name
kubernetes.io/service-account.name: "test-sa"
RBAC 권한 설정
Kubernetes의 리소스에 접근하기 위해서 권한설정을 해주셔야합니다. 아래의 예제는 Kubernetes에서 기본으로 제공되는 cluster-admin
(ClusterRole) 권한을 설정하였습니다. 예제 작성을 위해 cluster-admin 권한을 설정하였지만, 최소권한으로 설정하셔야 합니다. Role
/ RoleBinding
을 사용하여 특정 namespace의 권한을 설정하거나, ClusterRole
/ ClusterRoleBinding
cluster 레벨로 권한을 설정할 수 있습니다.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: test-sa-clusterrolebinding
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: test-sa
namespace: default
Kubeconfig 파일 생성
아래의 스크립트를 저장 후 실행하여 Kubeconfig 파일을 작성합니다.
#!/bin/bash
API_SERVER_URL=$1
NAMESPACE=$2
SERVICEACCOUNT=$3
SECRETNAME=$4
if [ -z "${API_SERVER_URL}" ]; then
echo "requried API_SERVER_URL"
echo "usage: make_kubeconfig.sh API_SERVER_URL NAMESPACE SERVICEACCOUNT"
exit 1
fi
if [ -z "${NAMESPACE}" ]; then
echo "requried NAMESPACE"
echo "usage: make_kubeconfig.sh API_SERVER_URL NAMESPACE SERVICEACCOUNT"
exit 1
fi
if [ -z "${SERVICEACCOUNT}" ]; then
echo "requried SERVICEACCOUNT"
echo "usage: make_kubeconfig.sh API_SERVER_URL NAMESPACE SERVICEACCOUNT"
exit 1
fi
if [ -z "${SECRETNAME}" ]; then
echo "requried SECRETNAME"
echo "usage: make_kubeconfig.sh API_SERVER_URL NAMESPACE SERVICEACCOUNT SECRETNAME"
exit 1
fi
CA=$(kubectl -n $NAMESPACE get secret $SECRETNAME -o jsonpath='{.data.ca\.crt}')
TOKEN=$(kubectl -n $NAMESPACE get secret $SECRETNAME -o jsonpath='{.data.token}' | base64 --decode)
echo "apiVersion: v1
kind: Config
clusters:
- name: default-cluster
cluster:
certificate-authority-data: ${CA}
server: ${API_SERVER_URL}
contexts:
- name: default-context
context:
cluster: default-cluster
namespace: ${NAMESPACE}
user: ${SERVICEACCOUNT}
current-context: default-context
users:
- name: ${SERVICEACCOUNT}
user:
token: ${TOKEN}
"
API Server Endpoint
kubectl 명령어를 사용하면 확인할 수 있습니다.
$ kubectl cluster-info
Kubernetes control plane is running at https://324JN324JKHNB32KJ4NB32KJ432KJ4N2.nn1.ap-northeast-2.eks.amazonaws.com
스크립트 실행
위의 파일을 /tmp/kubeconfig.sh
파일로 저장하여 실행하는 예제입니다.
/tmp/kubeconfig.sh https://324JN324JKHNB32KJ4NB32KJ432KJ4N2.nn1.ap-northeast-2.eks.amazonaws.com default test-sa test-sa-token > /tmp/kubeconfig.yaml
kubectl
생성된 Kubeconfig 파일을 사용하여 kubectl
명령어를 사용할 수 있습니다. 예제에서는 RBAC 권한이 cluster-admin
으로 설정되어있어서 모든 namespace의 POD를 조회할 수 있습니다. RBAC 권한에 따라 namespace 또는 리소스 접근에 제한이 걸릴 수 있습니다.
$ kubectl --kubeconfig=/tmp/kubeconfig.yaml get pod --all-namespaces