본문 바로가기

쿠버네티스

kubectl 사용자 별 권한 설정하기

쿠버네티스에서 서비스를 운영하다 보면 특정 사용자에게, 특정 NameSpace에 대한 권한을 부여해야 하는 경우가 있습니다. 특정 기능 개발을 위한 임시 권한이 필요하거나, NameSpace별로 서비스 담당자를 구분하여 관리할 때입니다.

 

 

 

 

모든 사용자가 동일한 Bsation Server를 사용해야 할 때,  Bastion Server의 User별 kubectl 권한을 분리하는 방법에 대해 자세히 소개합니다. 

 

※ 본 포스팅은 다음 환경에서 테스트하였습니다. 

 - Bastion Server : Ubuntu 22.04

 - Kubernetes Version : v1.29.3

 - kubectl Version : v1.29.3

 

 

Kubectl 사용자 별 권한 설정하기

 

목 차

 

1. Bastion 서버에서 사용자 생성 

모든 사용자가 동일한 Bastion Server를 사용하므로, 사용자 별 계정을 생성하여 kubectl을 실행하도록 설정해야 합니다. Ubuntu에서는 adduser 명령어를 통해 User를 생성할 수 있습니다.

# 새 사용자 생성 (ex: devuser)
sudo adduser devuser

 

adduser 명령어로 사용자를 생성할 경우 패스워드를 함께 설정해야 합니다. 적절한 패스워드를 설정한 후 메모합니다.

 

2. Kubernetes RBAC(Role-Based Access Control) 설정

Kubernetes에서는 RBAC를 이용하여 특정 사용자에게 특정 네임스페이스에서만 권한을 부여할 수 있습니다.

 

2.1 Kubernetes Cluster에서 ServiceAccount 생성

 

사용자가 Kubernetes API를 사용할 때 ServiceAccount를 통해 인증하도록 설정합니다.

  • NameSpace : dev-ns
  • ServiceAccount : devuser-sa
kubectl create namespace dev-ns  # 권한을 부여할 네임스페이스 생성
kubectl create serviceaccount devuser-sa -n dev-ns  # ServiceAccount 생성

 

2.2 Role 생성 (dev-ns에서 Read, Write, List 권한 부여)

 

dev-ns에서 pod, deployment, service, configmap, secret, pvc에 대한 Read, Write, List 권한을 부여합니다. 

개인의 상황에 맞추어 ClusterRole을 생성할 수 있습니다. 

cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: dev-ns
  name: devuser-role
rules:
- apiGroups: [""] # Core API 그룹
  resources: ["pods", "deployments", "services", "configmaps", "secrets", "persistentvolumeclaims"]
  verbs: ["get", "list", "create", "update"]
EOF

 

2.3 RoleBinding을 생성하여 ServiceAccount와 연결

 

RoleBinding을 통해 위에서 생성한 ServiceAccount와 Role을 연결합니다. 

cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  namespace: dev-ns
  name: devuser-rolebinding
subjects:
- kind: ServiceAccount
  name: devuser-sa
  namespace: dev-ns
roleRef:
  kind: Role
  name: devuser-role
  apiGroup: rbac.authorization.k8s.io
EOF

 

3. devuser가 kubectl을 사용하도록 kubeconfig 설정

이제 devuser가 kubectl을 사용할 수 있도록 kubeconfig 파일을 생성해야 합니다.

 

 

 

 

 

kubeconfig 파일 생성을 위해선, ServiceAccount의 Token 이 필요합니다. 

Kubernetes v1.24.0 이후부터는 ServiceAccount 생성 시 Token이 자동으로 생성되지 않으므로, Token을 생성합니다. 

 

3.1. ServiceAccount의 Token 생성하기 

ServiceAccount의 Token은 장기 토큰과 단기 토큰이 있습니다. 

단기 토큰의 경우 자동으로 만료되므로, Secret을 통해 장기 토큰을 생성합니다. 

생성한 토큰은 secret 이 삭제되기 전까지 유효합니다. 

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: devuser-sa-token
  namespace: dev-ns
  annotations:
    kubernetes.io/service-account.name: devuser-sa
type: kubernetes.io/service-account-token
EOF

 

3.2 Secret을 통해 Token 확인

생성한 Token 은 다음 명령어를 통해 확인할 수 있습니다.

kubectl get secret devuser-sa-token -n dev-ns -o jsonpath='{.data.token}' | base64 --decode

 

3.3 devuser의 Kubeconfig 생성

devuser의 kubectl 사용을 위해 kubeconfig를 생성합니다.

mkdir -p /home/devuser/.kube
cat <<EOF > /home/devuser/.kube/config
apiVersion: v1
kind: Config
clusters:
- cluster:
    certificate-authority-data: $(kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')
    server: $(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    namespace: dev-ns
    user: devuser-sa
  name: devuser-context
current-context: devuser-context
users:
- name: devuser-sa
  user:
    token: $(kubectl get secret devuser-sa-token -n dev-ns -o jsonpath='{.data.token}' | base64 -d)
EOF

 

3.4 devuser의 kubeconfig 파일 권한 설정

devuser가 kubectl을 실행할 수 있도록 권한을 설정합니다.

# 권한 설정
chown -R devuser:devuser /home/devuser/.kube
chmod 600 /home/devuser/.kube/config

 

4. devuser가 실행할 수 있는 명령어 제한

4.1 sudo 없이 kubectl만 실행하도록 설정

기본적으로 devuser가 kubectl만 실행하고 다른 명령어는 사용하지 못하게 하려면 다음과 같이 restricted_shell을 구성할 수 있습니다.

 

4.2 devuser의 기본 쉘을 제한된 쉘로 변경

sudo chsh -s /bin/rbash devuser

 

4.3 kubectl만 실행하도록 제한

sudo mkdir -p /home/devuser/bin
sudo ln -s /usr/bin/kubectl /home/devuser/bin/kubectl
sudo chown -R devuser:devuser /home/devuser/bin

 

4.4 devuser의 . bashrc를 수정하여 PATH 제한

echo 'export PATH=$HOME/bin' >> /home/devuser/.bashrc
echo 'export KUBECONFIG=$HOME/.kube/config' >> /home/devuser/.bashrc
echo 'set +o history' >> /home/devuser/.bashrc  # 명령어 기록 방지

 

4.5 devuser가 다른 명령어를 실행하지 못하게 설정

sudo chmod 750 /home/devuser
sudo chmod 750 /home/devuser/.kube

 

 

5. 검증 

이제 devuser로 로그인하여 kubectl을 실행할 수 있는지 확인합니다.

su - devuser
kubectl get pods -n dev-ns  # 정상 동작해야 함
kubectl get pods -n default  # 접근 거부 오류 발생해야 함

 

만약 kubectl 외 다른 명령어 실행을 시도하면 다음과 같은 오류가 발생해야 합니다.

-bash: ls: command not found

 

 

6. 요약정리

  1. Ubuntu에 devuser 계정을 생성
  2. Kubernetes에서 ServiceAccount를 만들고, Role 및 RoleBinding을 생성하여 dev-ns에 대한 권한 부여
  3. Kubeconfig를 생성하여 devuser가 사용할 수 있도록 설정
  4. Restricted Shell 설정을 통해 kubectl 외 다른 명령어 실행을 차단
  5. 테스트를 통해 정상적으로 권한이 제한되었는지 검증