12. Accessing to Pod metadata from application

2021. 5. 9. 19:50ใ†๐ŸŽฏ OpenSource/K8S

  • ์ปจํ…Œ์ด๋„ˆ์— ์ •๋ณด ์ „๋‹ฌํ•˜๊ธฐ ์œ„ํ•ด Downard API ์‚ฌ์šฉ
  • ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค REST API ์‚ดํŽด๋ณด๊ธฐ
  • ์ธ์ฆ๊ณผ ์„œ๋ฒ„ ๊ฒ€์ฆ์„ kubectl proxy์— ๋งก๊ธฐ๊ธฐ
  • ์ปจํ…Œ์ด๋„ˆ ๋‚ด์—์„œ API ์„œ๋ฒ„์— ์ ‘๊ทผํ•˜๊ธฐ
  • ์•ฐ๋ฒ„์„œ๋” ์ปจํ…Œ์ด๋„ˆ ํŒจํ„ด์˜ ์ดํ•ด
  • ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์‚ฌ์šฉ

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค API ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•ด ๋ฆฌ์†Œ์Šค ์ •๋ณด๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ๊ณผ, ์ด๋Ÿฌํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณธ๋‹ค.

 

8.1 Downward API๋กœ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ „๋‹ฌ

ํŒŒ๋“œ์˜ IP, ํ˜ธ์ŠคํŠธ ์ด๋ฆ„, ํŒŒ๋“œ ์ž์ฒด์˜ ์ด๋ฆ„๊ณผ ๊ฐ™์ด ์‹คํ–‰ ์‹œ์ ์ด ์•Œ๋ ค์ง€์ง€ ์•Š์€ ๋ฐ์ดํ„ฐ๋Š” ConfigMap ๋˜๋Š” Secret์œผ๋กœ ์ „๋‹ฌํ•˜๊ธฐ์— ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค.

ConfigMap, Secret์˜ ๊ฒฝ์šฐ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ์„ค์ •ํ•˜๊ฑฐ๋‚˜ ํŒŒ๋“œ๊ฐ€ ๋…ธ๋“œ์— ์Šค์ผ€์ค„๋ง ๋˜์–ด ์‹คํ–‰๋˜๊ธฐ ์ด์ „์— ์•Œ๊ณ  ์žˆ์–ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด ๊ฒฝ์šฐ Downward API๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

โœ… Downward API
- ํ™˜๊ฒฝ๋ณ€์ˆ˜ or downward API ๋ณผ๋ฅจ ๋‚ด์˜ ํŒŒ์ผ๋กœ ํŒŒ๋“œ์™€ ํ•ด๋‹น ํ™˜๊ฒฝ์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ปจํ…Œ์ด๋„ˆ์— ์ „๋‹ฌ ํ•  ์ˆ˜ ์žˆ๋‹ค.
- Downward API๋Š” REST API(์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ํ˜ธ์ถœํ•ด์„œ ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์˜ค๋Š” api)์™€๋Š” ๋‹ค๋ฅด๋‹ค.

 

8.1.1 ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ดํ•ด

Downward API๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์€ pod ์ž์ฒด์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ปจํ…Œ์ด๋„ˆ์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ํŒŒ๋“œ์˜ ์ด๋ฆ„
  • ํŒŒ๋“œ IP ์ฃผ์†Œ
  • ํŒŒ๋“œ์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค
  • ํŒŒ๋“œ๊ฐ€ ์‹คํ–‰ ์ค‘์ธ ๋…ธ๋“œ ์ด๋ฆ„
  • ํŒŒ๋“œ๊ฐ€ ์‹คํ–‰ ์ค‘์ธ ์„œ๋น„์Šค ๊ณ„์ • ์ด๋ฆ„ (ํŒŒ๋“œ๊ฐ€ api ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•  ๋•Œ ์ธ์ฆํ•˜๋Š” ๊ณ„์ •)
  • ๊ฐ ์ปจํ…Œ์ด๋„ˆ์˜ CPU์™€ ๋ฉ”๋ชจ๋ฆฌ ์š”์ฒญ 
  • ๊ฐ ์ปจํ…Œ์ด๋„ˆ์˜ CPU์™€ ๋ฉ”๋ชจ๋ฆฌ ์ œํ•œ (์ปจํ…Œ์ด๋„ˆ์— ๋ณด์žฅ๋˜๋Š” CPU์™€ ๋ฉ”๋ชจ๋ฆฌ์˜ ์–‘, ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์–ป์„ ์ˆ˜ ์žˆ๋Š” ์ตœ๋Œ€ ์–‘)
  • ํŒŒ๋“œ์˜ ๋ ˆ์ด๋ธ”
  • ํŒŒ๋“œ์˜ ์–ด๋…ธํ…Œ์ด์…˜

8.1.2 ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ๋…ธ์ถœํ•˜๊ธฐ

์•„๋ž˜ yaml ํŒŒ์ผ์— ๋”ฐ๋ฅด๋ฉด pod ์ด๋ฆ„, ip, ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋Š” ๊ฐ๊ฐ POD_NAME, POD_IP, POD_NAMESPACE๋กœ ๋‚˜ํƒ€๋‚œ๋‹ค.

์ด๋•Œ divisor๋Š” CPU๋‚˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์š”์ฒญ/์ œํ•œํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋‹จ์œ„์ด๋‹ค.

apiVersion: v1
kind: Pod
metadata:
  name: downward
spec:
  containers:
  - name: main
    image: busybox
    command: ["sleep", "9999999"]
    resources:
      requests:
        cpu: 15m
        memory: 100Ki
      limits:
        cpu: 100m
        memory: 20Mi
    env:
    # ํŠน์ • ๊ฐ’์„ ์„ค์ •ํ•˜๋Š” ๋Œ€์‹  ํŒŒ๋“œ ๋งค๋‹ˆํŽ˜์ŠคํŠธ์˜ metadata.name์„ ์ฐธ์กฐ
    - name: POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    - name: POD_NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespac    
    - name: POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP
    - name: NODE_NAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: SERVICE_ACCOUNT
      valueFrom:
        fieldRef:
          fieldPath: spec.serviceAccountName
    - name: CONTAINER_CPU_REQUEST_MILLICORES
      valueFrom: 
        # ์ปจํ…Œ์ด๋„ˆ์˜ CPU/๋ฉ”๋ชจ๋ฆฌ ์š”์ฒญ๊ณผ ์ œํ•œ์€ fieldRef ๋Œ€์‹  resourceFieldRef๋ฅผ ์‚ฌ์šฉํ•ด ์ฐธ์กฐ
        resourceFieldRef:
          resource: requests.cpu
          divisor: 1m      # ๋ฆฌ์†Œ์Šค ํ•„๋“œ์˜ ๊ฒฝ์šฐ ํ•„์š”ํ•œ ๋‹จ์œ„์˜ ๊ฐ’์„ ์–ป์œผ๋ ค๋ฉด ์ œ์ˆ˜(divisor)์„ ์ •์˜
    - name: CONTAINER_MEMORY_LIMIT_KIBIBYTES
      valueFrom:
        resourceFieldRef:
          resource: limits.memory
          divisor: 1Ki

์œ„ yaml ํŒŒ์ผ์—์„œ cpu divisor๋Š” 1m์œผ๋กœ, 1๋ฐ€๋ฆฌ์ฝ”์–ด๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

memory divisor๋Š” 1ki(ํ‚ค๋น„๋ฐ”์ดํŠธ)๋กœ ์„ค์ •๋˜์—ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ปจํ…Œ์ด๋„ˆ์— ์ ์šฉ๋œ ๋ชจ๋“  ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ปจํ…Œ์ด๋„ˆ ๋‚ด๋ถ€์˜ ๋ชจ๋“  ํ”„๋กœ์„ธ์Šค๋Š” ํ•ด๋‹น ๋ณ€์ˆ˜๋ฅผ ์ฝ๊ณ , ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.

root@master001:~/k8s_in_action/kubernetes-in-action/Chapter08# kubectl exec downward env
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=downward
POD_IP=172.30.254.34
NODE_NAME=worker002
SERVICE_ACCOUNT=default
CONTAINER_CPU_REQUEST_MILLICORES=15
CONTAINER_MEMORY_LIMIT_KIBIBYTES=20480
POD_NAME=downward
POD_NAMESPACE=default
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBIA_NODEPORT_SERVICE_HOST=10.99.129.201
KUBIA_NODEPORT_SERVICE_PORT=80
KUBIA_NODEPORT_PORT=tcp://10.99.129.201:80
KUBIA_NODEPORT_PORT_80_TCP=tcp://10.99.129.201:80
KUBIA_NODEPORT_PORT_80_TCP_PORT=80
KUBIA_NODEPORT_PORT_80_TCP_ADDR=10.99.129.201
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_PORT=443
KUBIA_NODEPORT_PORT_80_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
HOME=/root

 

8.1.3 downward API ๋ณผ๋ฅจ์— ํŒŒ์ผ๋กœ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ „๋‹ฌ

downward API ๋ณผ๋ฅจ์„ ์ด์šฉํ•ด์„œ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๋Œ€์‹  ํŒŒ์ผ๋กœ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ๋…ธ์ถœํ•  ์ˆ˜ ์žˆ๋‹ค.

ํŒŒ๋“œ์˜ ๋ผ๋ฒจ์ด๋‚˜ ์–ด๋…ธํ…Œ์ด์…˜์€ ํŒŒ์ผ๋กœ๋งŒ ์ „๋‹ฌ ๊ฐ€๋Šฅํ•˜๋‹ค.

downward๋ผ๋Š” ๋ณผ๋ฅจ์„ ์ •์˜ํ•˜๊ณ  ์ปจํ…Œ์ด๋„ˆ์˜ /etc/downward ์•„๋ž˜์— ๋งˆ์šดํŠธํ•œ๋‹ค.

apiVersion: v1
kind: Pod
metadata:
  name: downward
  labels:        # ๋ ˆ์ด๋ธ”๊ณผ ์–ด๋…ธํ…Œ์ด์…˜์€ downwardAPI ๋ณผ๋ฅจ์œผ๋กœ ๋…ธ์ถœ
    foo: bar
  annotations:
    key1: value1
    key2: |
      multi
      line
      value
spec:
  containers:
  - name: main
    image: busybox
    command: ["sleep", "9999999"]
    resources:
      requests:
        cpu: 15m
        memory: 100Ki
      limits:
        cpu: 100m
        memory: 4Mi
    volumeMounts:
    - name: downward
      mountPath: /etc/downward  # downward ๋ณผ๋ฅจ /etc/downward์— ๋งˆ์šดํŠธ
  volumes:
  - name: downward              # downwardAPI ๋ณผ๋ฅจ ์ •์˜
    downwardAPI:
      items:
      - path: "podName"         # metadata.name์— ์ •์˜ํ•œ ์ด๋ฆ„์€ podName ํŒŒ์ผ์— ๊ธฐ๋ก๋จ
        fieldRef:
          fieldPath: metadata.name
      - path: "podNamespace"
        fieldRef:
          fieldPath: metadata.namespac
      - path: "labels"               # ํŒŒ๋“œ์˜ ๋ ˆ์ด๋ธ”์€ /etc/downward/labels ํŒŒ์ผ์— ๊ธฐ๋ก๋จ
        fieldRef:
          fieldPath: metadata.labels
      - path: "annotations"          # ํŒŒ๋“œ์˜ ์–ด๋…ธํ…Œ์ด์…˜์€ /etc/downward/annotations ํŒŒ์ผ์— ๊ธฐ๋ก๋จ
        fieldRef:
          fieldPath: metadata.annotations
      - path: "containerCpuRequestMilliCores"
        resourceFieldRef:
          containerName: main
          resource: requests.cpu
          divisor: 1m
      - path: "containerMemoryLimitBytes"
        resourceFieldRef:
          containerName: main
          resource: limits.memory
          divisor: 1

๋งˆ์šดํŠธ๋œ ์ •๋ณด๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค.

root@master001:~/k8s_in_action/kubernetes-in-action/Chapter08# kubectl exec downward-volume -- ls -lL /etc/downward
total 24
-rw-r--r--    1 root     root           227 May  9 12:16 annotations
-rw-r--r--    1 root     root             2 May  9 12:16 containerCpuRequestMilliCores
-rw-r--r--    1 root     root             8 May  9 12:16 containerMemoryLimitBytes
-rw-r--r--    1 root     root             9 May  9 12:16 labels
-rw-r--r--    1 root     root            15 May  9 12:16 podName
-rw-r--r--    1 root     root             7 May  9 12:16 podNamespace

ํ™˜๊ฒฝ๋ณ€์ˆ˜๋กœ๋Š” ์ „๋‹ฌํ•  ์ˆ˜ ์—†๋Š” label๊ณผ annotaion๋„ ์ „๋‹ฌ๋œ ๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๋ ˆ์ด๋ธ”๊ณผ ์–ด๋…ธํ…Œ์ด์…˜ ์—…๋ฐ์ดํŠธ

  • downward API ๋ณผ๋ฅจ์„ ์‚ฌ์šฉํ•˜๋ฉด ํŒŒ๋“œ๊ฐ€ ์‹คํ–‰ ์ค‘์ธ ์ƒํƒœ์—์„œ ๋ ˆ์ด๋ธ”๊ณผ ์–ด๋…ธํ…Œ์ด์…˜ ๊ฐ’์ด ์—…๋ฐ์ดํŠธ ๋˜๋ฉด ํŒŒ๋“œ๊ฐ€ ์ตœ์‹  ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•˜๋„๋ก ํ•œ๋‹ค.
  • ํ™˜๊ฒฝ๋ณ€์ˆ˜ ๋ฐฉ๋ฒ•์œผ๋กœ๋Š” ์—…๋ฐ์ดํŠธ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๋ณผ๋ฅจ ์ŠคํŽ™์—์„œ ์ปจํ…Œ์ด๋„ˆ ์ˆ˜์ค€์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ฐธ์กฐ

๋‹จ ์ปจํ…Œ์ด๋„ˆ์˜ ์ˆ˜์ค€์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒฝ์šฐ๋Š” ํ•ด๋‹น ์ปจํ…Œ์ด๋„ˆ์˜ ์ด๋ฆ„์„ ์ง€์ •ํ•ด์•ผ ํ•œ๋‹ค.

spec:
  volumes:
  - name: downward
    downwardAPI:
      items:
      - path: "containerCpuRequestMilliCores"
        resourceFieldRef:
          containerName: main   # ์ปจํ…Œ์ด๋„ˆ ์ด๋ฆ„ ์ง€์ •
          resource: requests.cpu
          divisor: 1m
๐Ÿ˜ฎ DownwardAPI ๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋Š” ํ•œ์ •์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋” ๋งŽ์€ ์ •๋ณด๋ฅผ ์œ„ํ•ด์„œ๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค API๋ฅผ ํ†ตํ•ด ๊ฐ€์ ธ์™€์•ผ ํ•œ๋‹ค.

 

8.2 ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค API ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๊ธฐ

DownwardAPI๋Š” ํŒŒ๋“œ ์ž์ฒด์˜ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ์™€ ์ผ๋ถ€ ๋ฐ์ดํ„ฐ๋งŒ์„ ๋…ธ์ถœํ•œ๋‹ค.

ํด๋Ÿฌ์Šคํ„ฐ์— ์ •์˜๋œ ๋‹ค๋ฅธ ํŒŒ๋“œ๋‚˜ ๋ฆฌ์†Œ์Šค์— ๊ด€ํ•œ ์ •๋ณด๋ฅผ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ œ๊ณตํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์ฟ ๋ฒ„๋„คํ‹ฐ์ŠคAPI๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

 

8.2.1 ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค REST API ์‚ดํŽด๋ณด๊ธฐ

๋กœ์ปฌ์—์„œ ์„œ๋ฒ„์˜ REST ์—”๋“œํฌ์ธํŠธ๋ฅผ ํ†ตํ•ด API ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณธ๋‹ค.

root@master001:~/k8s_in_action/kubernetes-in-action/Chapter08# kubectl cluster-info
Kubernetes control plane is running at https://172.16.110.10:6443
KubeDNS is running at https://172.16.110.10:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

์ธ์ฆ ์ฒ˜๋ฆฌ ๋•Œ๋ฌธ์— ํ•ด๋‹น url๋กœ ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๋Š”๊ฑธ ํ™•์ธํ•  ์ˆ˜ ์—†๋‹ค.

๊ทธ๋ž˜์„œ proxy๋กœ localhost์—์„œ HTTP ์—ฐ๊ฒฐ์„ ์ˆ˜์‹ ํ•˜๋„๋กํ•œ๋‹ค.

root@master001:~/k8s_in_action/kubernetes-in-action/Chapter08# kubectl proxy &
[1] 3103944
root@master001:~/k8s_in_action/kubernetes-in-action/Chapter08# Starting to serve on 127.0.0.1:8001

์ด์ œ curl๋กœ ๋กœ์ปฌ ํฌํŠธ 8001๋ฒˆ์œผ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.

root@master001:~/k8s_in_action/kubernetes-in-action/Chapter08# curl localhost:8001
{
  "paths": [
    "/.well-known/openid-configuration",
    "/api",
    "/api/v1",
    "/apis",
    "/apis/",
    "/apis/admissionregistration.k8s.io",
    "/apis/admissionregistration.k8s.io/v1",
    "/apis/admissionregistration.k8s.io/v1beta1",
    "/apis/apiextensions.k8s.io",
    "/apis/apiextensions.k8s.io/v1",
    "/apis/apiextensions.k8s.io/v1beta1",
    "/apis/apiregistration.k8s.io",
    "/apis/apiregistration.k8s.io/v1",
    "/apis/apiregistration.k8s.io/v1beta1",
    "/apis/apps",
    "/apis/apps/v1",

proxy๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  -> proxy๊ฐ€ API ์„œ๋ฒ„๋กœ ์š”์ฒญ -> proxy๋Š” API ์„œ๋ฒ„๊ฐ€ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ๋ฐ˜ํ™˜

์œ„์˜ ๋ฐ˜ํ™˜ ๊ฒฐ๊ณผ์—์„œ ๋Œ€๋ถ€๋ถ„์˜ ๋ฆฌ์†Œ์Šค ํƒ€์ž…์„ ํ™•์ธ ๊ฐ€๋Šฅํ•˜๋‹ค.

์ด๋Ÿฌํ•œ ๊ฒฝ๋กœ๋Š” ํŒŒ๋“œ, ์„œ๋น„์Šค ๋“ฑ๊ณผ ๊ฐ™์€ ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ๋ฆฌ์†Œ์Šค ์ •์˜์— ์ง€์ •ํ•œ API ๊ทธ๋ฃน๊ณผ ๋ฒ„์ „์— ํ•ด๋‹นํ•œ๋‹ค.

 

๋ฐฐ์น˜ API ๊ทธ๋ฃน์˜ REST ์—”๋“œํฌ์ธํŠธ ์‚ดํŽด๋ณด๊ธฐ

Job ๋ฆฌ์†Œ์Šค API๋ฅผ ์‚ดํŽด๋ณด๋„๋ก ํ•œ๋‹ค.

/apis/batch ๊ฒฝ๋กœ ๋’ค์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ •๋ณด๊ฐ€ ์กด์žฌ ํ•œ๋‹ค.

root@master001:~/Chapter08# curl http://localhost:8001/apis/batch
{
  "kind": "APIGroup",
  "apiVersion": "v1",
  "name": "batch",
  "versions": [
    {
      "groupVersion": "batch/v1",
      "version": "v1"
    },
    {
      "groupVersion": "batch/v1beta1",
      "version": "v1beta1"
    }
  ],
  "preferredVersion": {
    "groupVersion": "batch/v1",
    "version": "v1"
  }

๋ฐ˜ํ™˜๊ฐ’์„ ๋ณด๋ฉด ๋ฐฐ์น˜ API ๊ทธ๋ฃน์—๋Š” v1๊ณผ v1beta1 ๋ฒ„์ „์ด ์กด์žฌํ•œ๋‹ค. 

๊ทธ๋ฆฌ๊ณ  ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์—์„œ ๊ถŒ์žฅํ•˜๋Š” ๋ฒ„์ „์€ v1์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

๊ทธ๋Ÿฌ๋ฉด /apis/batch/v1 ๊ฒฝ๋กœ์— ํ•ด๋‹นํ•˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•ด ๋ณธ๋‹ค.

root@master001:~/Chapter08# curl http://localhost:8001/apis/batch/v1
{
  "kind": "APIResourceList",    # batch/v1 API ๊ทธ๋ฃน ๋‚ด์˜ API ๋ฆฌ์†Œ์Šค ๋ชฉ๋ก
  "apiVersion": "v1",
  "groupVersion": "batch/v1",
  "resources": [                # ์ด ๊ทธ๋ฃน์˜ ๋ชจ๋“  ๋ฆฌ์†Œ์Šค ์œ ํ˜•์„ ๋‹ด๋Š” ๋ฐฐ์—ด
    {
      "name": "jobs",            
      "singularName": "",
      "namespaced": true,
      "kind": "Job",      # job ๋ฆฌ์†Œ์Šค
      "verbs": [          # job ๋ฆฌ์†Œ์Šค์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ช…๋ น์–ด(๋™์‚ฌ)
        "create",
        "delete",
        "deletecollection",
        "get",
        "list",
        "patch",
        "update",
        "watch"
      ],
      "categories": [
        "all"
      ],
      "storageVersionHash": "mudhfqk/qZY="
    },
    {
      "name": "jobs/status",    # ๋ฆฌ์†Œ์Šค์˜ ์ƒํƒœ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•œ ๋ณ„๋„์˜ REST ์—”๋“œํฌ์ธํŠธ
      "singularName": "",
      "namespaced": true,
      "kind": "Job",
      "verbs": [                # ์ƒํƒœ ์ •๋ณด๋ฅผ ๊ฒ€์ƒ‰, ํŒจ์น˜, ์—…๋ฐ์ดํŠธ ๊ฐ€๋Šฅ
        "get",
        "patch",
        "update"
      ]
    }
  ]

 

8.2.2 ํŒŒ๋“œ ๋‚ด API ์„œ๋ฒ„์™€์˜ ํ†ต์‹ 

์ด๋ฒˆ์—๋Š” kubectl์ด ์—†๋Š” ํŒŒ๋“œ์™€ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค API ์„œ๋ฒ„๊ฐ€ ํ†ต์‹ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณธ๋‹ค.

API ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ ์„ธ ๊ฐ€์ง€๊ฐ€ ์ˆ˜ํ–‰๋˜์–ด์•ผ ํ•œ๋‹ค.

  1. API ์„œ๋ฒ„์˜ ์œ„์น˜๋ฅผ ์ฐพ๋Š”๋‹ค.
  2. ์ •ํ™•ํ•œ API ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๊ณ  ์žˆ๋Š”์ง€ ํ™•์ธ
  3. API ์„œ๋ฒ„๋กœ ์ธ์ฆ

API ์„œ๋ฒ„์™€์˜ ํ†ต์‹ ํ•  ํŒŒ๋“œ ์‹คํ–‰

apiVersion: v1
kind: Pod
metadata:
  name: curl
spec:
  containers:
  - name: main
    image: tutum/curl
    command: ["sleep", "9999999"]

๊ทธ๋ฆฌ๊ณ  ํ•ด๋‹น ์ปจํ…Œ์ด๋„ˆ์˜ bash ์‰˜๋กœ ์ ‘์†ํ•œ๋‹ค.

root@master001:~/Chapter08# kubectl exec -it curl bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@curl:/# 

ํ•ด๋‹น pod์—์„œ API ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•ด ๋ณธ๋‹ค.

์ด๋ฅผ ์œ„ํ•ด์„œ๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค API ์„œ๋ฒ„์˜ IP์™€ ํฌํŠธ๋ฅผ ์ฐพ์•„์•ผ ํ•œ๋‹ค.

root@curl:/# env | grep KUBERNETES_SERVICE
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_HOST=10.96.0.1
KUBERNETES_SERVICE_PORT_HTTPS=443

์œ„์˜ ๋ณ€์ˆ˜๋“ค์€ kubernetes ๋ผ๋Š” ์„œ๋น„์Šค์—์„œ ์ œ๊ณต๋˜๋Š” ๊ฒƒ์ด๋‹ค. 

๋”ฐ๋ผ์„œ ์ปจํ…Œ์ด๋„ˆ์—์„œ kubernetes๋กœ ์š”์ฒญ์„ ๋ณด๋‚ธ๋‹ค.

root@curl:/# curl https://kubernetes -k
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
  "reason": "Forbidden",
  "details": {

  },
  "code": 403

 

์„œ๋ฒ„์˜ ์•„์ด๋ดํ‹ฐํ‹ฐ ๊ฒ€์ฆ

  • Authorization HTTP ํ—ค๋” ๋‚ด๋ถ€์— ํ† ํฐ์„ ์ „๋‹ฌํ•˜์—ฌ ํ† ํฐ์„ ์ธ์ฆ๋œ ๊ฒƒ์œผ๋กœ ์ธ์‹ํ•˜์—ฌ ์ ์ ˆํ•œ ์‘๋‹ต ๋ฐ›๊ธฐ ๊ฐ€๋Šฅ
  • ์ด๋Ÿฌํ•œ ๋ฐฉ์‹์œผ๋กœ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ๋‚ด์— ์žˆ๋Š” ๋ชจ๋“  ํŒŒ๋“œ ์กฐํšŒ ๊ฐ€๋Šฅ (curl ํŒŒ๋“œ๊ฐ€ ์–ด๋–ค ๋„ค์ž„์ŠคํŽ˜์ด์Šค์—์„œ ์‹คํ–‰์ค‘์ธ์ง€ ์•Œ์•„์•ผ ํ•จ)
# ์„œ๋ฒ„์˜ ์ธ์ฆ์„œ๊ฐ€ CA๋กœ ์„œ๋ช…๋œ ๊ฒƒ์ธ์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด CA ์ธ์ฆ์„œ๋ฅผ ์ง€์ •ํ•ด์„œ API ์„œ๋ฒ„์— ์ ‘์†ํ•œ๋‹ค.
root@curl:/# export CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

root@curl:/# curl https://kubernetes
{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
  "reason": "Forbidden",
  "details": {

  },
  "code": 403

 

API ์„œ๋ฒ„๋กœ ์ธ์ฆ

์„œ๋ฒ„์—์„œ ์ธ์ฆ์„ ํ†ต๊ณผํ•ด์•ผ ํด๋Ÿฌ์Šคํ„ฐ์— ๋ฐฐํฌ๋œ API ์˜ค๋ธŒ์ ํŠธ๋ฅผ read, update, delete๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋•Œ ์ธ์ฆํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ธ์ฆ ํ† ํฐ์ด ํ•„์š”ํ•˜๋‹ค.

์ด ํ† ๊ทผ์€ default-token ์‹œํฌ๋ฆฟ์œผ๋กœ ์ œ๊ณต๋œ๋‹ค. ํ•ด๋‹น ํ…Œ์ดํ„ฐ๋ฅผ TOKEN ํ™˜๊ฒฝ๋ณ€์ˆ˜์— ๋กœ๋“œํ•ด์„œ API ์„œ๋ฒ„๋กœ ์š”์ฒญ ๋ณด๋‚ผ๋•Œ ์‚ฌ์šฉํ•˜๋„๋ก ํ•œ๋‹ค.

root@curl:/# TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)

์ด์ œ ํ•ด๋‹น token์„ ์‚ฌ์šฉํ•ด์„œ API ์„œ๋ฒ„๋กœ๋ถ€ํ„ฐ ์‘๋‹ต์„ ๋ฐ›๋Š”์ง€ ๋ณธ๋‹ค.

root@curl:/#  curl -H "Authorization: Bearer $TOKEN" https://kubernetes
{
  "paths": [
    "/.well-known/openid-configuration",
    "/api",
    "/api/v1",
    "/apis",
    "/apis/",
    "/apis/admissionregistration.k8s.io",
    "/apis/admissionregistration.k8s.io/v1",
    "/apis/admissionregistration.k8s.io/v1beta1",
    "/apis/apiextensions.k8s.io",

 

 

 

ํŒŒ๋“œ๊ฐ€ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์™€ ํ†ต์‹ ํ•˜๋Š” ๋ฐฉ๋ฒ• ์ •๋ฆฌ

Pod ๋‚ด์—์„œ ์‹คํ–‰ ์ค‘์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค API์— ์ ์ ˆํžˆ ์•ก์„ธ์Šค ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ •๋ฆฌํ•œ๋‹ค.

  1. ca.cert : ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ API ์„œ๋ฒ„์˜ ์ธ์ฆ์„œ๊ฐ€ ์ธ์ฆ ๊ธฐ๊ด€์œผ๋กœ๋ถ€ํ„ฐ ์„œ๋ช…๋œ๊ฑด์ง€ ๊ฒ€์ฆํ•ด์•ผ ํ•˜๋Š”๋ฐ, ca.crt ํŒŒ์ผ์ด ์ธ์ฆ ๊ธฐ๊ด€์˜ ์ธ์ฆ์„œ์ด๋‹ค.
  2. token : ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ token ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ Authorization HTTP ํ—ค๋”์— Bearer ํ† ํฐ์œผ๋กœ ๋„ฃ์–ด ์ „์†กํ•ด์„œ ์ž์‹ ์„ ์ธ์ฆํ•œ๋‹ค.
  3. namespace : ํŒŒ๋“œ์˜ ๋„ค์ž„์ŠคํŽ˜์ด์Šค ์•ˆ์— ์žˆ๋Š” API ์˜ค๋ธŒ์ ํŠธ์˜ CRUD(create, read, update, delete) ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ๋•Œ ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ API ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•˜๋Š”๋ฐ ์‚ฌ์šฉ

 

8.2.3 ์•ฐ๋ฐฐ์„œ๋” ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ด์šฉํ•œ API ์„œ๋ฒ„ ํ†ต์‹  ๊ฐ„์†Œํ™”

์ง€๊ธˆ๊นŒ์ง€ ํ•œ ๊ฒƒ์ฒ˜๋Ÿผ HTTPS, ์ธ์ฆ์„œ, ์ธ์ฆ ํ† ํฐ์„ ํ•˜๋‚˜ํ•˜๋‚˜ ๋‹ค๋ฃจ๋Š”๊ฑด ๊นŒ๋‹ค๋กญ๋‹ค.

๊ทธ๋ž˜์„œ pod ๋‚ด์—์„œ๋„ proxy๋ฅผ ์‚ฌ์šฉํ•ด์„œ API๋กœ ์ง์ ‘ ์š”์ฒญ์„ ๋ณด๋‚ด๋Š” ๋Œ€์‹  ํ”„๋ก์‹œ๋กœ ์š”์ฒญ์„ ๋ณด๋‚ด ์ธ์ฆ, ์•”ํ˜ธํ™” ๋“ฑ์˜ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค.

์ด๋ฅผ ์•ฐ๋ฐฐ์„œ๋” ํŒจํ„ด์ด๋ผ๊ณ  ํ•œ๋‹ค.

 

์•ฐ๋ฐฐ์„œ๋” ์ปจํ…Œ์ด๋„ˆ ํŒจํ„ด

API์™€ ์ง์ ‘ ํ†ต์‹ ํ•˜๋Š” ๋Œ€์‹  ๋งค์ธ ์ปจํ…Œ์ด๋„ˆ์˜ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ HTTP๋กœ ์•ฐ๋ฒ„์„œ๋”์— ์—ฐ๊ฒฐํ•˜๊ณ , ์•ฐ๋ฒ„์„œ๋” ํ”„๋ก์‹œ๊ฐ€ API ์„œ๋ฒ„์— ๋Œ€ํ•œ https ์—ฐ๊ฒฐ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค.

 

์•ฐ๋ฒ„์„œ๋” ์ปจํ…Œ์ด๋„ˆ ์‚ฌ์šฉํ•œ curl ํŒŒ๋“œ ์‹คํ–‰

kubectl-proxy ์ด๋ฏธ์ง€๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•˜๋Š” ambassador ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํฌํ•จํ•œ pod๋ฅผ ์‹คํ–‰์‹œํ‚จ๋‹ค.

apiVersion: v1
kind: Pod
metadata:
  name: curl-with-ambassador
spec:
  containers:
  - name: main
    image: tutum/curl
    command: ["sleep", "9999999"]
  - name: ambassador
    image: luksa/kubectl-proxy:1.6.2

curl-with-ambassador pod๋ฅผ ์ƒ์„ฑํ•œ ํ›„ main ํŒŒ๋“œ์— ๋“ค์–ด๊ฐ€ API ์„œ๋ฒ„์— ์ ‘์†ํ•œ๋‹ค.

์ด๋•Œ curl์„ ๋‚ ๋ฆฌ๋ฉด ambassador ์ปจํ…Œ์ด๋„ˆ์—์„œ proxy ๋˜๋„๋ก ํ•œ๋‹ค.

kubectl proxy๋Š” ํฌํŠธ 8001์— ๋ฐ”์ธ๋”ฉ ๋˜์–ด ์žˆ๋‹ค.

root@curl-with-ambassador:/# curl localhost:8001
{
  "paths": [
    "/.well-known/openid-configuration",
    "/api",
    "/api/v1",
    "/apis",
    "/apis/",โ€‹

 

(์—ฌ๊ธฐ์„œ curl์„ ๋‚ ๋ฆฌ๋ฉด ๋ฐ”๋กœ ์œ„์™€ ๊ฐ™์€ api path๊ฐ€ ๋‚˜์™”์–ด์•ผ ํ–ˆ์œผ๋‚˜, serviceaccount๊ฐ€ ์ƒ์„ฑ๋˜์ง€ ์•Š์•„ 403 forbidden์ด ๋ฐœ์ƒํ•˜๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ๋‹ค)

Kubernetes log, User “system:serviceaccount:default:default” cannot get services in the namespace

์œ„ ๋ฌธ์„œ์— ๋”ฐ๋ผ default ServiceAccount์™€ Cluster-admin์ด๋ผ๋Š” role์„ ๋ฐ”์ธ๋”ฉํ•˜๊ณ  ํ•ด๊ฒฐํ–ˆ๋‹ค.

---
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: fabric8-rbac
subjects:
  - kind: ServiceAccount
    # Reference to upper's `metadata.name`
    name: default
    # Reference to upper's `metadata.namespace`
    namespace: default
roleRef:
  kind: ClusterRole
  name: cluster-admin
  apiGroup: rbac.authorization.k8s.io

 

๊ฒฐ๊ณผ์ ์œผ๋กœ, curl๋กœ ์ถœ๋ ฅ๋œ ๊ฒฐ๊ณผ๋Š” ์•ž์„œ ํ…Œ์ŠคํŠธํ•œ ๊ฒƒ๊ณผ ๊ฐ™์ง€๋งŒ ์ด๋ฒˆ์—๋Š” token ์ƒ์„ฑ๊ณผ ๊ฐ™์€ ์ธ์ฆ ๊ณผ์ •์„ ๊ฑฐ์น  ํ•„์š”๊ฐ€ ์—†์—ˆ๋‹ค.

  • ๊ณผ์ •
    • main ์ปจํ…Œ์ด๋„ˆ์—์„œ ์ผ๋ฐ˜ HTTP ์š”์ฒญ์„ ambassador ์ปจํ…Œ์ด๋„ˆ๋กœ ์ „๋‹ฌ
    • ambassador์˜ proxy๊ฐ€ HTTPS ์š”์ฒญ + ์ธ์ฆ ํ† ํฐ + ์„œ๋ฒ„ ์ธ์ฆ์„œ๋ฅผ API ์„œ๋ฒ„๋กœ ์ „๋‹ฌ
    • ์ธ์ฆ ์ด๋ค„์ง„ ํ›„ main ์ปจํ…Œ์ด๋„ˆ๋กœ ์š”์ฒญ๊ฐ’ ๋ฐ˜ํ™˜

์ด๋Ÿฌํ•œ ambassador container์˜ ๋‹จ์ ์€ ์ถ”๊ฐ€ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋™์ž‘ํ•˜์—ฌ ๋ฆฌ์†Œ์Šค๊ฐ€ ์†Œ๋น„๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

 

 

8.2.4 ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ด์šฉํ•˜์—ฌ API ์„œ๋ฒ„์™€ ํ†ต์‹ 

๋‹จ์ˆœํ•œ API ์š”์ฒญ์˜ ๊ฒฝ์šฐ kubectl-proxy ambassador๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋˜์ง€๋งŒ, ์ข€ ๋” ๋‚œ์ด๋„ ์žˆ๋Š” ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค API ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

 

ํด๋ผ์ด์–ธํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ชฉ๋ก

-> kubernetes.io/ko/docs/reference/using-api/client-libraries/

 

 

Swagger์™€ OpenAPI๋ฅผ ์‚ฌ์šฉํ•ด ์ž์‹ ์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ตฌ์ถ•

์›ํ•˜๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์— ๋Œ€ํ•œ ํด๋ผ์ด์–ธํŠธ๊ฐ€ ์—†๋Š” ๊ฒฝ์šฐ ์Šค์›จ๊ฑฐ Swagger API ํ”„๋ ˆ์ž„์›Œํฌ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค. Swagger API๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค API ์„œ๋ฒ„์— ํƒ‘์žฌ๋˜์–ด ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” ๋น„ํ™œ์„ฑํ™” ๋˜์–ด ์žˆ๋‹ค. 

 

 

 

 

'๐ŸŽฏ OpenSource > K8S' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[K8S] Service (NodePort / ClusterIP / LoadBalancer)  (0) 2022.11.14
11. Secret  (0) 2021.05.09
10. ConfigMap  (0) 2021.05.08
09. Job์œผ๋กœ ์™„๋ฃŒ ๊ฐ€๋Šฅํ•œ ๋‹จ์ผ task ๊ตฌํ˜„ํ•˜๊ธฐ  (0) 2021.04.05
08. DaemonSet  (0) 2021.04.05