๐ŸŒŠ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ธ์ฆ [Static Token, Service Account, kube config, TLS, Role, RoleBinding]

๊น€์„ฑ์ธยท2023๋…„ 10์›” 21์ผ
0

[DevOps] ๐ŸณDocker & Kubernetes

๋ชฉ๋ก ๋ณด๊ธฐ
52/62

๋ชจ๋“  ํ†ต์‹ ์€ TLS๋ฅผ ํ†ตํ•ด Kube-apiserver๋ฅผ ์ด์šฉํ•˜์—ฌ ์š”์ฒญํ•จ
https://kubernetes.io/docs/reference/access-authn-authz/authentication/

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ธ์ฆ ์ฒด๊ณ„

https://kubernetes.io/docs/reference/access-authn-authz/authorization/#authorization-modules

  • RBAC/ABAC/Node Authorization, WebHook Mode
    • RBAC : role based access controll
    • ABAC : attribute based access controll
    • Webhook : HTTP ์ฝœ๋ฐฑ, ํŠน์ • ์ด๋ฒคํŠธ๋ฅผ ๋ฐœ์ƒํ• ๋•Œ URL์— ๋ฉ”์‹œ์ง€ ์ „๋‹ฌ

Account

  • ์ข…๋ฅ˜: user, Service Account(์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์‚ฌ์šฉ)

Static Token File

Apiserver ์„œ๋น„์Šค ์‹คํ–‰ ์‹œ --token-auth-file=<ํ† ํฐํŒŒ์ผ.csv>

  • static pod ์žฌ์„ค์ • ๋ฐ api์„œ๋ฒ„๋ฅผ ๋‹ค์‹œ ์‹œ์ž‘ํ•ด์•ผํ•จ
ํŒจ์Šค์›Œ๋“œ, ์œ ์ €, ์œ ์ €์•„์ด๋””, ๊ทธ๋ฃน  #ํ˜•ํƒœ์˜ ์—ด์„ ์ž‘์„ฑํ•จ

--token-auth-file=<ํ† ํฐํŒŒ์ผ.csv> ์„ค์ •์„ kube-apiserver ํŒŒ๋“œ์— ์ ์šฉํ• ๋•Œ ์ปจํ…Œ์ด๋„ˆ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆ๋ฅจ๋งˆ์šดํŠธ๋ฅผ ํ†ตํ•ด์„œ csvํŒŒ์ผ ๊ฒฝ๋กœ๋ฅผ ์„ค์ •ํ•ด์ฃผ๋„๋ก ํ• ๊ฒƒ

kubectl์— ๋“ฑ๋ก๋œ static token ์œ ์ € ๋“ฑ๋ก

$ kubectl config set-credentials user1 --token=password1 : ์œ ์ €์— ๋Œ€ํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ
$ kubectl config set-context user1-context --cluster=kubernetes \ --namespace=frontend --user=user1

  • ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋ฒ„๋ฅผ ์„ ํƒํ•˜๊ธฐ ์œ„ํ•œ ์ธ๊ฐ€ ์„ค์ •(kubernetes:๋งˆ์Šคํ„ฐ๋…ธ๋“œ?)
  • context -> ๋กœ๊ทธ์ธ์„ ํ†ตํ•ด ์—ฐ๊ฒฐํ•  ์•„์ด๋””์™€ kubernetes๋ฅผ ์—ฐ๊ฒฐ

$ kubectl get pod --user user1 : user1์œผ๋กœ ๋กœ๊ทธ์ธ

kubernetes-admin์œผ๋กœ ๋Œ์•„์˜ค๊ธฐ

kubectl config use-context kubernetes-admin@kubernetes


์„œ๋น„์Šค ์–ด์นด์šดํŠธ

https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

์„œ๋น„์Šค ์–ด์นด์šดํŠธ ํ™•์ธ

kubectl get sa default -o yaml (default์—๋Š” ์ž๋™ ์ƒ์„ฑ๋˜์–ด์žˆ์Œ)

์„œ๋น„์Šค ์–ด์นด์šดํŠธ ์ƒ์„ฑ

kubectl create serviceaccount <์„œ๋น„์Šค์–ด์นด์šดํŠธ๋ช…>

sa์™€ ํ•จ๊ป˜ ์‹œํฌ๋ฆฟ๋„ ์ƒ์„ฑ๋จ (์‹œํฌ๋ฆฟ ์•ˆ์—๋Š” ํ† ํฐ๊ฐ’ ์ƒ์„ฑ)

pod์— ์„œ๋น„์Šค์–ด์นด์šดํŠธ ์„ค์ •

spec.serviceAccount: <์„œ๋น„์Šค์–ด์นด์šดํŠธ๋ช…>

  • ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด default sa๋กœ ์„ค์ •๋จ
  • sa ์—ฐ๊ฒฐ ์‹œ ํ† ํฐ์ด ๋ถˆ๋ฅจ ๋งˆ์šดํŠธ๋จ
    https://kubernetes.io/ko/docs/tasks/administer-cluster/access-cluster-api/#kubectl-%ED%94%84%EB%A1%9D%EC%8B%9C-%EC%97%86%EC%9D%B4-%EC%A0%91%EA%B7%BC
    • ํŒŒ๋“œ ๋‚ด /var/run/secrets/kubernetes.io/serviceaccount
      ca.crt, namespace, token
    • TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
    • curl -X GET https://$KUBERNETES_SERVICE_HOST/api --header "Authorization: Bearer $TOKEN" โ€“insecure : ํ† ํฐ ๊ฐ’์„ ๋ณ€์ˆ˜๋กœ curl ๋ช…๋ น ์‹คํ–‰ (insecure ์ธ์ฆ์„œ ๊ธฐ๊ฐ„ ๋ฌด์‹œ)
    • KUBERNETES_SERVICE_HOST -> pod๋‚ด์— printenv๋ฅผ ํ†ตํ•ด์„œ ํ™•์ธ

TLS

SSL ์ธ์ฆ

Kubernetes ์ธ์ฆ์„œ ์œ„์น˜

sudo ls /etc/kubernetes/pki
sudo ls /etc/kubernetes/pki/etcd

TLS ์ธ์ฆ์„œ ํ™•์ธ

sudo ls /etc/kubernetes/manifests/

kubelet ์ธ์ฆ์„œ

sudo ls /var/lib/kubelet/pki
sudo ls /var/lib/kubelet/
sudo cat /var/lib/kubelet/config.yaml

์ธ์ฆ์„œ ์ •๋ณด ํ™•์ธ

sudo openssl x509 -in <certificate๊ฒฝ๋กœ> -text

Issure ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ํ™•์ธํ•ด์•ผํ•จ (์ธ์ฆ์„œ ๋ฐœ๊ธ‰ ์ œ๊ณต์ž)

์ธ์ฆ์„œ ์œ ํšจ๊ธฐ๊ฐ„ ํ™•์ธ ๋ฐ ๊ฐฑ์‹ 

kubeadm alpha certs check-expiration : ๋ชจ๋“  ์ธ์ฆ์„œ ์œ ํšจ ํ™•์ธ

  • kubeadm์€ ์ปจํŠธ๋กค ํ”Œ๋ ˆ์ธ์„ ์—…๊ทธ๋ ˆ์ด๋“œ ํ•˜๋ฉด ๋ชจ๋“  ์ธ์ฆ์„œ ์ž๋™ ๊ฐฑ์‹ 
    kubeadm alpha certs renew all : ๋ชจ๋“  ์ธ์ฆ์„œ ์ƒˆ๋กœ ๊ฐฑ์‹ 

์œ ์ € from TLS ์ธ์ฆ์„œ

https://kubernetes.io/ko/docs/tasks/administer-cluster/certificates/

1. ๊ฐœ์ธํ‚ค ๋ฐœ๊ธ‰

openssl genrsa -out <ํ‚คํŒŒ์ผ๋ช….key> 2048 : ๊ธธ์ด 2048 ๊ฐœ์ธํ‚ค ์ƒ์„ฑ

2. ๊ฐœ์ธํ‚ค๋ฅผ ์ด์šฉํ•ด ์ธ์ฆ์„œ ์„œ๋ช… ๋ฐœ๊ธ‰์š”์ฒญ

openssl req -new -key <๊ฐœ์ธํ‚คํŒŒ์ผ.key> -out <csrํŒŒ์ผ.csr> -subj "/CN=<์‚ฌ์šฉ์ž์ด๋ฆ„>/O=<๊ทธ๋ฃน์ด๋ฆ„>"

  • CN : ์‚ฌ์šฉ์ž์ด๋ฆ„
  • O: ๊ทธ๋ฃน ์ด๋ฆ„
  • ca์— ์ธ์ฆ ๊ฒฐ๊ณผ๋ฅผ csrํŒŒ์ผ๋กœ ๋ฐ›์Œ

3. csr์Šน์ธ

  • ๋‚ด๋ถ€ ์ง์ ‘ ์Šน์ธ ์ด์šฉ์‹œ pki ๋””๋ ‰ํ„ฐ๋ฆฌ ๋‚ด์— ca.key, ca.crt ์‚ฌ์šฉ
  • .csr ํŒŒ์ผ์„ ์ด์šฉํ•˜์—ฌ .crt ์ƒ์„ฑ
  • -days ์˜ต์…˜ ์‚ฌ์šฉํ•ด ์ธ์ฆ์„œ ์œ ํšจ๊ธฐ๊ฐ„ ์ง€์ •
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
    -CAcreateserial -out server.crt -days 10000 \
    -extensions v3_ext -extfile csr.conf -sha256

openssl x509 -req -in <csrํŒŒ์ผ.csr> -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out <๊ฒฐ๊ณผcrtํŒŒ์ผ.crt> -days 500

4. kubectl์— ์ธ์ฆ์„œ ๋“ฑ๋ก

4-1) ์œ ์ € ์„ค์ •

$ kubectl config set-credentials <์œ ์ €๋ช…> --client-certificate=.certs/<ca์ธ์ฆ์„œ. crt> --client-key=.certs/<๊ฐœ์ธํ‚ค.key>

4-2) ์œ ์ € ์ปจํ…์ŠคํŠธ ์„ค์ •

$ kubectl config set-context <์œ ์ €๋ช…>-context --cluster=kubernetes --namespace=office --user=<์œ ์ €๋ช…>

4-3) ์ปจํ…์ŠคํŠธ ๋ณ€๊ฒฝ

kubectl config use-context <์œ ์ €์ธ์ฆ ์ปจํ…์ŠคํŠธ>
kubectl config use-context kubernetes-admin@kubernetes : ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์–ด๋“œ๋ฏผ์œผ๋กœ ๋Œ์•„์˜ค๊ธฐ

4-4) ๋ช…๋ น ์ˆ˜ํ–‰

๊ถŒํ•œ์ด ์—†์–ด์„œ ์‘๋‹ต์ด Forbidden ์œผ๋กœ ์˜ค๋Š” ๋ชจ์Šต


kube config

kube config ํŒŒ์ผ์ด ์—†์œผ๋ฉด curl ์„ ํ†ตํ•ด์„œ ๋ช…๋ น ์ˆ˜ํ–‰ ํ•ด์•ผํ•จ -> ๋น„ํšจ์œจ์ 

kubeconfig ์œ„์น˜

cd $HOME/.kube/

kube config์กฐํšŒ

kube config view
kube config view --kube config=<configํŒŒ์ผ๋ช…>

๋“ฑ๋กํ•œ credential ๋กœ๊ทธ์ธ , ์ปจํ…์ŠคํŠธ ์ •๋ณด ๋“ฑ์ด ๋“ค์–ด์žˆ์Œ

  • cluster: ์—ฐ๊ฒฐํ•  ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํด๋Ÿฌ์Šคํ„ฐ ์ •๋ณด
  • users: ์‚ฌ์šฉํ•  ๊ถŒํ•œ ์‚ฌ์šฉ์ž
  • contexts: cluster์™€ user๋ฅผ ์ด์–ด์ฃผ๋Š” context ์ •๋ณด

ํด๋Ÿฌ์Šคํ„ฐ ์š”์ฒญ user ๋ฐ context ๋ณ€๊ฒฝ

kubectl config use-context <์ปจํ…์ŠคํŠธ๋ช…>@<ํด๋Ÿฌ์Šคํ„ฐ๋ช…>

kubectl ๋ช…๋ น์–ด context ์ง€์ •

kubectl get pod --context <๋“ฑ๋ก๋œ ์ปจํ…์ŠคํŠธ๋ช…>
kubectl get pod --user <๋“ฑ๋ก๋œ ์œ ์ €๋ช…>
kubectl get pod --as <๋“ฑ๋ก๋œ ์œ ์ €๋ช…>


RBAC

https://kubernetes.io/docs/reference/access-authn-authz/rbac/

์œ ์ € ๊ถŒํ•œ ๊ด€๋ฆฌ

  • rbac.authorization.k8s.ioAPI๋ฅผ ์‚ฌ์šฉ
  • ๊ถŒํ•œ ๊ฒฐ์ •์„ ๋‚ด๋ฆฌ๊ณ  Kubernetes Api๋ฅผ ํ†ตํ•ด ์ •์ฑ…์„ ๋™์ ์œผ๋กœ ๊ตฌ์„ฑ
  • RBAC๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ฃฐ ์ •์˜์‹œ apiserver์— --authorization-mode=RBAC ์˜ต์…˜ ํ•„์š”
    • kubeadm ์„ค์น˜์‹œ ์ด๋ฏธ ์„ค์ •๋˜์–ด์žˆ์Œ
      kube-apiserver --authorization-mode=Example,RBAC --other-options --more-options
  • ๋กค ์ •์˜ -> ๋กค ๋ถ€์—ฌ(๋ฐ”์ธ๋”ฉ)

rbac.authorization.k8s.ioAPI

  • ๋„ค์ž„ ์ŠคํŽ˜์ด์Šค ๋‚ด๋ถ€ (like ๊ฐœ๋ฐœ์ž)
    • Role
    • RoleBinding
  • ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ๊ตฌ์†์•ˆ๋จ (ํด๋Ÿฌ์Šคํ„ฐ ์ „์ฒด, ๊ด€๋ฆฌ์ž))
    • ClusterRole
    • ClusterRoleBinding

๋Œ€์‹œ๋ณด๋“œ์— ํด๋Ÿฌ์Šคํ„ฐ ๋กค์„ ๋ถ€์—ฌํ•˜์—ฌ ์‚ฌ์šฉ ํ•จ : ๋งํฌ

๋ฆฌ์†Œ์Šค - ๋กค(ํด๋Ÿฌ์Šคํ„ฐ) - ๋กค๋ฐ”์ธ๋”ฉ(ํด๋Ÿฌ์Šคํ„ฐ) - ์‚ฌ์šฉ์ž

๋กค

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  # "namespace" omitted since ClusterRoles are not namespaced
  name: secret-reader
rules:
- apiGroups: [""]
  #
  # at the HTTP level, the name of the resource for accessing Secret
  # objects is "secrets"
  resources: ["secrets"]
  verbs: ["get", "watch", "list"]

๋กค ๋ฐ”์ธ๋”ฉ

  • ๋ˆ„๊ฐ€ ํ•˜๋Š” ๊ฒƒ์ธ์ง€ ์ •ํ•จ
  • ๋กค ์ •์˜ X
  • ์–ด๋–ค ์‚ฌ์šฉ์ž์—๊ฒŒ ์–ด๋–ค ๊ถŒํ•œ ๋ถ€์—ฌํ• ์ง€ ์ •ํ•˜๋Š” ๋ฆฌ์†Œ์Šค
  • ์ผ๋ฐ˜๋กค-์ผ๋ฐ˜๋กค ๋ฐ”์ธ๋”ฉ, ํด๋Ÿฌ์Šคํ„ฐ๋กค-ํด๋Ÿฌ์Šคํ„ฐ๋กค ๋ฐ”์ธ๋”ฉ
apiVersion: rbac.authorization.k8s.io/v1
# This role binding allows "jane" to read pods in the "default" namespace.
# You need to already have a Role named "pod-reader" in that namespace.
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
# You can specify more than one "subject"
- kind: User  # ServiceAccount๋กœ๋„ ์„ค์ • ๊ฐ€๋Šฅ
  name: jane # "name" is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  # "roleRef" specifies the binding to a Role / ClusterRole
  kind: Role #this must be Role or ClusterRole
  name: pod-reader # this must match the name of the Role or ClusterRole you wish to bind to
  apiGroup: rbac.authorization.k8s.io
apiVersion: rbac.authorization.k8s.io/v1
# This cluster role binding allows anyone in the "manager" group to read secrets in any namespace.
kind: ClusterRoleBinding
metadata:
  name: read-secrets-global
subjects:
- kind: Group
  name: manager # Name is case sensitive
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: ClusterRole
  name: secret-reader
  apiGroup: rbac.authorization.k8s.io

๊ถŒํ•œ ๋ถ€์—ฌํ•˜๊ธฐ

TLS ์—์„œ ์‚ฌ์šฉํ–ˆ๋˜ test ์œ ์ € ์ปจํ…์ŠคํŠธ์— ๊ถŒํ•œ ๋ถ€์—ฌ

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
- apiGroups: [""] # "" indicates the core API group
  resources: ["pods"]
  verbs: ["get", "watch", "list"]
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: default
subjects:
- kind: User  
  name: test
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role 
  name: pod-reader 
  apiGroup: rbac.authorization.k8s.io

  • rolebinding์— ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ default๋กœ ์ง€์ •ํ•ด์ฃผ์—ˆ๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • .csrํŒŒ์ผ๋งŒ๋“ค๋•Œ O์˜ต์…˜์ด ๋„ค์ž„์ŠคํŽ˜์ด์Šค์ธ๊ฐ€?? ๋„ ํ™•์ธํ•ด๋ด์•ผ ํ• ๋“ฏํ•˜๋‹ค

0๊ฐœ์˜ ๋Œ“๊ธ€