PaaS/Kubernetes

k8s 보안, 최소권한으로 특정 NameSpace에 대한 권한만 부여하기

armyost 2023. 11. 8. 21:51
728x90

Zero Trust가 유행함에 따라서 모든 영역이 보안의 영역이 되었다. 과거에는 k8s Cluster Wide한 권한을 편의상 사용해왔는데, 점점 보안이 강화되는 분위기라 Service Account와 Role에 대한 이해도가 필요해졌다.

 

아래 샘플은 특정 NameSpace의 특정 자원에 대해서만 CRUD가 가능한 권한을 매핑한 YAML이다.

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: null
  name: sample-role
  namespace: sample-ns
rules:
- apiGroups:
  - ""
  resources:
  - services
  - deployments
  - pods
  verbs:
  - get
  - list
  - update
  - create
  - patch
  - delete


---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  creationTimestamp: null
  name: sample-rolebinding
  namespace: sample-ns
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: sample-role
subjects:
- kind: ServiceAccount
  name: sample-sa
  namespace: sample-ns

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: sample-sa
  namespace: sample-ns

---
apiVersion: v1
kind: Secret
metadata:
  name: sample-secret
  namespace: sample-ns
  annotations:
    kubernetes.io/service-account.name: sample-sa
type: kubernetes.io/service-account-token

 

위와 같은 YAML을 작성하여 배포한다.

$ kubectl apply -f ~~~.yaml

 

그리고 아래의 Bash Shell Script를 돌려 kubeconfig를 하나 생성한다. 

물론 SERVER 주소나 NAMESPACE 같은것들은 본인 환경에 맞추어 바꾼다.

#!/bin/bash

# your server name goes here
export SERVER="https://192.168.122.181:6443"
# the name of the service account
SA_NAME="sample-sa"
# the name of the namespace
NAMESPACE="sample-ns"
# the name of the token
TOKEN_NAME="sample-secret"


echo "Server URL is ${SERVER}"
echo "SA name is ${SA_NAME}"
echo "NameSpace is ${NAMESPACE}"


CA="$(kubectl -n ${NAMESPACE} get secret/${TOKEN_NAME} -o jsonpath='{.data.ca\.crt}')"
TOKEN="$(kubectl -n ${NAMESPACE} get secret/${TOKEN_NAME} -o jsonpath='{.data.token}' | base64 --decode)"
NAMESPACE="$(kubectl -n ${NAMESPACE} get secret/${TOKEN_NAME} -o jsonpath='{.data.namespace}' | base64 --decode)"

echo "---------------- TOKEN NAME -------------------"
echo $TOKEN_NAME

echo "---------------- CA -------------------------"
echo $CA

echo "-------------- TOKEN ------------------------"
echo $TOKEN

echo "--------------- NAMESPACE ---------------------"
echo $NAMESPACE



echo "
apiVersion: v1
kind: Config
clusters:
- name: default-cluster
  cluster:
    certificate-authority-data: ${CA}
    server: ${SERVER}
contexts:
- name: default-context
  context:
    cluster: default-cluster
    namespace: ${NAMESPACE}
    user: ${SA_NAME}
current-context: default-context
users:
- name: ${SA_NAME}
  user:
    token: ${TOKEN}
" > kubeconfig

 

만들어진 kubeconfig 파일을

~/.kube/config 경로에 덮어 쓴다음 권한이 잘 먹혀들어 갔는지 kubectl 쿼리를 해본다.

 

sample-ns NameSpace에 대해서 pods를 조회하면 정상적으로 먹지만

sample-ns-temp NameSpace에 대해서 pods를 조회하면 권한이 없다고 뜬다.