Contents

Certificated Kubernetes Administrator - Secret

configure certification file

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# kubectl describe pods -n kube-system kube-apiserver-controlplane
Command:
      kube-apiserver
      --advertise-address=192.8.216.9
      --allow-privileged=true
      --authorization-mode=Node,RBAC
      --client-ca-file=/etc/kubernetes/pki/ca.crt
      --enable-admission-plugins=NodeRestriction
      --enable-bootstrap-token-auth=true
      --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
      --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
      --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
      --etcd-servers=https://127.0.0.1:2379
      --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
      --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
      --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
      --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
      --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
      --requestheader-allowed-names=front-proxy-client
      --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
      --requestheader-extra-headers-prefix=X-Remote-Extra-
      --requestheader-group-headers=X-Remote-Group
      --requestheader-username-headers=X-Remote-User
      --secure-port=6443
      --service-account-issuer=https://kubernetes.default.svc.cluster.local
      --service-account-key-file=/etc/kubernetes/pki/sa.pub
      --service-account-signing-key-file=/etc/kubernetes/pki/sa.key
      --service-cluster-ip-range=10.96.0.0/12
      --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
      --tls-private-key-file=/etc/kubernetes/pki/apiserver.key

#kubectl describe pods -n kube-system etcd-controlplane
Command:
      etcd
      --advertise-client-urls=https://192.8.216.9:2379
      --cert-file=/etc/kubernetes/pki/etcd/server.crt
      --client-cert-auth=true
      --data-dir=/var/lib/etcd
      --experimental-initial-corrupt-check=true
      --experimental-watch-progress-notify-interval=5s
      --initial-advertise-peer-urls=https://192.8.216.9:2380
      --initial-cluster=controlplane=https://192.8.216.9:2380
      --key-file=/etc/kubernetes/pki/etcd/server.key
      --listen-client-urls=https://127.0.0.1:2379,https://192.8.216.9:2379
      --listen-metrics-urls=http://127.0.0.1:2381
      --listen-peer-urls=https://192.8.216.9:2380
      --name=controlplane
      --peer-cert-file=/etc/kubernetes/pki/etcd/peer.crt
      --peer-client-cert-auth=true
      --peer-key-file=/etc/kubernetes/pki/etcd/peer.key
      --peer-trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt
      --snapshot-count=10000
      --trusted-ca-file=/etc/kubernetes/pki/etcd/ca.crt

kube-apiserver์˜ --etcd-certfile ์˜ต์…˜๊ณผ etcd server์˜ --cert-file ์˜ต์…˜์˜ ๊ฐ’์„ ๋ณด๋ฉด ์„œ๋กœ ๋‹ค๋ฅธ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ „์ž๋Š”, kube-apiserver๊ฐ€ etcd server์™€ ํ†ต์‹ ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ํด๋ผ์ด์–ธํŠธ ์ธ์ฆ์„œ๋ฅผ ์˜๋ฏธํ•˜๊ณ  ํ›„์ž๋Š” etcd ์„œ๋ฒ„ ์ž์ฒด์˜ ์ธ์ฆ์„œ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

What is the Common Name (CN) configured on the Kube API Server Certificate?

kube api server ์˜ ssl/tls ์ธ์ฆ์„œ์— ์„ค์ •๋œ ‘๊ณตํ†ต ์ด๋ฆ„’์ด ๋ฌด์—‡์ธ์ง€๋ฅผ ๋ฌผ์–ด๋ณด๋Š” ๊ฒƒ์ด๋‹ค. ‘Common Name’์€ ์ธ์ฆ์„œ๊ฐ€ ๋ฐœ๊ธ‰๋œ ์„œ๋ฒ„์˜ ๋„๋ฉ”์ธ ์ด๋ฆ„์„ ์ง€์ •ํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•œ๋‹ค. ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ํ™˜๊ฒฝ์—์„œ CN์€ kubeapi server๊ฐ€ ์‚ฌ์šฉํ•˜๋Š” ์ฃผ์†Œ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 4169429065381004709 (0x39dcc9a4f63945a5)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = kubernetes
        Validity
            Not Before: May 26 06:08:28 2024 GMT
            Not After : May 26 06:13:28 2025 GMT
        Subject: CN = kube-apiserver
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    00:a9:e4:03:72:0f:63:ee:57:c2:25:b7:ff:57:6a:
                    9f:78:37:07:52:11:48:98:d8:b4:a3:ca:4a:05:36:
                    52:af:0d:50:69:60:60:1d:b9:e7:1a:98:6f:e4:2b:
                    73:66:aa:9d:77:ce:f3:18:e7:b1:09:83:ec:bb:ce:
                    5f:fd:88:a1:48:7f:50:94:26:a1:4b:ef:12:bf:92:
                    25:ce:a5:8d:6c:bb:7a:3e:6f:f5:78:2f:47:8a:e3:
                    18:b9:14:11:69:f2:a4:0d:4c:f9:c7:1b:e2:b5:ab:
                    09:7b:7b:3a:cf:37:bf:e6:8b:8e:2f:b1:89:0c:2a:
                    bc:2a:a1:14:b2:04:61:6c:6e:01:42:52:bb:c9:bf:
                    f0:a2:cf:53:fd:0a:be:64:34:1a:f0:93:84:57:4f:
                    f3:9a:b9:02:41:f9:21:3e:4a:a8:a4:4b:ca:41:7b:
                    8f:ed:98:b1:ef:91:58:20:ba:dd:74:45:a4:13:81:
                    ba:6f:7b:07:8d:d6:6d:bf:03:15:01:40:4a:e1:52:
                    1d:ba:a4:5e:80:1a:42:9f:0e:4a:b4:ef:0f:d0:5c:
                    51:c0:90:e6:44:e5:4e:03:7f:1c:85:6f:b6:26:23:
                    52:f7:e2:f8:b8:77:6f:81:36:93:ea:42:55:90:7a:
                    c0:7c:e4:f4:66:5b:a0:45:c2:e0:f3:99:53:1e:aa:
                    2b:95
                Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Authority Key Identifier:
                F3:54:72:08:EE:F6:FC:9A:27:C9:61:F6:37:6D:32:B3:8B:86:A7:9B
            X509v3 Subject Alternative Name:
                DNS:controlplane, DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster.local, IP Address:10.96.0.1, IP Address:192.8.216.9
    Signature Algorithm: sha256WithRSAEncryption
    Signature Value:
        62:9d:43:f9:a8:db:73:5f:36:fe:8e:14:b4:00:9a:27:f5:7f:
        76:6a:ab:64:a4:65:7c:2a:ca:43:c7:6a:f3:fd:10:0c:a3:d5:
        f8:68:31:23:3a:0a:7e:10:51:1c:1d:9c:36:d0:05:2a:12:97:
        6e:8d:29:d4:9b:42:95:54:42:77:b6:cc:72:82:7e:98:f7:8b:
        8d:77:f9:cf:ae:4e:1a:d4:3c:a4:67:e5:94:1e:a7:d9:dd:8a:
        73:e4:d6:58:32:0e:4d:0e:8c:1b:51:a7:85:06:23:1c:ae:cf:
        30:2f:62:24:1c:1c:1b:a8:45:c9:69:59:08:17:c9:0d:b8:08:
        99:f4:01:05:76:2a:e7:4c:a2:f1:7e:71:a0:b6:6e:95:c5:55:
        3b:8c:67:a6:e1:e5:31:ca:2a:9d:b0:45:df:89:d0:77:2c:d9:
        9a:89:ee:35:99๐Ÿ†Ž34:8e:b3:41:a7:f7:3a:6e:83:4f:a1:05:
        65:42:7b:db:91:9f:0f:55:36:ec:82:12:78:cf:bf:57:1a:95:
        31:18:f2:6e:5a:7b:61:11:cc:06:2b:f0:2c:32:dc:b9:b0:af:
        e6:55:44:f8:98:0b:76:02:72:40:a4:7a:1a:84:2a:40:e1:a8:
        e2:c2:f4:3a:8c:da:9b:83:ca:05:7b:81:b9:48:ac:6e:58:13:

kube api server ์˜ ssl/tls ์ธ์ฆ์„œ์˜ ๋‚ด์šฉ์„ ๋ณด๋ฉด, ์•Œ ์ˆ˜ ์žˆ๋Š”๊ฒƒ๋“ค์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • Issuer: CN = kubernetes : ํ•ด๋‹น ์ธ์ฆ์„œ๋ฅผ ๋ฐœ๊ธ‰ํ•œ CN ์€ kubernetes ์ด๋‹ค.
  • Subject: CN = kube-apiserver : ์ธ์ฆ์„œ์˜ ์ฃผ์ฒด์˜ CN์€ kube-apiserver์ด๋‹ค.
  • X509v3 Subject Alternative Name : kube apiserver๋ฅผ ์ธ์ฆํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ณ„์นญ์ด๋‹ค.
  • Validity : ์ธ์ฆ์„œ๊ฐ€ ์–ผ๋งˆ๋‚˜ ์œ ํšจํ•œ์ง€

The kube-api server stopped again! Check it out. Inspect the kube-api server logs and identify the root cause and fix the issue.

kubeapi server ๊ฐ€ ์ค‘์ง€๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, kubectl ์„ ์ด์šฉํ•œ ๋กœ๊ทธ๋Š” ํ™•์ธํ•  ์ˆ˜ ์—†๋‹ค. ๋”ฐ๋ผ์„œ, container id ๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด, ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์— ๋”ฐ๋ผ ๋‹ค๋ฅด์ง€๋งŒ docker ps -a ๋˜๋Š” crictl ps -a ๋“ฑ ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด container id๋ฅผ ๊ฐ€์ ธ์˜จ ํ›„, docker logs [container-id]๋ฅผ ํ†ตํ•ด ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ์ƒ๊ฒผ๋Š” ์ง€ ์‚ดํŽด๋ณธ๋‹ค.

1
2
127.0.0.1:2379", }. Err: connection error: desc = "transport: authentication handshake failed: tls: failed to verify certificate: x509: certificate signed by unknown authority"
W0526 06:48:05.594458       1 logging.go:59] [core] [Channel #1 SubChannel #3] grpc: addrConn.createTransport failed to connect to {Addr: "127.0.0.1:2379", ServerName: "127.0.0.1:2379", }. Err: connection error: desc = "transport: authentication handshake failed: tls: failed to verify certificate: x509: certificate signed by unknown authority"

์œ„์™€ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๊ณ  kube-api server๊ฐ€ etcd ์„œ๋ฒ„์™€ ํ†ต์‹ ํ•  ๋•Œ ์ธ์ฆ์„œ์— ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์šฐ์„ , kube-apiserver์˜ ์„ค์ •ํŒŒ์ผ์„ ํ†ตํ•ด ca file ์ด ์–ด๋””์žˆ๋Š” ์ง€ ํ™•์ธํ•œ๋‹ค.

1
2
3
4
5
cat /etc/kubernetes/manifests/kube-apiserver.yaml | grep "etcd"
    - --etcd-cafile=/etc/kubernetes/pki/ca.crt
    - --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
    - --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
    - --etcd-servers=https://127.0.0.1:2379

์œ„์—์„œ etcd-cafile์˜ ๊ฒฝ๋กœ๋ฅผ ๋ณด๋ฉด, /etc/kubernetes/pki/ca.crt ํ•ด๋‹น ๊ฒฝ๋กœ๋Š” ํด๋Ÿฌ์Šคํ„ฐ ๋‚ด์—์„œ ๋‹ค์–‘ํ•œ ๊ตฌ์„ฑ์š”์†Œ์˜ ์ธ์ฆ์„œ๋ฅผ ๋ฐœ๊ธ‰ํ•˜๊ณ  ๊ฒ€์ฆํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฃจํŠธ ์ธ์ฆ์„œ ๊ฒฝ๋กœ์ด๋‹ค. ์ด ์ธ์ฆ์„œ๋Š” ์ƒˆ๋กœ์šด ๋…ธ๋“œ๋‚˜ ์‚ฌ์šฉ์ž๊ฐ€ ํด๋Ÿฌ์Šคํ„ฐ์— ์ถ”๊ฐ€๋  ๋•Œ, ์ด CA๋ฅผ ์ด์šฉํ•ด์„œ ํ•„์š”ํ•œ ์ธ์ฆ์„œ๋ฅผ ๋ฐœ๊ธ‰ํ•˜๊ณ  ํด๋Ÿฌ์Šคํ„ฐ ์„œ๋น„์Šค ๋‚ด ์ƒํ˜ธ ์ธ์ฆ์„ ์œ„ํ•ด ์ด CA๊ฐ€ ์ธ์ฆ๊ธฐ๊ด€์œผ๋กœ์„œ ์ž‘์šฉ๋œ๋‹ค.

๊ทธ๋Ÿฌ๋ฏ€๋กœ, ํ•ด๋‹น ๊ฒฝ๋กœ๋ฅผ etcd ์„œ๋ฒ„์˜ ca ์ธ์ฆ์„œ๋กœ ๊ต์ฒดํ•˜์—ฌ์•ผ ํ•œ๋‹ค.

certificate api

์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ์ธํ”„๋ผ ๊ด€๋ฆฌ ํŒ€์— ์ƒˆ๋กœ์šด ๋ฉค๋ฒ„๊ฐ€ ๋“ค์–ด์™”๋‹ค. ํ•ด๋‹น ๋ฉค๋ฒ„๊ฐ€ ์ฟ ๋ฒ„๋„ค์‹œ์Šค๋ฅผ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•œ ์ ์ ˆํ•œ ๊ถŒํ•œ์„ ๊ฐ€์ง„ ์ธ์ฆ์„œ๋ฅผ ๋ถ€์—ฌํ•˜๋ ค๊ณ  ํ•œ๋‹ค. ๊ทธ ๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. csr ํŒŒ์ผ / key ํŒŒ์ผ ์ƒ์„ฑ
1
2
3
4
5
# generate private key
openssl genrsa -out mykey.key 2048

# generate csr
openssl req -new -key mykey.key -out mycsr.csr -sujb "/CN=example.com/O=My organization/C=US"
  1. ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค์— CSR(certificate Signing Request) object ๋ฅผ ์ƒ์„ฑ
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# base64 ๋กœ ์ธ์ฝ”๋”ฉ
cat mycsr.csr | base64 -w 0

vi create-csr-object.yaml
# apiVersion: certificates.k8s.io/v1
# kind: CertificateSigningRequest
# metadata:
#   name: temp
# spec:
#   groups:
#   - system:authenticated
#   request: <์œ„์—์„œ ์ธ์ฝ”๋”ฉํ•œ ๊ฐ’>
#   signerName: kubernetes.io/kube-apiserver-client
#   usages:
#   - client auth
  1. ์Šน์ธ ๋˜๋Š” ๊ฑฐ์ ˆ
1
2
kubectl certificate approve temp
kubectl certificate deny temp

RBAC

RBAC ์€ ๊ธฐ๊ด€ ๋‚ด ๊ฐœ์ธ์˜ ์œ ์ €๊ฐ€ ํด๋Ÿฌ์Šคํ„ฐ์— ์ ‘๊ทผํ•  ๋•Œ ๊ทœ์ œ๋ฅผ ๋‘˜ ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ฃผ๋Š” ๊ฒƒ์„ ๋งํ•œ๋‹ค. ๊ถŒํ•œ์„ ๊ฐ€์ง„ ์‚ฌ๋žŒ๋งŒ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋ ค๋ฉด, kube api server๋ฅผ ์‹คํ–‰ํ•  ๋•Œ, –authorization-mode ๊ฐ’์— RBAC์„ ํฌํ•จ์‹œ์ผœ์ฃผ๋ฉด ๋œ๋‹ค.

1
2
3
4
5
6
7
8
kubectl describe role -n kube-system kube-proxy
Name:         kube-proxy
Labels:       <none>
Annotations:  <none>
PolicyRule:
  Resources   Non-Resource URLs  Resource Names  Verbs
  ---------   -----------------  --------------  -----
  configmaps  []                 [kube-proxy]    [get]

์œ„ ๊ฒฐ๊ณผ๋ฅผ ๋ณด๋ฉด, kube-system namespace ์—๋Š” kube-proxy๋ผ๋Š” role์ด ์กด์žฌํ•˜๊ณ , ์ด Role์„ ํ• ๋‹น๋ฐ›์€ ์œ ์ €๋Š” kube-proxy๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง„ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•ด get ์š”์ฒญ๋งŒ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ์•„๋ž˜๋Š”, kube-proxy๋ผ๋Š” role์„ ๊ฐ€์ง„ ์ฃผ์ฒด๋ฅผ ๋œปํ•œ๋‹ค.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
kubectl describe rolebindings.rbac.authorization.k8s.io -n kube-system kube-proxy
Name:         kube-proxy
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  kube-proxy
Subjects:
  Kind   Name                                             Namespace
  ----   ----                                             ---------
  Group  system:bootstrappers:kubeadm:default-node-token

Role์€ ์–ด๋–ค ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•ด ์–ผ๋งŒํผ์˜ ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•  ์ง€๋ฅผ ๊ฒฐ์ •ํ•ด์ฃผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๊ณ , rolebinding ์€ user/group/ ๋“ฑ ํด๋Ÿฌ์Šคํ„ฐ์— ์ ‘๊ทผํ•˜๋Š” ์ฃผ์ฒด์— role์„ ๋ถ€์—ฌํ•˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. role/rolebinding ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
kubectl create role developer --verb=list,create,delete --resource=pods
kubectl create rolebinding  dev-user-binding --role=developer --user=dev-user

# ์ถ”๊ฐ€๋กœ ์—ฌ๋Ÿฌ๊ฐœ์˜ ๋ฆฌ์†Œ์Šค์— ๋Œ€ํ•œ ๊ทœ์น™์„ ํ•˜๋‚˜์˜ role์— ๋ถ€์—ฌํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  creationTimestamp: "2024-05-26T14:36:47Z"
  name: developer
  namespace: blue
  resourceVersion: "2165"
  uid: bd5331df-f342-4d58-88b5-fff760d5b765
rules:
- apiGroups:
  - ""
  resourceNames:
  - blue-app
  - dark-blue-app
  resources:
  - pods
  verbs:
  - get
  - watch
  - create
  - delete
- apiGroups:
  - apps
  resources:
  - deployments
  verbs:
  - create

Role ์ด ์ •์ƒ์ ์œผ๋กœ ๋ถ€์—ฌ๊ฐ€ ๋˜์—ˆ๋Š” ์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด์„  ์•„๋ž˜์™€ ๊ฐ™์€ ๋ช…๋ น์–ด๋ฅผ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค. ์œ„ developer ์— ๋ช…์‹œ๋œ role์„ ๋ณด๋ฉด pods์— ๋Œ€ํ•œ ๋ชจ๋“  ์ ‘๊ทผ๊ถŒํ•œ, deployments์— ๋Œ€ํ•œ create๊ถŒํ•œ๋งŒ ์ƒ์„ฑ๋œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ, deployments๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” ์„ฑ๊ณต์ ์œผ๋กœ ์ˆ˜ํ–‰๋˜๊ณ , deployment ๋ชฉ๋ก์„ ๊ฐ€์ ธ์˜ค๋Š” api๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋˜๋ฉด ์‹คํŒจํ•  ๊ฒƒ์ด๋‹ค.

1
2
3
4
5
kubectl create deployment test --image busybox --dry-run=client --as dev-user
deployment.apps/test created (dry run)

kubectl get deployments.apps --as dev-user
Error from server (Forbidden): deployments.apps is forbidden: User "dev-user" cannot list resource "deployments" in API group "apps" in the namespace "default"

cluster role binding

์•ž์„œ role/rolebinding ๊ณผ cluster/cluster role binding ์˜ ์ฐจ์ด๋Š” role์€ ํŠน์ • namespace๋‚ด์—์„œ๋งŒ ์ž‘์šฉํ•˜๋Š” ๋ฐ˜๋ฉด, cluster role์€ ํด๋Ÿฌ์Šคํ„ฐ ์ „์ฒด์— ๊ฑธ์ณ ์ž‘์šฉํ•œ๋‹ค.

service account

service account๋Š” pod ๋‚ด์—์„œ ์‹คํ–‰์ค‘์ธ ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค api์™€ ์ƒํ˜ธ์ž‘์šฉํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค. ์ด ๊ณ„์ •์€ ํŠน์ • ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— ์†ํ•ด์žˆ์œผ๋ฉฐ, pod level์—์„œ ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ฆฌ์†Œ์Šค์— ์ ‘๊ทผํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. deployment์— service account ๋ฅผ ์ƒ์„ฑํ•  ๋•Œ๋Š” spec.serviceAccountName ์œผ๋กœ service account ์˜ ๋ฆฌ์†Œ์Šค ์ด๋ฆ„์„ ์ž‘์„ฑํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

Specifying imagePullSecrets on a Pod

private registry ์—์„œ ์ด๋ฏธ์ง€๋ฅผ pullํ•˜๋ ค๊ณ  ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค. ์šฐ์„  docker config์— ์‚ฌ์šฉํ•  kubernetes secret ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.

1
2
3
4
5
kubectl create secret docker-registry  <name> \
  --docker-server=DOCKER_REGISTRY_SERVER \
  --docker-username=DOCKER_USER \
  --docker-password=DOCKER_PASSWORD \
  --docker-email=DOCKER_EMAIL

secret ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ๋‚œ ํ›„ (literal ๋กœ ์ ์–ด์ฃผ๋Š” ๊ฒƒ์ด ์•„๋‹Œ ํŒŒ์ผ์„ ์ฐธ์กฐํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค), private registry ์— ์ ‘๊ทผ๊ถŒํ•œ์„ ์ฃผ๊ธฐ ์œ„ํ•ด, pod์˜ ์„ค์ •ํŒŒ์ผ์— imagePullSecrets ํ•„๋“œ๋ฅผ ์œ„์— ๋งŒ๋“ค์–ด์ค€ secret ์ด๋ฆ„์œผ๋กœ ํ• ๋‹นํ•œ๋‹ค.

1
2
3
4
5
spec:
  imagePullSecrets:
   - name : <name>
  containers:
   ...

security context

security context๋Š” pod ๋˜๋Š” container ๋ ˆ๋ฒจ์—์„œ ๋ณด์•ˆ ์ˆ˜์ค€์„ ์ •์˜ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋œ๋‹ค. container ์ƒ์„ฑ ์‹œ command argument ์— ํŠน์ • ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋Š” ์ฃผ์ฒด๊ฐ€ ๋ˆ„๊ตฌ์ธ์ง€ ์•Œ๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

1
kubectl exec [pod-name] -- whoami
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
 apiVersion: v1
kind: Pod
metadata:
  name: multi-pod
spec:
  securityContext:
    runAsUser: 1001
  containers:
  -  image: ubuntu
     name: web
     command: ["sleep", "5000"]
     securityContext:
      runAsUser: 1002

  -  image: ubuntu
     name: sidecar
     command: ["sleep", "5000"]

์œ„์™€ ๊ฐ™์ด specification ์ด ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉด, pod level์—์„œ๋Š” 1001 ๋กœ ์ž‘๋™ํ•œ๋‹ค. web container์—์„œ๋Š” 1002๋กœ pod level์˜ security context๋ฅผ ๋ฎ์œผ์“ฐ๊ฒŒ ๋œ๋‹ค. sidecar์˜ ๊ฒฝ์šฐ pod level์—์„œ ์ •์˜ํ•œ 1001์˜ context๋ฅผ ํ• ๋‹น๋ฐ›๊ฒŒ ๋œ๋‹ค.

1
2
3
securityContext:
  capabilities:
    add: ["NET_ADMIN", "SYS_TIME"]

์œ„ ์˜ต์…˜์€, ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์‹คํ–‰๋  ๋•Œ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ๊ฐ–๊ณ  ์žˆ์ง€ ์•Š์€ linux ๊ธฐ๋Šฅ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋‹ค. ๊ฐ ๊ธฐ๋Šฅ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • NET_ADMIN : ๋„คํŠธ์›Œํฌ ๊ด€๋ จ ์ˆ˜์ • ๊ถŒํ•œ, ip,route table ๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅ
  • SYS_TIME : ์‹œ๊ฐ„๊ฐ’ ์ˆ˜์ • ๊ถŒํ•œ

network policy

aws์˜ security group๊ณผ ๋น„์Šทํ•œ ๊ฑฐ๋‹ค. ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ์„ ์ œ์–ดํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•˜๋Š” ์ฟ ๋ฒ„๋„คํ‹ฐ์Šค ๋ฆฌ์†Œ์Šค์ด๋‹ค.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: internal-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      name: internal
  policyTypes:
    - Egress
    - Ingress
  ingress:
    - {}
  egress:
    - to:
        - podSelector:
            matchLabels:
              name: mysql
      ports:
        - protocol: TCP
          port: 3306

    - to:
        - podSelector:
            matchLabels:
              name: payroll
      ports:
        - protocol: TCP
          port: 8080

    - ports:
        - port: 53
          protocol: UDP
        - port: 53
          protocol: TCP

์œ„ specification ์„ ๋ณด๋ฉด, name=internal label์„ ๊ฐ€์ง„ pod์—๊ฒŒ network policy ๋ฅผ ๋ถ€์—ฌํ•˜๋Š”๋ฐ, ์™ธ๋ถ€ ํŠธ๋ž˜ํ”ฝ์€ name=mysql์„ ๊ฐ€์ง„ pod์˜ 3306 port ๊ทธ๋ฆฌ๊ณ , name=payroll label์„ ๊ฐ€์ง„ pod์˜ 8080 port ๋กœ ๋‚˜๊ฐ€๋Š” ํŠธ๋ž˜ํ”ฝ๋งŒ ํ—ˆ์šฉํ•œ๋‹ค.

์ถ”๊ฐ€๋กœ, kube-dns์—์„œ dns resolve ๋ฅผ ํ•˜๊ธฐ ์œ„ํ•ด TCP/UDP 53 ๋ฒˆ ํŠธ๋ž˜ํ”ฝ์„ ํ—ˆ์šฉํ•œ ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.