
์ฟ ๋ฒ๋คํฐ์ค๋ฅผ ๊ณต๋ถํ๋ฉด์ ์ฒ์ User Account ์ Service Account ๋ฅผ ์ ํ์ ๋ ๋จ์ํ ์ฟ ๋ฒ๋คํฐ์ค API ์๋ฒ์๊ฒ ์๊ฒฉ ์ฆ๋ช
ํ๋ ๋ฆฌ์์ค์ธ๊ฐ๋ณด๋ค ํ๊ณ ๋์ด๊ฐ๋ ์ ์ด ์์ต๋๋ค. ์ดํด๊ฐ ์๋์ ๊ทธ๋ฅ ๋์ด๊ฐ๋..
๊ทธ๋์ User Account ๋ Service Account ๋ ๋น์ทํ๊ฑฐ !! ๊ฐ์ ๊ฑฐ !! ๋ผ๋ ์๊ฐ์ ๊ฐ์ง๊ณ ์์์ฃ .. ํ์ง๋ง ์ด ๋์ ๋ถ๋ช ๋ค๋ฆ ๋๋ค.
์ฟ ๋ฒ๋คํฐ์ค์๋ ์ฟ ๋ฒ๋คํฐ์ค ๋ด์ ์กด์ฌํ๋ ์์์ ๋ํ ์ ๊ทผ์ ์ํ 2๊ฐ์ง์ account ํ์ ์ด ์กด์ฌํฉ๋๋ค.
- User Account
- Service Account
์ฟ ๋ฒ๋คํฐ์ค ๊ณต์ ๋ฌธ์์๋ ์ด์ ๊ฐ์ด ๋์์์ต๋๋ค.
<code />์ฌ์ฉ์ ์ด์นด์ดํธ๋ ์ฌ๋์ ์ํ ๊ฒ์ด๋ค. ์๋น์ค ์ด์นด์ดํธ๋ ํ๋์์ ์คํ๋๋ ํ๋ก์ธ์ค๋ฅผ ์ํ ๊ฒ์ด๋ค.
100% ๋ง๋ ๋ง์ด์ง๋ง, ์ฒ์ ์ ํ๋ค๋ฉด ์ ์ดํด๊ฐ ๋์ง ์์ต๋๋ค. ์ ๋ํ ๊ทธ๋ฌ๊ณ ์ ๐ค
AWS ๋ฅผ ๊ฐ์ง๊ณ ์๋ฅผ ๋ค์ด๋ณด์ฃ !

์ฐ๋ฆฌ๊ฐ AWS ํํ์ด์ง์ ๋ค์ด๊ฐ๊ฒ ๋๋ค๋ฉด, ๊ฐ์ฅ ๋จผ์ ํด์ผํ ๊ฒ์ ๋ก๊ทธ์ธ ์ผ ๊ฒ์ ๋๋ค.
๋ก๊ทธ์ธ ํตํด์ AWS ์๊ฒ ์ฐ๋ฆฌ๊ฐ ๋๊ตฐ์ง ์ฆ๋ช ์ ํ ์ ์์ต๋๋ค.
๋ก๊ทธ์ธ ํ EC2 ๋ฅผ ์ด์ฉํฉ๋๋ค. EC2 ๋ ๊ฐ์ ๋จธ์ ์ ๋น๋ ค์ฃผ๋ ์๋น์ค์ ๋๋ค. ๊ทธ๋ฆฌ๊ณ ssh ๋ฅผ ํตํด EC2 ์ ์ ์ํฉ๋๋ค.
EC2 ์์ ์ฐ๋ฆฌ๋ S3 ์ ์กด์ฌํ๋ test.img ๋ฅผ ์ฌ์ฉํ๋ ค๊ณ ํฉ๋๋ค.

ํ์ง๋ง EC2 ์์ S3 ์ ์ ๊ทผ์ด ๋ถ๊ฐ๋ฅํ์ฃ . ์๋ EC2 ๋ S3 ์ ์ ๊ทผํ ์ ์๋ ๊ถํ์ด ์๊ธฐ ๋๋ฌธ์ ๋๋ค.
AWS IAM ์ ํตํด EC2 ๊ฐ S3 ์ ์ ๊ทผํ ์ ์๋ค๋ ๊ฒ์ ์ฆ๋ช ํด์ผ ํฉ๋๋ค.
๋ก๊ทธ์ธ ํตํด์ AWS ์๊ฒ ์ฐ๋ฆฌ๊ฐ ๋๊ตฐ์ง ์ฆ๋ช ์ ์ฃผ์ฒด๊ฐ User Account (์ ์ ์ด์นด์ดํธ),
EC2 ๊ฐ S3 ์ ์ ๊ทผํ๊ธฐ ์ํด ํ๋ ์ฆ๋ช ์ฃผ์ฒด๊ฐ Service Account (์๋น์ค ์ด์นด์ดํธ) ์ ๋๋ค.
์ด๋ฅผ ์ฟ ๋ฒ๋คํฐ์ค์ ๋์ ํด๋ณธ๋ค๋ฉด.. ๐
์ฟ ๋ฒ๋คํฐ์ค์ ํ ๋น๋ ์ ์ ๊ฐ User Account (์ ์ ์ด์นด์ดํธ),
Pod ๊ฐ ๋ค๋ฅธ ์ฟ ๋ฒ๋คํฐ์ค ์์ (Pods, Services ..) ์ ์ ๊ทผํ๊ธฐ ์ํด ํ๋ ์ฆ๋ช ์ฃผ์ฒด๊ฐ Service Account (์๋น์ค ์ด์นด์ดํธ) ์ ๋๋ค.
์์ง ๊ฐ์ด ์ ์์ค์๋์? ๐
๊ทธ๋ผ ํ๋ฒ ์ค์ ๋ก ์ ์ฉํด๋ณด์ฃ !
<html />apiVersion: v1 kind: ServiceAccount metadata: name: service-account-example-sa namespace: sample
Service Account ๋ฅผ ์์ฑํด์ค๋๋ค.
Service Account ๋ฅผ ์์ฑํ๊ฒ ๋๋ฉด Secret ์ผ๋ก Token ์ด ํ๋ ์๋์ผ๋ก ์์ฑ๋๋๋ฐ์, ์ด Token ์ ์ด์ฉํด์ ์ฟ ๋ฒ๋คํฐ์ค์๊ฒ ์๊ฒฉ ์ฆ๋ช ์ ํ ์ ์์ต๋๋ค.
โ ์ฟ ๋ฒ๋คํฐ์ค v1.24 ์ด์๋ถํฐ๋ ์๋์ผ๋ก Secret ์ด ์์ฑ๋์ง ์์ต๋๋ค
<html />apiVersion: apps/v1 kind: Deployment metadata: name: service-account-example namespace: sample labels: app: service-account-example spec: replicas: 1 selector: matchLabels: app: service-account-example template: metadata: labels: app: service-account-example spec: serviceAccountName: service-account-example-sa # SA ๋ฅผ ์ง์ ํด์ค๋๋ค containers: - name: nginx image: nginx:latest ports: - containerPort: 80
Deployment ๋ ์์ฑํด์ฃผ์ฃ ๐ค
๋ ์ฌ๊ฒจ ๋ณผ ๊ฒ์ด ์์ต๋๋ค. ๋ฐ๋ก ๋ฐฐํฌ๋ Pod ์ Service Account ๊ฐ ๋ง์ดํธ ๋๋ค๋ ์ ์ด์ฃ โกโก
<html />
Containers:
nginx:
Container ID: docker://67919bf2e0cbcb079bf7a696fef23fd25d3e48691cb2329ac0dd761a251fd8a1
Image: nginx:latest
Image ID: docker-pullable://nginx@sha256:e209ac2f37c70c1e0e9873a5f7231e91dcd83fdf1178d8ed36c2ec09974210ba
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sun, 20 Nov 2022 14:47:02 +0900
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-pclnt (ro)
๊ทธ๋ผ ์ ๊ฒฝ๋ก์ ์๋ ๊ฒ์ด ๋ฌด์์ธ์ง ๋ฐ๋ก ํ์ธ ํด๋ด์ผ๊ฒ ์ฃ ? ๐
<html />root@service-account-example-558865ff7d-vx5gl:/var/run/secrets/kubernetes.io/serviceaccount# ls -l total 0 lrwxrwxrwx 1 root root 13 Nov 20 05:46 ca.crt -> ..data/ca.crt lrwxrwxrwx 1 root root 16 Nov 20 05:46 namespace -> ..data/namespace lrwxrwxrwx 1 root root 12 Nov 20 05:46 token -> ..data/token
์ํ ๐ก ๋ฐ๋ก ์ ๊ธฐ์ ์ฟ ๋ฒ๋คํฐ์ค API ์๋ฒ์ ํต์ ํ ์ ์๋ Token ์ด ์์ต๋๋ค.
๊ทธ๋ผ ์ง์ง์ธ์ง ํ๋ฒ ํ์ธํด๋ณผ๊น์?
<bash />
$ TOKEN=$(cat token)
$ curl -X GET https://$KUBERNETES_SERVICE_HOST/api/v1/namespaces/default/pods --header "Authorization: Bearer $TOKEN" --insecure
<html />{ "kind": "Status", "apiVersion": "v1", "metadata": {}, "status": "Failure", "message": "pods is forbidden: User \"system:serviceaccount:sample:service-account-example-sa\" cannot list resource \"pods\" in API group \"\" in the namespace \"default\": RBAC: clusterrole.rbac.authorization.k8s.io \"service-account-example-role\" not found", "reason": "Forbidden", "details": { "kind": "pods" }, "code": 403 }
401 (Unauthorized) ๊ฐ ์๋ 403 (Forbidden) ์ด ์จ ๊ฒ์ ๋ณด๋ ์ธ์ฆ์ ๋์๋ ๋ด ๋๋ค ๐ฅ
์ด๋๋ก๋ ์์ฌ์ฐ๋ ๊ทธ๋ผ ํ๋ฒ ์์์ ๋ฐฐํฌํ Pod ์ ๋ฆฌ์คํธ๋ฅผ ๊ฐ์ ธ์๋ณด์ฃ !
์์์ ์์ฑํ Service Account ๋ ์๊ฒฉ ์ฆ๋ช ๋ง ๊ฐ๋ฅํ ๋ฟ ํ์ฌ ์ด๋ ํ ๊ถํ๋ ์์ต๋๋ค. ( Pods list, create, update .. ๋ฑ)
<html />apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: service-account-example-role namespace: sample rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "watch", "list"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: service-account-example-role-binding namespace: sample subjects: - kind: ServiceAccount name: service-account-example-sa namespace: sample roleRef: kind: Role name: service-account-example-role apiGroup: rbac.authorization.k8s.io
Role ์ ์์ฑํ์ฌ Service Account ์ Role Binding ํด์ค๋๋ค.
โ Role ์ ํ์ฌ pods ์ ๋ํด ["get", "watch", "list"] ๊ฐ ๊ฐ๋ฅํฉ๋๋ค
<shell />
$ curl -X GET https://$KUBERNETES_SERVICE_HOST/api/v1/namespaces/default/pods --header "Authorization: Bearer $TOKEN" --insecure
์ฌ์ ํ Forbidden ์ด ๋๋ ๊ฑธ ํ์ธํ ์ ์๋๋ฐ, ์ด๋ ๋ฐ๋ก Role ์ ๊ธฐ๋ฅ ๋๋ฌธ์ ๋๋ค. Cluster Role ๊ณผ ๋ฌ๋ฆฌ Role ์ ํน์ Namespace ์ ๋ํด์๋ง ์์ ์ ํ ์ ์์ต๋๋ค. ๋ฐ๋ผ์ default NameSpace ๊ฐ ์๋ sample NameSpace ๋ก ์์ฒญ์ ๋ณด๋ด๋ด ์๋ค !
<shell />
$ curl -X GET https://$KUBERNETES_SERVICE_HOST/api/v1/namespaces/sample/pods --header "Authorization: Bearer $TOKEN" --insecure
<shell />{ "kind": "PodList", "apiVersion": "v1", "metadata": { "resourceVersion": "6608823" }, "items": [ { "metadata": { "name": "service-account-example-558865ff7d-vx5gl", "generateName": "service-account-example-558865ff7d-", "namespace": "sample", "uid": "c85ffc48-affb-4977-8686-657644717c0e", "resourceVersion": "6604097", "creationTimestamp": "2022-11-20T05:46:59Z", ....
200 ์์ฒญ์ด ์์ต๋๋ค ๐ต
์ค์ต์ ๊ณผ์ ์ ํ๋ฒ ์ ๋ฆฌํด๋ณด์ฃ ๐โโ๏ธ
- Service Account ์ Pods ๋ฅผ ์์ฑํ์ต๋๋ค
- Pods ์ Service Account ๊ฐ ์๋์ผ๋ก ๋ง์ดํธ๋๊ณ ์ด๊ณณ์ Token ์ด ์กด์ฌํฉ๋๋ค
- Pods ์ ์ ์ํด์ curl ๋ช ๋ น์ด๋ฅผ ๋ ๋ ธ์ง๋ง Service Account ๋ ์๊ฒฉ ์ฆ๋ช ๋ง ๋ ์ํ์ด๊ณ ๊ถํ์ ์์ต๋๋ค
- Role ๊ณผ Role Binding ์ ์์ฑํด์ Service Account ์ ๊ถํ๋ ๋ถ์ฌํด์ค๋๋ค
- ๋ค์ Pods ์ ์ ํ curl ๋ช ๋ น์ด๋ฅผ ๋ ๋ฆฌ๋ฉด 200 ์๋ต ์ํ๊ฐ ์ต๋๋ค
์ด์ User Account ์ Service Account ์ ์ฐจ์ด์ ์ด ๋ฌด์์ธ์ง ํ์คํ ๊ฐ์ด ์์๊ฑฐ๋ผ ์๊ฐํฉ๋๋ค ๐