💡 핵심 요약 (Executive Summary)
본 가이드는 readonly sa와 kubeconfig 핵심 가이드 및 실전 아키텍처의 핵심 개념, 실전 구성 명령어 및 아키텍처 베스트 프랙티스를 다룹니다. 클라우드 네이티브 및 인프라 엔지니어링 실무에 즉시 활용 가능하도록 체계적으로 정리했습니다.
📑 Table of Contents
readonly SA, Secrets, Kubeconfig
권한 생성
env
bash
export prefix=read-only
export ns=default
SA, token, CRB 생성
bash
kubectl create serviceaccount ${prefix}-sa -n ${ns}
kubectl apply -f - << EOF
apiVersion: v1
kind: Secret
metadata:
name: ${prefix}-sa-token
namespace: ${ns}
annotations:
kubernetes.io/service-account.name: "${prefix}-sa"
type: kubernetes.io/service-account-token
EOF
kubectl apply -f - << EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ${prefix}-clusterrolebinding
subjects:
- kind: ServiceAccount
name: ${prefix}-sa
namespace: ${ns}
roleRef:
kind: ClusterRole
name: ${prefix}-clusterrole
apiGroup: rbac.authorization.k8s.io
EOF
kubectl get secret ${prefix}-sa-token -n ${ns} -o jsonpath="{.data.token}" | base64 --decode
ClusterRole 정의
- 최소 권한 정책(Principle of Least Privilege, POLP)을 적용
bash
kubectl apply -f - << EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ${prefix}-clusterrole
rules:
- apiGroups: ["","apps","batch","autoscaling","app.k8s.io"]
resources: ["pods","services","replicasets","deployments","daemonsets","statefulsets","replicationcontrollers","horizontalpodautoscalers","cronjobs","jobs","applications"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
verbs: ["get", "list", "watch"]
EOF
- OPA를 통한 예외사항 관리
bash
kubectl apply -f - << EOF
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: ${prefix}-clusterrole
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["get", "list", "watch"]
EOF
#ex) read-only로 시작하는 sa or clusterrole or role을 제한
kubectl apply -f - << EOF
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: deny-read-only-access
spec:
crd:
spec:
names:
kind: DenyReadOnlyAccess
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package denyreadonlyaccess
violation[{"msg": msg}] {
# 요청된 리소스가 Secret 또는 ServiceAccount인지 확인
input.review.object.kind == "Secret" || input.review.object.kind == "ServiceAccount"
# 요청된 동작이 get, list, watch 중 하나인지 확인
input.review.operation == "GET" || input.review.operation == "LIST" || input.review.operation == "WATCH"
# 요청한 사용자 정보 추출
factor := "read-only"
subject := input.review.userInfo.username
# ServiceAccount, Role, ClusterRole 이름이 "read-only"로 시작하는지 확인
startswith(subject, "system:serviceaccount:") {
sa_name := split(subject, ":")[2]
startswith(sa_name, factor)
}
startswith(subject, factor)
msg := sprintf("'%s'로 시작하는 Role이나 ServiceAccount인 '%s'는 Secret 리소스에 접근할 수 없습니다.", [factor,subject])
}
EOF
kubectl apply -f - << EOF
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: DenySecretAccessConstraint
metadata:
name: deny-secret-access-for-users
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Secret"]
subjects:
- kind: User
name: "example-user" # 특정 사용자
- kind: Group
name: "example-group" # 특정 그룹
EOF
접근정보 생성
env
bash
export prefix=read-only
export ns=default
export clustername=kubernetes
export SERVER=
1안: certificate-authority-data를 포함한 kubeconfig 생성
bash
cat <<EOF >> kubeconfig
apiVersion: v1
kind: Config
clusters:
- name: ${clustername}
cluster:
certificate-authority-data: $(kubectl config view --raw -o jsonpath="{.clusters[0].cluster.certificate-authority-data}")
server: ${SERVER}
contexts:
- name: ${prefix}-context
context:
cluster: ${clustername}
namespace: ${ns}
user: ${prefix}-user
current-context: ${prefix}-context
users:
- name: ${prefix}-user
user:
token: $(kubectl get secret ${prefix}-sa-token -n ${ns} -o jsonpath="{.data.token}" | base64 --decode)
EOF
2안: insecure-skip-tls-verify를 enable하고 kubeconfig 생성
bash
cat <<EOF >> kubeconfig
apiVersion: v1
kind: Config
clusters:
- name: ${clustername}
cluster:
insecure-skip-tls-verify: true
server: ${SERVER}
contexts:
- name: ${prefix}-context
context:
cluster: ${clustername}
namespace: ${ns}
user: ${prefix}-user
current-context: ${prefix}-context
users:
- name: ${prefix}-user
user:
token: $(kubectl get secret ${prefix}-sa-token -n ${ns} -o jsonpath="{.data.token}" | base64 --decode)
EOF
클라이언트 설정
bash
export prefix=read-only
kubectl config use-context ${prefix}-context
Leave a Reply