kmg28801 / kubernetes-study

2 stars 0 forks source link

Chapter 7. 컨피그맵과 시크릿: 애플리케이션 설정 #8

Open kmg28801 opened 1 year ago

seojeonghyeon commented 1 year ago

https://seojeonghyeon0630.notion.site/Chapter-7-ad75eb935992427a9c334bb49e94fcce

kmg28801 commented 1 year ago

고생하셨습니다 👍

seojeonghyeon commented 1 year ago

Chapter 7. 컨피그맵과 시크릿 애플리케이션 설정


Build 된 Application 자체에 포함하지 말아야하는 설정(배포된 Instance 별 다른 설정, 외부 System Access를 위한 자격증명 등)에 대해 Application 실행 시 설정 옵션을 전달하는 방법

ConfigMap : 설정 데이터를 저장하는 쿠버네티스 리소스

Main Point

7.1 Container화된 Application 설정(설정 정보를 Application에 전달하는 방법)

  1. Application에 대한 필요한 모든 설정을 Application에 포함
  2. 명령줄 인수(설정할 옵션 목록이 커지면 설정을 파일에 저장하고 사용)
  3. 환경 변수를 사용
  4. 특수한 유형의 Volumn을 통해 설정 파일을 Container에 Mount
  5. ConfigMap 사용

7.2 Container에 명령줄 인자 전달

ENTRYPOINT : Container가 시작될 때 호출될 명령어를 정의

CMD : ENTRYPOINT에 전달되는 인자를 정의

shell과 exec 형식 간의 차이

Shell 형식

내부에 정의된 명령을 Shell로 호출한다.(불필요한 Shell 프로세스가 호출될 수 있다.)

ENTRYPOINT node app.js

exec 형식

Container 내부에서 프로세스를 직접 실행한다.

ENTRYPOINT ["node", "app.js"]

Kubernetes에서 명령과 인자 재정의

ENTRYPOINT와 CMD 둘 다 재정의하기 위해 Container 정의 안에 “command”와 “args” 속성을 지정한다.

kind: Pod
spec:
    containers:
    - image: some/image
        # 명령을 재정의하는 경우는 거의 없음(ENTRYPOINT를 정의하지 않는 범용 이미지 제외)
        # command와 args 속성은 Pod 생성 이후 업데이트 불가능
        command: ["/bin/command"]
        args: ["arg1", "arg2", "arg3"]

Docker와 Kubernetes의 실행파일과 인자를 지정하는 방법 비교

Docker Kubernetes Description
ENTRYPOINT command Container 안에서 실행되는 실행파일
CMD args 실행파일에 전달되는 인자

사용자 정의 주기로 fortune Pod 실행

apiVersion: v1
kind: Pod
metadata:
  name: fortune2s
spec:
  containers:
  - name: html-generator
    image: luksa/fortune:args
    args:
      - "2" #문자는 따옴표로 묶을 필요가 없지만 숫자는 묶어야한다
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html
    emptyDir: {}

7.3 Container의 환경변수 설정

Pod의 각 Container를 위한 환경 변수 리스트를 지정 가능하다. Pod Level에서 환경변수를 설정하고 Container에서 상속받는 옵션은 없다.

환경변수 가져다 쓰는 예제

#!/bin/bash
trap "exit" SIGINT
# INTERVAL=$1
echo Configured to generate new fortune every @INTERVAL seconds
mkdir -p /var/htdocs
while : 
do
    echo $(date) Writing fortune to /var/htdocs/index.html
    /usr/games/fortune > /var/htdocs/index.html
    sleep $INTERVAL
done

Container 정의에서 환경변수 지정

apiVersion: v1
kind: Pod
metadata:
  name: fortune2s
spec:
  containers:
  - name: html-generator
    image: luksa/fortune:env
    **env:
    - name: INTERVAL
            value: "30"**
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html
    emptyDir: {}

변수값에서 다른 환경변수 참조

apiVersion: v1
kind: Pod
metadata:
  name: fortune2s
spec:
  containers:
  - name: html-generator
    image: luksa/fortune:env
    **env:
    - name: INTERVAL
            value: "30"
        - name: FIRST_VAR
            value: "foo"
        - name: SECOND_VAR
            value: "$(FIRST_VAR)bar" #foobar**
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html
    emptyDir: {}

Pod 정의에 하드코딩된 값을 가져오는 것은 효율적이지만 Production과 Development를 위해 서로 분리된 Pod의 정의가 필요하다. value field 대신 valueFrom으로 환경변수 값의 원본소스를 사용할 수 있다.

7.4 ConfigMap으로 설정분리

Application 구성의 요점은 환경에 따라 다르거나 자주 변경되는 설정 옵션을 Application Source Code와 별도로 유지하는 것이다.

ConfigMap(짧은 문자열에서 전체 설정 파일에 이르는 값을 가지는 Key-Value로 구성된 Map)

Map의 내용은 Container의 환경 변수 or ConfigMap Volume 파일로 전달된다. 또한 Container의 환경 변수는 $(ENV_VAR) 구문을 사용해 명령줄 인수에서 참조할 수 있기에 ConfigMap 항목을 프로세스의 명령줄 인자로 전달 가능하다.

Application이 직접 Kubernetes REST API Endpoint를 통해 ConfigMap 내용을 읽을 수 있지만 반드시 필요한 경우가 아니라면 Kubernetes와 무관하도록 유지해야한다.

Untitled

ConfigMap에서 내용을 읽어가도록 설정을 포함하게 되면, 각각 다른 환경(Development, Stage, Production 등)에 관해 동일한 이름으로 ConfigMap에 관한 여러 Manifest를 유지 가능하다. Pod는 ConfigMap을 이름으로 참조하기 때문에 모든 환경에서 동일한 Pod 정의를 사용해 각각 환경에서 서로 다른 설정을 사용할 수 있다.

ConfigMap 생성

ConfigMap 생성 예제


단일 항목을 가진 ConfigMap 생성

zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create configmap fortune-config --from-literal=sleep-interval=25
W1224 09:47:11.973914   80963 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
configmap/fortune-config created

**# sleep-interval = 25라는 단일 항목을 가진 ConfigMap 생성**
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get configmap fortune-config -o yaml
W1224 09:47:14.701277   80971 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
apiVersion: v1
data:
  **sleep-interval: "25"**
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-24T00:47:12Z"
  **name: fortune-config**
  **namespace: default**
  resourceVersion: "3413924"
  uid: 933123ea-20af-404f-8983-b3b717ae4dcb

*ConfigMap Key는 유효한 DNS Subdomain(영문, 숫자, 대시, 밑줄 점만 포함가능)이어야하며 필요시 점이 먼저 나올 수 있다.

두 개 이상의 항목을 가진 ConfigMap 생성

zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create configmap configmaptest --from-literal=bar=baz --from-literal=one=
two
W1224 09:45:39.030337   80920 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
configmap/configmaptest created

#일반적으로 ConfigMap에는 두 개 이상의 항목을 포함한다.
**#bar = baz, one = two라는 두 개의 항목을 가진 ConfigMap 생성**
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get configmap configmaptest -o yaml
W1224 09:53:05.015537   81084 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
apiVersion: v1
data:
  **bar: baz
  one: two**
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-24T00:45:39Z"
  **name: configmaptest**
  **namespace: default**
  resourceVersion: "3412904"
  uid: 6c57c88c-4bad-4bd6-a7b8-aa3fb90e1cd6

YML 파일로 ConfigMap 생성

#fortune-config.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: fotune-config-test-file
data:
  number: one
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create -f fortune-config.yml
W1224 10:07:37.049426   81376 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
configmap/fotune-config-test-file created

zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get configmap fotune-config-test-file -o yaml
W1224 10:07:49.331121   81385 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
apiVersion: v1
data:
  **number: one**
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-24T01:07:39Z"
  **name: fotune-config-test-file
  namespace: default**
  resourceVersion: "3427401"
  uid: cd8fcd47-8aa9-4bf4-b392-c9f068e0ba3f

File 내용으로 ConfigMap 생성

  1. Key 이름 미 지정

    zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create configmap my-config --from-file=fortuneloop.sh
    W1224 10:12:57.407862   81507 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
    To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
    configmap/my-config created
    
    **#파일이름 : 파일 내용으로 Key-Value가 생성**
     zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get configmap my-config -o yaml
    W1224 10:13:14.193705   81522 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
    To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
    apiVersion: v1
    data:
      **fortuneloop.sh: "#!/bin/bash\ntrap \"exit\" SIGINT\n# INTERVAL=$1\necho Configured
        to generate new fortune every @INTERVAL seconds\nmkdir -p /var/htdocs\nwhile :
        \ndo\n    echo $(date) Writing fortune to /var/htdocs/index.html\n    /usr/games/fortune
        > /var/htdocs/index.html\n    sleep $INTERVAL\ndone"**
    kind: ConfigMap
    metadata:
      creationTimestamp: "2022-12-24T01:12:57Z"
      **name: my-config**
      namespace: default
      resourceVersion: "3430901"
      uid: 8db4855f-7bc1-4ed4-a97f-880001e0b5d3
    
     zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  ll
    total 136
    -rw-r--r--  1 zayden  staff   153B 12 23 09:09 Dockerfile
    -rw-r--r--  1 zayden  staff   290B 12 10 15:45 Kubia-svc.yml
    -rw-r--r--  1 zayden  staff   481B 11  6 13:02 coffeorderservice-msa-deployment.yml
    -rw-r--r--  1 zayden  staff   390B 12 10 13:48 cronjob.yml
    -rw-r--r--  1 zayden  staff    67B 11 19 17:34 custom-namespace.yml
    -rw-r--r--  1 zayden  staff   237B 12 10 13:31 exporter.yml
    -rw-r--r--  1 zayden  staff    93B 12 24 10:07 fortune-config.yml
    -rw-r--r--  1 zayden  staff   452B 12 24 10:02 fortune-pod-args.yml
    -rw-r--r--  1 zayden  staff     0B 12 17 11:47 fortune-pod.yml
    -rw-r--r--  1 zayden  staff   273B 12 23 11:06 fortuneloop.sh
    -rw-r--r--  1 zayden  staff    64B 11 13 13:51 kubectl.sha256
    -rw-r--r--  1 zayden  staff   372B 12 10 17:43 kubia-ingress-tls.yml
    -rw-r--r--  1 zayden  staff   293B 12 10 16:23 kubia-ingress.yml
    -rw-r--r--  1 zayden  staff   271B 12 10 13:38 multi-completion-batch-job.yml
    -rw-r--r--  1 zayden  staff   288B 12 10 13:42 muti-completion-parallel-batch-job.yml
    -rw-r--r--  1 zayden  staff   261B 11 19 16:39 ngix-sample.yml
    -rw-r--r--@ 1 zayden  staff   341B 11 19 14:13 sample1.yml
    -rw-r--r--  1 zayden  staff   297B 12 10 13:17 ssd-monitor-daemonset.yml
  2. Key이름 지정

    zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create configmap my-config2 --from-file=customkey=fortuneloop.sh
    W1224 10:16:19.189840   81586 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
    To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
    configmap/my-config2 created
    
    **#지정한 Key이름 : 파일 내용으로 Key-Value가 생성**
     zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get configmap my-config2 -o yaml
    W1224 10:16:25.397629   81594 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
    To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
    apiVersion: v1
    data:
      **customkey: "#!/bin/bash\ntrap \"exit\" SIGINT\n# INTERVAL=$1\necho Configured to
        generate new fortune every @INTERVAL seconds\nmkdir -p /var/htdocs\nwhile : \ndo\n
        \   echo $(date) Writing fortune to /var/htdocs/index.html\n    /usr/games/fortune
        > /var/htdocs/index.html\n    sleep $INTERVAL\ndone"**
    kind: ConfigMap
    metadata:
      creationTimestamp: "2022-12-24T01:16:19Z"
      **name: my-config2
      namespace: default**
      resourceVersion: "3433117"
      uid: 8735ef7e-b121-4dfb-9a7a-45003e9377f3

Directory에 있는 파일로 ConfigMap 생성

파일이 너무 많아 보기 힘든데, 파일이름 : 파일 내용으로 Key-Value가 추가되며, 파일이름이 ConfigMap Key로 사용하기에 유효한 파일만 추가가 된다.

zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  pwd
/Users/zayden/Documents/Work/kubernetes-repo

 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create configmap my-config3 --from-file=/Users/zayden/Documents/Work/kubernetes-repo
W1224 10:19:58.036620   81671 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
configmap/my-config3 created

 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get configmap my-config3 -o yaml
W1224 10:20:10.524882   81680 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
apiVersion: v1
binaryData:
  .DS_Store: AAAAAUJ1ZDEAABAAAAAIAAAAEAAAAAIJAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAUAAAABAAAQAABlAG8AcgBkAGUAcgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAkAGMAbwBmAGYAZQBvAHIAZABlAHIAcwBlAHIAdgBpAGMAZQAtAG0AcwBhAC0AZABlAHAAbABvAHkAbQBlAG4AdAAuAHkAbQBsSWxvY2Jsb2IAAAAQAAAAQQAAAC7///////8AAAAAABQAYwB1AHMAdABvAG0ALQBuAGEAbQBlAHMAcABhAGMAZQAuAHkAbQBsSWxvY2Jsb2IAAAAQAAAB+QAAAC7///////8AAAAAAA4AawB1AGIAZQBjAHQAbAAuAHMAaABhADIANQA2SWxvY2Jsb2IAAAAQAAAArwAAAC7///////8AAAAAAA8AbgBnAGkAeAAtAHMAYQBtAHAAbABlAC4AeQBtAGxJbG9jYmxvYgAAABAAAAEdAAAALv///////wAAAAAACwBzAGEAbQBwAGwAZQAxAC4AeQBtAGxJbG9jYmxvYgAAABAAAAGLAAAALv///////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAgLAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAACAAAAABAAAAQAAAAAEAAACAAAAAAQAAAQAAAAABAAACAAAAAAEAAAQAAAAAAAAAAAEAABAAAAAAAQAAIAAAAAABAABAAAAAAAEAAIAAAAAAAQABAAAAAAABAAIAAAAAAAEABAAAAAAAAQAIAAAAAAABABAAAAAAAAEAIAAAAAAAAQBAAAAAAAABAIAAAAAAAAEBAAAAAAAAAQIAAAAAAAABBAAAAAAAAAEIAAAAAAAAARAAAAAAAAABIAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAEAsAAABFAAACCQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBERTREIAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAIAAAAGAAAAAAAAAAAQAAAIAAAAABAAABAAAAAAAAAAABAAAEAAAAAAIAAAgAAAAYAAAAAAAAAAABAAAgAAAAAAEAAEAAAAAAAQAAgAAAAAABAAEAAAAAAAEAAgAAAAAAAQAEAAAAAAABAAgAAAAAAAEAEAAAAAAAAQAgAAAAAAABAEAAAAAAAAEAgAAAAAAAAQEAAAAAAAABAgAAAAAAAAEEAAAAAAAAAQgAAAAAAAABEAAAAAAAAAEgAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
data:
  Dockerfile: |-
    FROM ubuntu:latest
    RUN apt-get update ; apt-get -y install fortune
    ADD fortuneloop.sh /bin/fortuneloop.sh
    ENTRYPOINT ["/bin/fortuneloop.sh"]
    CMD [ "10" ]
  Kubia-svc.yml: |
    apiVersion: v1
    kind: Service
    metadata:
      name: kubia
    spec:
      selector:
        app: kubia
      ports:
      - port: 80
        targetPort: 8080
        ## 멀티 포트 공유시
        ## - name: http
        ##   port: 80
        ##   targetPort: 8080
        ## - name: https
        ##   port: 443
        ##   targetPort: 8443
  coffeorderservice-msa-deployment.yml: |
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: coffeeorderservice-deployment
    spec:
      selector:
        matchLabels:
          app: coffeeorderservice-msa-project
        replicas: 2

        template:
        metadata:
          labels:
            app: coffeeorderservice-msa-project
        spec:
          containers:
          - name: coffeeorderservice-msa-project
            image: seojeonghyeon0630/coffeeorderservice-eurekaservice
            imagePullPolicy: Always
            ports:
            - containerPort: 8080
  cronjob.yml: |-
    apiVersion: batch/v1beta1
    kind: CronJob
    metadata:
      name: batch-job-every-fifteen-minutes
    spec:
      jobTemplate:
        spec:
          template:
              metadata:
                labels:
                  app: periodic-batch-job
              spec:
                restartPolicy: OnFailure
                containers:
                  - name: main
                    image: luksa/batch-job
      schedule: "0,15,30,45 * * * *"
  custom-namespace.yml: |-
    apiVersion: v1
    kind: Namespace
    metadata:
        name: custom-namespace
  exporter.yml: |
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: batch-job
    spec:
      template:
        metadata:
          labels:
            app: batch-job
        spec:
          containers:
          - name: main
            image: luksa/batch-job
          restartPolicy: OnFailure
  fortune-config.yml: |
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: fotune-config-test-file
    data:
      number: one
  fortune-pod-args.yml: |
    apiVersion: v1
    kind: Pod
    metadata:
      name: fortune2s
    spec:
      containers:
      - name: html-generator
        image: luksa/fortune:args
        args:
          - "2"
        volumeMounts:
        - name: html
          mountPath: /var/htdocs
      - image: nginx:alpine
        name: web-server
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
          readOnly: true
        ports:
        - containerPort: 80
          protocol: TCP
      volumes:
      - name: html
        emptyDir: {}
  fortune-pod.yml: ""
  fortuneloop.sh: "#!/bin/bash\ntrap \"exit\" SIGINT\n# INTERVAL=$1\necho Configured
    to generate new fortune every @INTERVAL seconds\nmkdir -p /var/htdocs\nwhile :
    \ndo\n    echo $(date) Writing fortune to /var/htdocs/index.html\n    /usr/games/fortune
    > /var/htdocs/index.html\n    sleep $INTERVAL\ndone"
  kubectl.sha256: b2acd8e949eca67eef4d1217d7d31bed348a0fda94c4b355aa2844f5ad5c6a9f
  kubia-ingress-tls.yml: "apiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n
    \ name: kubia\nspec:\n  rules:\n  - host: kubia.example.com\n    http:\n      paths:\n
    \     - pathType: Prefix\n        path: \"/\"\n        backend:\n          service:\n
    \           name: kubia-nodeport\n            port: \n              number: 80\n
    \ tls:\n    - hosts:\n        - kubia.example.com\n        secretName: tls-secret\n"
  kubia-ingress.yml: "apiVersion: networking.k8s.io/v1\nkind: Ingress\nmetadata:\n
    \ name: kubia\nspec:\n  rules:\n  - host: kubia.example.com\n    http:\n      paths:\n
    \     - pathType: Prefix\n        path: \"/\"\n        backend:\n          service:\n
    \           name: kubia-nodeport\n            port: \n              number: 80\n"
  multi-completion-batch-job.yml: |
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: multi-completion-batch-job
    spec:
      completions: 5
      template:
        metadata:
          labels:
            app: batch-job
        spec:
          containers:
          - name: main
            image: luksa/batch-job
          restartPolicy: OnFailure
  muti-completion-parallel-batch-job.yml: |
    apiVersion: batch/v1
    kind: Job
    metadata:
      name: multi-completion-batch-job
    spec:
      completions: 5
      parallelism: 2
      template:
        metadata:
          labels:
            app: batch-job
        spec:
          containers:
          - name: main
            image: luksa/batch-job
          restartPolicy: OnFailure
  ngix-sample.yml: |-
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-pod-sample-v2
      labels:
        creation_method: sample
        env: stg
    spec:
      nodeSelector:
        sdd: "true"
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort : 80
          protocol: TCP
  sample1.yml: |-
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: nginx:1.14.2
            ports:
            - containerPort : 80
  ssd-monitor-daemonset.yml: |-
    apiVersion: apps/v1
    kind: DaemonSet
    metadata:
      name : ssd-monitor
    spec:
      selector:
        matchLabels:
          app: ssd-monitor
      template:
        metaLabels:
          labels:
            app: ssd-monitor
      spec:
        nodeSelector:
          disk: ssd
        containers:
        - name: main
          image: luksa/ssd-monitor
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-24T01:19:58Z"
  name: my-config3
  namespace: default
  resourceVersion: "3435520"
  uid: 1f3af1a9-0d4b-41b0-8951-02ddccdd1985

ConfigMap 항목을 환경변수로 Container에 전달

환경변수를 ConfigMap에서 가져오는 Pod 생성 예제


#fortune-pod-env-configmap.yml
apiVersion: v1
kind: Pod
metadata:
  name: fortune-env-from-configmap
spec:
  containers:
  - name: html-generator
    image: luksa/fortune:env
    **env:
      - name: INTERVAL
        valueFrom:
          configMapKeyRef:
            key: sleep-interval
            name: fortune-config**
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html
    emptyDir: {}
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create -f fortune-pod-env-configmap.yml
W1224 10:42:57.478235   82074 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
Warning: Autopilot set default resource requests for Pod default/fortune-env-from-configmap, as resource requests were not specified. See http://g.co/gke/autopilot-defaults
pod/fortune-env-from-configmap created

 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get pods
W1224 10:43:14.711009   82127 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
NAME                         READY   STATUS    RESTARTS   AGE
fortune-env-from-configmap   0/2     Pending   0          15s

 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get po fortune-env-from-configmap -o yaml
W1224 10:44:19.144492   82156 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
apiVersion: v1
kind: Pod
metadata:
  annotations:
    autopilot.gke.io/resource-adjustment: '{"input":{"containers":[{"name":"html-generator"},{"name":"web-server"}]},"output":{"containers":[{"limits":{"cpu":"500m","ephemeral-storage":"1Gi","memory":"2Gi"},"requests":{"cpu":"500m","ephemeral-storage":"1Gi","memory":"2Gi"},"name":"html-generator"},{"limits":{"cpu":"500m","ephemeral-storage":"1Gi","memory":"2Gi"},"requests":{"cpu":"500m","ephemeral-storage":"1Gi","memory":"2Gi"},"name":"web-server"}]},"modified":true}'
    seccomp.security.alpha.kubernetes.io/pod: runtime/default
  creationTimestamp: "2022-12-24T01:43:00Z"
  **name: fortune-env-from-configmap**
  namespace: default
  resourceVersion: "3451585"
  uid: 3b9cd31d-d088-44e3-977e-1882b957048c
spec:
  containers:
  **- env:
    - name: INTERVAL
      valueFrom:
        configMapKeyRef:
          key: sleep-interval
          name: fortune-config**
    image: luksa/fortune:env
    imagePullPolicy: IfNotPresent
    name: html-generator
    resources:
      limits:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
      requests:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
    securityContext:
      capabilities:
        drop:
        - NET_RAW
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/htdocs
      name: html
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-zw49s
      readOnly: true
  - image: nginx:alpine
    imagePullPolicy: IfNotPresent
    name: web-server
    ports:
    - containerPort: 80
      protocol: TCP
    resources:
      limits:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
      requests:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
    securityContext:
      capabilities:
        drop:
        - NET_RAW
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: html
      readOnly: true
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-zw49s
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: gke.io/optimize-utilization-scheduler
  securityContext:
    seccompProfile:
      type: RuntimeDefault
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  - effect: NoSchedule
    key: kubernetes.io/arch
    operator: Equal
    value: amd64
  volumes:
  - emptyDir: {}
    name: html
  - name: kube-api-access-zw49s
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2022-12-24T01:43:01Z"
    message: '0/1 nodes are available: 1 node(s) had untolerated taint {node.kubernetes.io/not-ready:
      }. preemption: 0/1 nodes are available: 1 Preemption is not helpful for scheduling.'
    reason: Unschedulable
    status: "False"
    type: PodScheduled
  phase: Pending
  qosClass: Guaranteed

zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get pods
W1224 10:47:50.639295   82221 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
NAME                         READY   STATUS    RESTARTS   AGE
fortune-env-from-configmap   2/2     Running   0          4m51s

Untitled

Pod에 존재하지 않는 ConfigMap 참조

  1. Kubernetes는 Pod를 Scheduling
  2. Pod 내 Container를 실행하려고 시도
  3. Cotainer가 존재하지 않는 ConfigMap을 참조하려하면 Container는 시작하는데 실패
  4. 참조하지 않는 다른 Container는 정상적으로 시작
  5. 누락된 ConfigMap을 생성하면 실패했던 Container는 자동 시작

*ConfigMap 참조를 Option(configMapKeyRef.optional: true)으로 지정한 경우 ConfigMap이 존재하지 않아도 Container는 시작된다.

ConfigMap의 모든 항목을 한 번에 환경변수로 전달

Kubernetes version 1.6부터 기능 제공

ConfigMap 모든 항목을 한 번에 환경변수로 전달 예제


#fortune-config.yml
apiVersion: v1
kind: ConfigMap
metadata:
  name: fotune-config-allitems
**data:
  FOO: foo
  BAR: bar
  FOO-BAR: foo-bar**
#fortune-pod-env-configmap.yml
apiVersion: v1
kind: Pod
metadata:
  name: fortune-env-from-configmap
spec:
  containers:
  - name: html-generator
    image: luksa/fortune:env
    **envFrom:
      - prefix: CONFIG_
        configMapRef:
          name: fotune-config-allitems**
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html
    emptyDir: {}
#ConfigMap 생성 완료
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create -f fortune-config.yml
W1224 11:25:55.771865   82834 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
**configmap/fotune-config-allitems created**

#Key-Value 정상 확인
 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get configmap fotune-config-allitems -o yaml
W1224 11:26:52.523957   82856 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
apiVersion: v1
**data:
  BAR: bar
  FOO: foo
  FOO-BAR: foo-bar**
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-24T02:25:56Z"
  **name: fotune-config-allitems**
  namespace: default
  resourceVersion: "3479839"
  uid: 78bb4b03-b3d9-4295-8d02-7d70eddb1a3a

# 이전꺼 Pod 우선 삭제
 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl delete po fortune-env-from-configmap
W1224 11:27:47.152815   82881 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
pod "fortune-env-from-configmap" deleted

# 정상적으로 Pod 삭제 확인
 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get po
W1224 11:29:08.211040   82907 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
No resources found in default namespace.

# Pod 생성
 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create -f fortune-pod-env-configmap.yml
W1224 11:29:24.203349   82917 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
Warning: Autopilot set default resource requests for Pod default/fortune-env-from-configmap, as resource requests were not specified. See http://g.co/gke/autopilot-defaults
pod/fortune-env-from-configmap created

#Pod 설정 확인
 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get po fortune-env-from-configmap -o yaml
W1224 11:29:43.052608   82928 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke

apiVersion: v1
kind: Pod
metadata:
  annotations:
    autopilot.gke.io/resource-adjustment: '{"input":{"containers":[{"name":"html-generator"},{"name":"web-server"}]},"output":{"containers":[{"limits":{"cpu":"500m","ephemeral-storage":"1Gi","memory":"2Gi"},"requests":{"cpu":"500m","ephemeral-storage":"1Gi","memory":"2Gi"},"name":"html-generator"},{"limits":{"cpu":"500m","ephemeral-storage":"1Gi","memory":"2Gi"},"requests":{"cpu":"500m","ephemeral-storage":"1Gi","memory":"2Gi"},"name":"web-server"}]},"modified":true}'
    seccomp.security.alpha.kubernetes.io/pod: runtime/default
  creationTimestamp: "2022-12-24T02:29:26Z"
  name: fortune-env-from-configmap
  namespace: default
  resourceVersion: "3482262"
  uid: 44444625-5c85-45a1-9c29-5c8136e0ccff
spec:
  containers:
  **- envFrom:
    - configMapRef:
        name: fotune-config-allitems
      prefix: CONFIG_**
    image: luksa/fortune:env
    imagePullPolicy: IfNotPresent
    name: html-generator
    resources:
      limits:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
      requests:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
    securityContext:
      capabilities:
        drop:
        - NET_RAW
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /var/htdocs
      name: html
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-fnbx6
      readOnly: true
  - image: nginx:alpine
    imagePullPolicy: IfNotPresent
    name: web-server
    ports:
    - containerPort: 80
      protocol: TCP
    resources:
      limits:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
      requests:
        cpu: 500m
        ephemeral-storage: 1Gi
        memory: 2Gi
    securityContext:
      capabilities:
        drop:
        - NET_RAW
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /usr/share/nginx/html
      name: html
      readOnly: true
    - mountPath: /var/run/secrets/kubernetes.io/serviceaccount
      name: kube-api-access-fnbx6
      readOnly: true
  dnsPolicy: ClusterFirst
  enableServiceLinks: true
  nodeName: gk3-autopilot-cluster-1-nap-1esnt5d2-4ebfef00-vrsj
  preemptionPolicy: PreemptLowerPriority
  priority: 0
  restartPolicy: Always
  schedulerName: gke.io/optimize-utilization-scheduler
  securityContext:
    seccompProfile:
      type: RuntimeDefault
  serviceAccount: default
  serviceAccountName: default
  terminationGracePeriodSeconds: 30
  tolerations:
  - effect: NoExecute
    key: node.kubernetes.io/not-ready
    operator: Exists
    tolerationSeconds: 300
  - effect: NoExecute
    key: node.kubernetes.io/unreachable
    operator: Exists
    tolerationSeconds: 300
  - effect: NoSchedule
    key: kubernetes.io/arch
    operator: Equal
    value: amd64
  volumes:
  - emptyDir: {}
    name: html
  - name: kube-api-access-fnbx6
    projected:
      defaultMode: 420
      sources:
      - serviceAccountToken:
          expirationSeconds: 3607
          path: token
      - configMap:
          items:
          - key: ca.crt
            path: ca.crt
          name: kube-root-ca.crt
      - downwardAPI:
          items:
          - fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
            path: namespace
status:
  conditions:
  - lastProbeTime: null
    lastTransitionTime: "2022-12-24T02:29:26Z"
    status: "True"
    type: Initialized
  - lastProbeTime: null
    lastTransitionTime: "2022-12-24T02:29:31Z"
    status: "True"
    type: Ready
  - lastProbeTime: null
    lastTransitionTime: "2022-12-24T02:29:31Z"
    status: "True"
    type: ContainersReady
  - lastProbeTime: null
    lastTransitionTime: "2022-12-24T02:29:26Z"
    status: "True"
    type: PodScheduled
  containerStatuses:
  - containerID: containerd://cd524b1c4d3279aa2d509756acbc484a2b183613c4e78a3c962b6d56f8976330
    image: docker.io/luksa/fortune:env
    imageID: docker.io/luksa/fortune@sha256:8af10b8eb1b1dcc6512e0061c0722db43f4795aefcde43b524b1c8b302611dde
    lastState: {}
    name: html-generator
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2022-12-24T02:29:29Z"
  - containerID: containerd://5d6bd03c5e19f9baf18b1366baf2152f72ddd5cb7cba706bfd635a9ee93dfe4a
    image: docker.io/library/nginx:alpine
    imageID: docker.io/library/nginx@sha256:dd8a054d7ef030e94a6449783605d6c306c1f69c10c2fa06b66a030e0d1db793
    lastState: {}
    name: web-server
    ready: true
    restartCount: 0
    started: true
    state:
      running:
        startedAt: "2022-12-24T02:29:30Z"
  hostIP: 10.140.0.10
  phase: Running
  podIP: 10.53.128.68
  podIPs:
  - ip: 10.53.128.68
  qosClass: Guaranteed
  startTime: "2022-12-24T02:29:26Z"

zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get po
W1224 11:32:17.962310   82982 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
NAME                         READY   STATUS    RESTARTS   AGE
fortune-env-from-configmap   2/2     Running   0          2m52s

zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl describe pod fortune-env-from-configmap
W1224 11:39:35.659756   83126 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
Name:             fortune-env-from-configmap
Namespace:        default
Priority:         0
Service Account:  default
Node:             gk3-autopilot-cluster-1-nap-1esnt5d2-4ebfef00-vrsj/10.140.0.10
Start Time:       Sat, 24 Dec 2022 11:29:26 +0900
Labels:           <none>
Annotations:      autopilot.gke.io/resource-adjustment:
                    {"input":{"containers":[{"name":"html-generator"},{"name":"web-server"}]},"output":{"containers":[{"limits":{"cpu":"500m","ephemeral-stora...
                  seccomp.security.alpha.kubernetes.io/pod: runtime/default
Status:           Running
IP:               10.53.128.68
IPs:
  IP:  10.53.128.68
Containers:
  html-generator:
    Container ID:   containerd://cd524b1c4d3279aa2d509756acbc484a2b183613c4e78a3c962b6d56f8976330
    Image:          luksa/fortune:env
    Image ID:       docker.io/luksa/fortune@sha256:8af10b8eb1b1dcc6512e0061c0722db43f4795aefcde43b524b1c8b302611dde
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Sat, 24 Dec 2022 11:29:29 +0900
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:                500m
      ephemeral-storage:  1Gi
      memory:             2Gi
    Requests:
      cpu:                500m
      ephemeral-storage:  1Gi
      memory:             2Gi
    **Environment Variables from:
      fotune-config-allitems  ConfigMap with prefix 'CONFIG_'  Optional: false
    Environment:              <none>**
    Mounts:
      /var/htdocs from html (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-fnbx6 (ro)
  web-server:
    Container ID:   containerd://5d6bd03c5e19f9baf18b1366baf2152f72ddd5cb7cba706bfd635a9ee93dfe4a
    Image:          nginx:alpine
    Image ID:       docker.io/library/nginx@sha256:dd8a054d7ef030e94a6449783605d6c306c1f69c10c2fa06b66a030e0d1db793
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sat, 24 Dec 2022 11:29:30 +0900
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:                500m
      ephemeral-storage:  1Gi
      memory:             2Gi
    Requests:
      cpu:                500m
      ephemeral-storage:  1Gi
      memory:             2Gi
    Environment:          <none>
    Mounts:
      /usr/share/nginx/html from html (ro)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-fnbx6 (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  html:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:
    SizeLimit:  <unset>
  kube-api-access-fnbx6:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   Guaranteed
Node-Selectors:              <none>
Tolerations:                 kubernetes.io/arch=amd64:NoSchedule
                             node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From                                   Message
  ----    ------     ----  ----                                   -------
  Normal  Scheduled  10m   gke.io/optimize-utilization-scheduler  Successfully assigned default/fortune-env-from-configmap to gk3-autopilot-cluster-1-nap-1esnt5d2-4ebfef00-vrsj
  Normal  Pulled     10m   kubelet                                Container image "luksa/fortune:env" already present on machine
  Normal  Created    10m   kubelet                                Created container html-generator
  Normal  Started    10m   kubelet                                Started container html-generator
  Normal  Pulled     10m   kubelet                                Container image "nginx:alpine" already present on machine
  Normal  Created    10m   kubelet                                Created container web-server
  Normal  Started    10m   kubelet                                Started container web-server

환경변수 앞에 붙을 접두사를 지정해두었고 Container 안에는 두 개(CONFIG_FOO, CONFIG_BAR)가 존재한다고 하는데, 여기 단계에서는 확인이 쉽지 않다.

CONFIG_FOO-BAR는 -를 가지고 잇어, 올바른 환경변수 이름이 아니다. Kubernetes는 임의로 Key를 변환하지 않고 항목을 건너뛴다.(건너뛸때는 건너뛰었다는 이벤트가 기록된다..?)

ConfigMap 항목을 명령줄 인자로 전달

ConfigMap 항목을 명령줄 인자로 전달


apiVersion: v1
kind: Pod
metadata:
  name: fortune-env-from-configmap
spec:
  containers:
  - name: html-generator
    image: luksa/fortune:args
    env:
      - name: INTERVAL
        valueFrom:
          configMapKeyRef:
            key: sleep-interval
            name: fortune-config
    args: ["$(INTERVAL)"]
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html
    emptyDir: {}
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create -f fortune-pod-env-configmap.yml
W1224 12:11:06.204222   83730 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
Warning: Autopilot set default resource requests for Pod default/fortune-env-from-configmap, as resource requests were not specified. See http://g.co/gke/autopilot-defaults
pod/fortune-env-from-configmap created

 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl describe pod fortune-env-from-configmap
W1224 12:11:25.575311   83741 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
Name:             fortune-env-from-configmap
Namespace:        default
Priority:         0
Service Account:  default
Node:             gk3-autopilot-cluster-1-nap-1esnt5d2-92c5f823-22pk/10.140.0.9
Start Time:       Sat, 24 Dec 2022 12:11:07 +0900
Labels:           <none>
Annotations:      autopilot.gke.io/resource-adjustment:
                    {"input":{"containers":[{"name":"html-generator"},{"name":"web-server"}]},"output":{"containers":[{"limits":{"cpu":"500m","ephemeral-stora...
                  seccomp.security.alpha.kubernetes.io/pod: runtime/default
Status:           Running
IP:               10.53.128.14
IPs:
  IP:  10.53.128.14
Containers:
  html-generator:
    Container ID:  containerd://78fdb6d311b5c8f12f90d9a491f0aa086c9f8b16b664194f9163def6d0ccc773
    Image:         luksa/fortune:args
    Image ID:      docker.io/luksa/fortune@sha256:423bba372648ab09365a156022ce032ab8f7979c6118074ef41ecc4a42eee57c
    Port:          <none>
    Host Port:     <none>
    **Args:
      $(INTERVAL)**
    State:          Running
      Started:      Sat, 24 Dec 2022 12:11:17 +0900
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:                500m
      ephemeral-storage:  1Gi
      memory:             2Gi
    Requests:
      cpu:                500m
      ephemeral-storage:  1Gi
      memory:             2Gi
    **Environment:
      INTERVAL:  <set to the key 'sleep-interval' of config map 'fortune-config'>  Optional: false**
    Mounts:
      /var/htdocs from html (rw)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-m279x (ro)
  web-server:
    Container ID:   containerd://48d77cbf797cb803dfcc502c09d38655b2bc5a1a9b6a57b81ec8257e4497153b
    Image:          nginx:alpine
    Image ID:       docker.io/library/nginx@sha256:dd8a054d7ef030e94a6449783605d6c306c1f69c10c2fa06b66a030e0d1db793
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sat, 24 Dec 2022 12:11:19 +0900
    Ready:          True
    Restart Count:  0
    Limits:
      cpu:                500m
      ephemeral-storage:  1Gi
      memory:             2Gi
    Requests:
      cpu:                500m
      ephemeral-storage:  1Gi
      memory:             2Gi
    Environment:          <none>
    Mounts:
      /usr/share/nginx/html from html (ro)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-m279x (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  html:
    Type:       EmptyDir (a temporary directory that shares a pod's lifetime)
    Medium:
    SizeLimit:  <unset>
  kube-api-access-m279x:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   Guaranteed
Node-Selectors:              <none>
Tolerations:                 kubernetes.io/arch=amd64:NoSchedule
                             node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age   From                                   Message
  ----    ------     ----  ----                                   -------
  Normal  Scheduled  18s   gke.io/optimize-utilization-scheduler  Successfully assigned default/fortune-env-from-configmap to gk3-autopilot-cluster-1-nap-1esnt5d2-92c5f823-22pk
  Normal  Pulling    16s   kubelet                                Pulling image "luksa/fortune:args"
  Normal  Pulled     9s    kubelet                                Successfully pulled image "luksa/fortune:args" in 7.813949711s
  Normal  Created    9s    kubelet                                Created container html-generator
  Normal  Started    8s    kubelet                                Started container html-generator
  Normal  Pulling    8s    kubelet                                Pulling image "nginx:alpine"
  Normal  Pulled     6s    kubelet                                Successfully pulled image "nginx:alpine" in 2.121623096s
  Normal  Created    6s    kubelet                                Created container web-server
  Normal  Started    6s    kubelet                                Started container web-server

ConfigMap Volume을 사용해 ConfigMap 항목을 파일로 노출

파일들에 대해 Container에 노출시키기 위해 ConfigMap Volume을 이용한다. ConfigMap Volume은 파일로 ConfigMap 각 항목을 노출하고 Container에서 실행 중인 프로세스는 이 파일 내용을 읽어 각 항목의 값을 얻을 수 있다.

ConfigMap 생성

ConfigMap 생성 예제


# PWD : /Users/zayden/Documents/Work/kubernetes-repo/configmap-files
# my-nginx-config.conf
server{
    listen  80;
    server_name www.kubia-example.com;

    gzip on;
    gzip_types text/plain application/xml;

    location / {
        root    /usr/share/nginx/html;
        index   index.html index.htm;
    }
}
# PWD : /Users/zayden/Documents/Work/kubernetes-repo/configmap-files
# sleep-interval
25
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo/configmap-files  kubectl create configmap fortune-config --from-file=/Users/zayden/Documents/Work/kubernetes-repo/configmap-files
W1224 14:13:25.620836   85368 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
configmap/fortune-config created

 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo/configmap-files  kubectl get configmap fortune-config -o yaml
W1224 14:13:45.048532   85388 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
apiVersion: v1
**data:
  my-nginx-config.conf: |-
    server{
        listen  80;
        server_name www.kubia-example.com;

        gzip on;
        gzip_types text/plain application/xml;

        location / {
            root    /usr/share/nginx/html;
            index   index.html index.htm;
        }
    }
  sleep-interval: "25"**
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-24T05:13:25Z"
  name: fortune-config
  namespace: default
  resourceVersion: "3591477"
  uid: 52769c87-95bc-4360-bea5-517932e6ed19

Volume 안에 있는 ConfigMap 항목 사용

Volume 안에 있는 ConfigMap 항목 사용 예제


Nginx는 /etc/nginx/nginx.conf 파일의 설정을 읽으며, 해당 Directory 안에 있는 모든 .conf파일을 포함하기 때문에 원하는 설정 파일을 추가하면 된다.

#fortune-pod-env-configmap-volume.yml

apiVersion: v1
kind: Pod
metadata:
  name: fortune-configmap-volume
spec:
  containers:
  - image: luksa/fortune:env
    **env:
    - name: INTERVAL
      valueFrom:
        configMapKeyRef:
          name: fortune-config
          key: sleep-interval**
    name: html-generator
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    **- name: config
      mountPath: /etc/nginx/conf.d
      readOnly: true**
    - name: config
      mountPath: /tmp/whole-fortune-config-volume
      readOnly: true
    ports:
      - containerPort: 80
        name: http
        protocol: TCP
  volumes:
  - name: html
    emptyDir: {}
  - name: config
    configMap:
      name: fortune-config
# my-nginx-config.conf
server{
    listen  80;
    server_name www.kubia-example.com;

    gzip on;
    gzip_types text/plain application/xml;

    location / {
        root    /usr/share/nginx/html;
        index   index.html index.htm;
    }
}
# sleep-interval
25
# Pod 생성
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create -f fortune-pod-env-configmap-volume.yml
W1224 14:42:40.186551   85907 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
Warning: Autopilot set default resource requests for Pod default/fortune-configmap-volume, as resource requests were not specified. See http://g.co/gke/autopilot-defaults
pod/fortune-configmap-volume created

# Pod 준비 완료
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get pods
W1224 14:45:06.144248   86038 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
NAME                       READY   STATUS    RESTARTS   AGE
fortune-configmap-volume   2/2     Running   0          2m25s

# 포트 연결 설정
 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl port-forward fortune-configmap-volume 8080:80 &
[1] 86046
 ⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  W1224 14:45:09.675200   86046 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80

# CURL을 이용하여 응답을 압축
 ⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  curl -H "Accept-Encoding: gzip" -I localhost:8080
Handling connection for 8080
HTTP/1.1 200 OK
Server: nginx/1.23.3
Date: Sat, 24 Dec 2022 05:46:16 GMT
Content-Type: text/html
Last-Modified: Sat, 24 Dec 2022 05:46:06 GMT
Connection: keep-alive
ETag: W/"63a6921e-25"
Content-Encoding: gzip

# Mount 된 ConfigMap Volume 확인
 ⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl exec fortune-configmap-volume -c web-server ls /etc/nginx/conf.d
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
W1224 14:46:59.802540   86093 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
**my-nginx-config.conf
sleep-interval**

마지막 결과를 통해 두 개의 ConfigMap 항목이 모두 Directory에 파일로 추가되어 있음을 알 수 있었다.

서로 다른 두 개의 ConfigMap을 작성해 하나는 fortuneloop Container에서 사용하고 나머지는 web-server Container에서 사용하도록 할 수 있지만, 동일한 Pod에 있는 Container들은 Container가 서로 밀접한 관계를 가지고 있어 하나의 Unit으로 설정되어야 한다.

볼륨에 특정 ConfigMap 항목만 노출

apiVersion: v1
kind: Pod
metadata:
  name: fortune-configmap-volume-with-items
spec:
  containers:
  - image: luksa/fortune:env
    name: html-generator
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    - name: config
      mountPath: /etc/nginx/conf.d/
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html
    emptyDir: {}
  - name: config
    **configMap:
      name: fortune-config
      items:
      - key: my-nginx-config.conf
        path: gzip.conf**

위 예제에서 Volume을 Directory에 Mount를 진행하였다. Container의 Image 자체에 있던 /etc/nginx/conf.d Directory 내 저장된 파일을 숨겼음을 의미한다. 일반적으로 Linux에서 Filesystem을 비어 있지 않은 Directory에 Mount할 때 발생하며, 해당 Directory는 Mount한 Filesystem에 있는 File만 포함하고 원래 존재하던 File은 해당 Filesystem이 Mount되어 있는 동안 접근할 수 없다.

일반적으로 중요한 File을 포함하는 /etc Directory에 Volume을 Mount한다면, /etc Directory에 존재해야하는 모든 원본 File이 더 이상 존재하지 않기 때문에 전체 Container가 손상될 수 있다. 만약 /etc와 같은 Directory가 필요하다면 위와 같은 방법으로 진행해서는 안된다.

Directory 안에 다른 파일을 숨기지 않고 개별 ConfigMap 항목을 파일로 Mount

Untitled 1

apiVersion: v1
kind: Pod
metadata:
  name: fortune-configmap-volume-with-items
spec:
  containers:
  - image: luksa/fortune:env
    name: html-generator
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    - name: config
      **# Directory가 아닌 파일을 마운트
      mountPath: /etc/nginx/conf.d/someconfig.conf
      # 전체 Volume을 Mount하는 대신 myconfig.conf 항목만 Mount
      subPath: myconfig.conf**
      readOnly: true
    ports:
    - containerPort: 80
      protocol: TCP
  volumes:
  - name: html
    emptyDir: {}
  - name: config
    configMap:
      name: fortune-config
      items:
      - key: my-nginx-config.conf
        path: gzip.conf

myconfig.conf 파일을 포함하는 ConfigMap Volume을 갖고 있으며, 이 파일을 /etc Directory에 someconfig.conf 파일로 추가하고자 할 때 위와 같이 subPath 속성으로 Directory에 있는 다른 파일에 영향을 주지 않고 Mount 가능하다.

subPath는 모든 종류의 Volume을 Mount할 때 사용 가능하며, 일부만 Mount 가능하지만 파일 업데이트와 관련해서 결함을 가지고 있다.

ConfigMap 내 파일 권한설정

ConfigMap의 모든 파일 권한은 664(-rw-r-r—, owner는 read/write 가능하며 group과 other은 read만 가능하다)으로 설정(Default)된다.

아래 예제와 같이 DefaultMode에 대한 권한 변경 가능하다.

ConfigMap Volume 내 파일 권한 설정 예제


apiVersion: v1
kind: Pod
metadata:
  name: fortune-configmap-volume
spec:
  containers:
  - image: luksa/fortune:env
    env:
    - name: INTERVAL
      valueFrom:
        configMapKeyRef:
          name: fortune-config
          key: sleep-interval
    name: html-generator
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    - name: config
      mountPath: /etc/nginx/conf.d
      readOnly: true
    - name: config
      mountPath: /tmp/whole-fortune-config-volume
      readOnly: true
  volumes:
  - name: html
    emptyDir: {}
  - name: config
    configMap:
      name: fortune-config
      defaultMode: 6600

-rw-rw——-

Application을 재시작하지 않고 Application 설정 업데이트

환경변수 or 명령줄 인수를 설정 소스로 사용하면 프로세스가 실행되는 동안 업데이트가 불가능하지만 ConfigMap을 사용해 볼륨을 노출하면 Application 재 시작 없이 설정을 업데이트 가능하다.

ConfigMap 업데이트 시 참조하는 모든 Volume의 파일이 업데이트되며 변경되었음을 감지하고 다시 로드하는 것은 프로세스에게 달려있다.(ConfigMap 업데이트 후 파일이 업데이트 되기까지 최대 1분까지 오래 걸릴 수 있다.)

Application 재시작 없이 Application 설정 업데이트 예제


⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get pods
W1224 15:14:43.842322   86575 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
NAME                       READY   STATUS    RESTARTS   AGE
fortune-configmap-volume   2/2     Running   0          32m

#gzip off로 변경
⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl edit configmap fortune-config
W1224 16:21:28.445567   87714 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
configmap/fortune-config edited

⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl exec fortune-configmap-volume -c web-server cat /etc/nginx/conf.d/my-ng
inx-config.conf
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
W1224 16:23:47.757696   87825 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
server{
    listen  80;
    server_name www.kubia-example.com;

    **gzip off;**
    gzip_types text/plain application/xml;

    location / {
        root    /usr/share/nginx/html;
        index   index.html index.htm;
    }
}

 ⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl exec fortune-configmap-volume -c web-server -- nginx -s reload
W1224 16:24:43.944982   87846 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
2022/12/24 07:24:45 [notice] 34#34: signal process started

# 더 이상 gzip을 하지 않음
 ⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  curl -H "Accept-Encoding: gzip" -I localhost:8080
Handling connection for 8080
HTTP/1.1 200 OK
Server: nginx/1.23.3
Date: Sat, 24 Dec 2022 07:24:58 GMT
Content-Type: text/html
Content-Length: 269
Last-Modified: Sat, 24 Dec 2022 07:24:53 GMT
Connection: keep-alive
ETag: "63a6a945-10d"
Accept-Ranges: bytes

파일이 한 번에 업데이트 되는 방법의 이해

 ⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl exec -it fortune-configmap-volume -c web-server -- ls -lA /etc/nginx/conf
.d
W1224 16:51:04.652442   88191 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
total 4
drwxr-xr-x    2 root     root          4096 Dec 24 07:22 ..2022_12_24_07_22_31.2271819884
lrwxrwxrwx    1 root     root            32 Dec 24 07:22 ..data -> ..2022_12_24_07_22_31.2271819884
lrwxrwxrwx    1 root     root            27 Dec 24 05:44 my-nginx-config.conf -> ..data/my-nginx-config.conf
lrwxrwxrwx    1 root     root            21 Dec 24 05:44 sleep-interval -> ..data/sleep-interval

Mount된 ConfigMap Volume 안의 파일 → ..data Directory의 파일

..data Directory →..2022_12_24_07_22_31.2271819884 Directory

Mount 된 ConfigMap Volume의 모든 파일을 조회하면 Mount된 ConfigMap Volume 안의 파일은 ..data Directory의 파일을 가리키는 심볼릭 링크이다. ..data Directory또한 ..2022_12_24_07_22_31.2271819884 Directory를 가리키는 심볼릭 링크이다. ConfigMap이 업데이트 되면 Kubernetes는 새로운 Directory를 생성하고 모든 파일을 새로운 Directory에 쓴 이후 ..data 심볼릭 링크가 새로운 Directory를 가리키도록 하여 모든 파일을 효과적으로 한 번에 변경한다.

이미 존재하는 Directory에 파일 만 Mount 했을 때 업데이트가 되지 않는 것 이해

(subPath)전체 Volume 대신 단일 파일을 Container에 Mount한 경우에는 파일이 업데이트 되지 않는다. 이를 해결하는 방법은 전체 Volume을 다른 Directory로 Mount한 다음 해당 파일을 가리키는 심볼릭 링크를 생성하는 것이다.

ConfigMap 업데이트 결과 이해

Container의 가장 중요한 기능은 불변성인데, Container를 실행하는데 사용되는 ConfigMap을 수정해 불변성을 우회하는 것은 잘못된 것인지 생각해볼 필요가 있다.

Application이 설정을 다시 읽는 기능을 지원하지 않을 때 서로 다른 설정을 가진 Instance가 실행되는 결과를 초래한다.(ConfigMap을 변경한 이후에 생성된 Pod는 새로운 설정을 사용하지만 예전 Pod는 예전 설정을 사용한다.) 따라서 Application이 설정을 자동으로 다시 읽는 기능을 가지고 있지 않다면, 이미 존재하는 ConfigMap을 Pod가 사용하는 동안에 수정하는 것은 좋은 방법이 아니다.

Application이 다시 읽기(Reloading)를 지원한다면 ConfigMap을 수정하는 것은 문제가 되지 않지만 ConfigMap Volume의 파일이 실행 중인 모든 Instance에 걸쳐서 동기적으로 업데이트 되지 않기에 개별 Pod의 파일은 최대 1분 동안 동기화 되지 않은 상태로 있을 수 있다.

7.5 시크릿으로 민감한 데이터를 Container에 전달

설정 안에는 보안이 유지되어야 하는 자격증명과 개인 암호화 Key와 같은 민감한 정보도 포함되어 있다.

시크릿(민감한 정보를 보관하고 배포하기 위해 제공하는 별도 오브젝트, Key-Value 쌍을 가진 Map으로 ConfigMap과 유사)

Kubernetes는 시크릿에 접근해야 하는 Pod가 실행되는 있는 노드에만 개별 시크릿을 배포해 시크릿을 안전하게 유지한다. 노드 자체적으로 시크릿을 항상 메모리에만 저장되게 하고 물리 저장소에 기록되지 않도록 한다.(물리 저장소는 시크릿을 삭제한 후에도 Disk를 완전히 삭제(wiping)하는 작업이 필요하기 때문에)

Master Node(etcd)에는 시크릿을 암호화되지 않은 형식으로 저장하므로 시크릿에 저장한 민감한 데이터를 보호하려면 Master Node를 보호하는 것이 필요하다.(etcd 저장소를 안전하게 하는 것 + 권한 없는 사용자가 API서버를 이용하지 못하게 하는 것, Pod를 만들 수 잇는 사람은 누구나 시크릿을 Pod에 Mount하고 민감한 데이터에 접근하는 것이 가능하기 때문에, Kubernetes version 1.7부터 etcd가 시크릿을 암호화된 형태로 저장) 따라서, 언제 시크릿을 사용할지, ConfigMap을 사용할지 올바르게 선택하는 것이 필요하다.

기본 Token 시크릿

모든 Pod에는 secret Volume이 자동으로 연결되어 있다.(?) (기본적으로 default-token 시크릿은 모든 Container에 Mount 되지만, Pod Spec 안에 automountService-AccountToken 필드 값을 false로 지정하거나 파드가 사용하는 서비스 어카운트를 false로 지정해 비활성화 가능하다.)

# 내 시크릿 어디갔지..(?)
⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get secrets
W1224 17:33:25.057938   88886 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
No resources found in default namespace.

시크릿이 갖고 있는 세 가지 항목(ca.crt, namespace, token)은 Pod 안에서 Kubernetes API 서버와 통신할 때 필요한 모든 것을 나타내며, 이상적으로 Application이 완전히 Kubernetes를 모르도록 하고 싶지만 Kubernetes와 직접적인 대화 외에 대안이 없으면 secret Volume을 통해 제공된 파일을 사용한다.

Untitled 2

 ⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get pods
W1224 17:48:33.418106   89157 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
NAME                       READY   STATUS    RESTARTS   AGE
fortune-configmap-volume   2/2     Running   0          3h5m

 ⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl exec fortune-configmap-volume ls /var/run/secrets/kubernetes.io/serviceaccount/
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
W1224 17:48:44.613519   89170 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
Defaulted container "html-generator" out of: html-generator, web-server
**ca.crt
namespace
token**

시크릿 생성

시크릿 생성 예제


Nginx Container가 HTTPS 트래픽을 제공할 수 있도록 개선한다. 인증서와 개인 키가 필요하며, 안전하게 유지 가능하도록 시크릿에 넣는다.

# 개인 키와 인증서 파일 생성
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  openssl genrsa -out https.key 2048
Generating RSA private key, 2048 bit long modulus
.......................................................................................................................................................................+++++
..............................................................................+++++
e is 65537 (0x10001)

zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  openssl req -new -x509 -key https.key -out https.cert -days 3650 -subj /CN=www.kubi
a-example.com

# foo라는 더미 파일 안에 bar를 저장
 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  echo bar > foo

# fortune-https 라는 Generic 시크릿 생성, https.key 항목과 https.cert 키 그리고 파일
 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create secret generic fortune-https --from-file=https.key --from-file=https
.cert --from-file=foo
W1224 18:31:52.474839   89512 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
secret/fortune-https created

# 생성 확인
 zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get secrets
W1224 18:32:42.208721   89530 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
NAME            TYPE     DATA   AGE
fortune-https   Opaque   3      49s

시크릿의 3 가지 유형

*kubectl create secret tls 명령어를 통해 tls 시크릿 생성 가능

ConfigMap과 시크릿 비교

시크릿 YML 정의

zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get secret fortune-https -o yaml
W1224 19:14:06.049055   89795 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
apiVersion: v1
**data:
  foo: YmFyCg==
  https.cert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN2RENDQWFRQ0NRRHkvcG8vTy9yd2lEQU5CZ2txaGtpRzl3MEJBUXNGQURBZ01SNHdIQVlEVlFRRERCVjMKZDNjdWEzVmlhV0V0WlhoaGJYQnNaUzVqYjIwd0hoY05Nakl4TWpJME1Ea3pNRE0zV2hjTk16SXhNakl4TURregpNRE0zV2pBZ01SNHdIQVlEVlFRRERCVjNkM2N1YTNWaWFXRXRaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHClNJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURKN0FpdUo5UlhFcHo3ellUdTErWE9qbEVTd2Q5akRxUFEKUy9Tc3hvN2E4T2Zsei9zNllkMEVTTEp6bzB5S2k1dm9UYnIreDRJbm5BS2tEc3NyTDB0VVZNT0p2ZldqRVV4dQptTGVENklmNDBzZlp4VW12Sm9YS3cvVDZuOW9mbW0rYURUZnZMdGhtUTJvRXpVQjdla1VPekJESlpjaGI2NGxGCjhWUlRIcmlJK282alJmUUZQazNRTVFWL2V0bzJpdE4wZXBnRUwxS0ZaNTNUQXdMdEU1bEFrbWdpWkE1VWpoTWoKVHFGZXJLY0FFTExaVU43cHVYbHB6WWZFcy9JcEVXenE1emF6WFJlUFZ3ZFFpTWY0WWZ1ZkwvS0NwRGlQRVd6Nwo3N2VNWmxyMDd0QlEvVmxWVW9GK0JBc3o5Ymc0OFVaalhyV0xjaDQ5QXNRR21jdm5KUWxaQWdNQkFBRXdEUVlKCktvWklodmNOQVFFTEJRQURnZ0VCQUR6QkJuOVBCVFhpM1dDRnUvWnBUVzU1UHFQUGNvajlVRnJpN21rWkJvd0kKOExjWUhDRm8vN1hybTh3dk16REVJT1N3L3VOclJQNmo5VWhNK1FWOCt1emVWREpJK3FFeER3Vkw2dTlWMmhINAp5ZnZIVHRtNWFMWUhGazRGajRON283WmpyZXNqVmMyZCtzck44UFZFVzRWRWx0cWZqcS9RaXB4K0xFMGxQd0dGClF2ODI5NnhENGFTYWlxQjViaEx3WmVkKy96T1A5S1BhZzVVSm5DUlU4Q0pzTTNOS3VKbE9zSmtDQjJOWDREcWYKYXFGMGk4MTdydDdNWDg5Q1EvNUMzT1RFQjFuK2xpSVY2SGlLZCtRc1IzOXVIdTREMHBmc2tha1p2cmd5RmNwUQpMZ1hEdVZZenVJWko3MmFENWt0S2txdVllRzlyUTUvVE5PeU5jOTQrRUZRPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
  https.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBeWV3SXJpZlVWeEtjKzgyRTd0Zmx6bzVSRXNIZll3NmowRXYwck1hTzJ2RG41Yy83Ck9tSGRCRWl5YzZOTWlvdWI2RTI2L3NlQ0o1d0NwQTdMS3k5TFZGVERpYjMxb3hGTWJwaTNnK2lIK05MSDJjVkoKcnlhRnlzUDArcC9hSDVwdm1nMDM3eTdZWmtOcUJNMUFlM3BGRHN3UXlXWElXK3VKUmZGVVV4NjRpUHFPbzBYMApCVDVOMERFRmYzcmFOb3JUZEhxWUJDOVNoV2VkMHdNQzdST1pRSkpvSW1RT1ZJNFRJMDZoWHF5bkFCQ3kyVkRlCjZibDVhYzJIeExQeUtSRnM2dWMyczEwWGoxY0hVSWpIK0dIN255L3lncVE0anhGcysrKzNqR1phOU83UVVQMVoKVlZLQmZnUUxNL1c0T1BGR1kxNjFpM0llUFFMRUJwbkw1eVVKV1FJREFRQUJBb0lCQURkdjV6NHhUem9Nc1M3cwowUWRtSFFEbHo5cHZnZTVIVWJCWmVqYUpXU1ZCS05uT2pUSU5Oa243ejRxeUZjeWY0ZEVZcmpOUEFTdnd5RVRVCmp2RXZUZVk4VTJjWTBUelEvZ1FMUjY4ZWcxNU1PSFJRbHhkUVkwRTFKYWc5aFB4U1FUdXhUMThLcEgwSEd5OXcKVHJqWDYrZlJIUGErVEJENGpMcTROQ2VSOHFZZ2IyVG95VUc3dDdvZ01FZ1VVZ3Jrc1pDTzFRY2NEeDRrSVRYVgo0K0QzNm9sa0JBK2VadEx0QWR4ZnYySWNBQVlYQllKcjVXYkJnNVVaRU83d2JFbkx6SG5sai9LVUl4QS9yeXJPCmVsTEpzaUpsVFd1YzZYdHN1VjVCYzFNbzdzeUllSUE5R1QvSDZMeHlMbVVSMHZNS1d1SGU3T0x0Mit0TnY4LysKYmp1UGtNVUNnWUVBNi9lcnJ2bEo4M0l1NmJpemh0K0xhRGt6NjM3Nmpud0YyTURKMmJEeVdnTUdmT25OVEpNKwp5bXFLMHBWOHNRbUtyekxzVWg4TGN5MGk3UlI4Q1VrN2ZRb2FtZlk4dW9sUzljZldlOWF6cXRWZWgvUFZ3L0UrClJpVVhqaFhwaklickNQZmxzWTJ5S1BtZ0svdGhHTzVWaU9IMlNkZTRBZ3RObU1BQitxWm1aK3NDZ1lFQTJ4QnkKUmV2aXNKYnk2L1FEcWVtbG52bHNvN013WVdEb1ZMY1FpMzVuMmlsOTVlZXlrTm1EZGRVZ1dUbFcyNHB2UVd1cgpSMVkyYThrMms1TUw0c0RZcmRuNEttY01HNjhsRWlyUUJHOGk5TERYbEZpUXh1Qm9ZN3Y4Sm1HR3dJMFI4dlhSCkczUUI4TmxDaGp5d2M1Sk1OVXpMNEV6ekJmZlZlb2NyV3lKYlpzc0NnWUVBMmVoQThuZWg5Q0FvOUlzdHRzcXYKYVpNUndGTGx2VGtKQ1M2WCtPRndIUEdZUnpoOTcwNDIrU1JFaU0ybGRiUHpEM0crVE9RQVpkOXoxbTVKVVNZQQp1cXJlLy9rbUFia1pGSUgwTHk2SmdxUkNCTmlIT3NpSWtxeGtRVUU1Q1IzNjVMQlF2Sk8yeUNJbDZSZmVoZkJxCnF0ckkzMDVIemhOMEdEQ1FZMURSVnZzQ2dZRUF0MlV6WmRvdk5BdUxYNEl2dHdZR1Erc295bnR2VzNiWHltUmcKRTRoRnhWekxLN2dueENCMWNDWjNLSHRhZmYyTldzV2E1T1FHTjRLQ2tGV2dzN3NqSzVpNXJEWU02dmhjSHJOOAo1dGxyK0ZJOGlOTUVrWnE1aWhXTTZVem9sVGNFK2RSVnRaZ1BMK1dUVGZKcy9yUlIzS1ZvWVdYS1p3cXV6Qjl4CmFxQit5TFVDZ1lCWGpiVHpXMVlXdWRRa3hkTnFCTi9ETHBBWitLV3Yxa3RLKzlRd2xIdCtSQjl3ZWRBVGVtaloKcS81REtrWDErMlY5TjZ4UktvZ1NXQnVDWHZwajB5WkthQ2ZUdjZuZ0wxSVhoeDZpSDh4aCtiakIxMEpjeENtRwpDaUVXMWw0OVJFeWlZVmdyU28yWEdiNVNDbFVPekFQTGJuOWJUSUV0ZEpUSTZoZkJmQ21SM3c9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=**
**kind: Secret**
metadata:
  creationTimestamp: "2022-12-24T09:31:53Z"
  name: fortune-https
  namespace: default
  resourceVersion: "3764826"
  uid: ed8a58f1-e509-42ea-b1ff-c9e2977d9736
type: Opaque

ConfigMap YML 정의

zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get configmap fortune-config -o yaml
W1224 19:14:36.838349   89811 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
apiVersion: v1
**data:
  my-nginx-config.conf: |-
    server{
        listen  80;
        server_name www.kubia-example.com;

        gzip off;
        gzip_types text/plain application/xml;

        location / {
            root    /usr/share/nginx/html;
            index   index.html index.htm;
        }
    }
  sleep-interval: "25"
kind: ConfigMap**
metadata:
  creationTimestamp: "2022-12-24T05:13:25Z"
  name: fortune-config
  namespace: default
  resourceVersion: "3677859"
  uid: 52769c87-95bc-4360-bea5-517932e6ed19

Binary data 시크릿 사용

일반 텍스트 뿐만 아니라 Binary data도 담기 위해 Base64 인코딩을 사용한다.(Base64로 인코딩하면 Binary data를 일반 텍스트 형식인 YAML or JSON에 넣을 수 있다.)

*시크릿의 최대 크기는 1MB로 제한되기 때문에 필요한 데이터만 시크릿을 사용한다.

stringData 필드

모든 민감한 데이터가 Binary 형태가 아니기에 시크릿 값을 stringData필드로 설정할 수 있게 해준다.

apiVersion: v1
kind: Secret
metadata:
  name: fortune-https
type: Opaque
**stringData:
  foo: plain text**
data:
  foo: YmFyCg==
  https.cert: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN2RENDQWFRQ0NRRHkvcG8vTy9yd2lEQU5CZ2txaGtpRzl3MEJBUXNGQURBZ01SNHdIQVlEVlFRRERCVjMKZDNjdWEzVmlhV0V0WlhoaGJYQnNaUzVqYjIwd0hoY05Nakl4TWpJME1Ea3pNRE0zV2hjTk16SXhNakl4TURregpNRE0zV2pBZ01SNHdIQVlEVlFRRERCVjNkM2N1YTNWaWFXRXRaWGhoYlhCc1pTNWpiMjB3Z2dFaU1BMEdDU3FHClNJYjNEUUVCQVFVQUE0SUJEd0F3Z2dFS0FvSUJBUURKN0FpdUo5UlhFcHo3ellUdTErWE9qbEVTd2Q5akRxUFEKUy9Tc3hvN2E4T2Zsei9zNllkMEVTTEp6bzB5S2k1dm9UYnIreDRJbm5BS2tEc3NyTDB0VVZNT0p2ZldqRVV4dQptTGVENklmNDBzZlp4VW12Sm9YS3cvVDZuOW9mbW0rYURUZnZMdGhtUTJvRXpVQjdla1VPekJESlpjaGI2NGxGCjhWUlRIcmlJK282alJmUUZQazNRTVFWL2V0bzJpdE4wZXBnRUwxS0ZaNTNUQXdMdEU1bEFrbWdpWkE1VWpoTWoKVHFGZXJLY0FFTExaVU43cHVYbHB6WWZFcy9JcEVXenE1emF6WFJlUFZ3ZFFpTWY0WWZ1ZkwvS0NwRGlQRVd6Nwo3N2VNWmxyMDd0QlEvVmxWVW9GK0JBc3o5Ymc0OFVaalhyV0xjaDQ5QXNRR21jdm5KUWxaQWdNQkFBRXdEUVlKCktvWklodmNOQVFFTEJRQURnZ0VCQUR6QkJuOVBCVFhpM1dDRnUvWnBUVzU1UHFQUGNvajlVRnJpN21rWkJvd0kKOExjWUhDRm8vN1hybTh3dk16REVJT1N3L3VOclJQNmo5VWhNK1FWOCt1emVWREpJK3FFeER3Vkw2dTlWMmhINAp5ZnZIVHRtNWFMWUhGazRGajRON283WmpyZXNqVmMyZCtzck44UFZFVzRWRWx0cWZqcS9RaXB4K0xFMGxQd0dGClF2ODI5NnhENGFTYWlxQjViaEx3WmVkKy96T1A5S1BhZzVVSm5DUlU4Q0pzTTNOS3VKbE9zSmtDQjJOWDREcWYKYXFGMGk4MTdydDdNWDg5Q1EvNUMzT1RFQjFuK2xpSVY2SGlLZCtRc1IzOXVIdTREMHBmc2tha1p2cmd5RmNwUQpMZ1hEdVZZenVJWko3MmFENWt0S2txdVllRzlyUTUvVE5PeU5jOTQrRUZRPQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tCg==
  https.key: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBeWV3SXJpZlVWeEtjKzgyRTd0Zmx6bzVSRXNIZll3NmowRXYwck1hTzJ2RG41Yy83Ck9tSGRCRWl5YzZOTWlvdWI2RTI2L3NlQ0o1d0NwQTdMS3k5TFZGVERpYjMxb3hGTWJwaTNnK2lIK05MSDJjVkoKcnlhRnlzUDArcC9hSDVwdm1nMDM3eTdZWmtOcUJNMUFlM3BGRHN3UXlXWElXK3VKUmZGVVV4NjRpUHFPbzBYMApCVDVOMERFRmYzcmFOb3JUZEhxWUJDOVNoV2VkMHdNQzdST1pRSkpvSW1RT1ZJNFRJMDZoWHF5bkFCQ3kyVkRlCjZibDVhYzJIeExQeUtSRnM2dWMyczEwWGoxY0hVSWpIK0dIN255L3lncVE0anhGcysrKzNqR1phOU83UVVQMVoKVlZLQmZnUUxNL1c0T1BGR1kxNjFpM0llUFFMRUJwbkw1eVVKV1FJREFRQUJBb0lCQURkdjV6NHhUem9Nc1M3cwowUWRtSFFEbHo5cHZnZTVIVWJCWmVqYUpXU1ZCS05uT2pUSU5Oa243ejRxeUZjeWY0ZEVZcmpOUEFTdnd5RVRVCmp2RXZUZVk4VTJjWTBUelEvZ1FMUjY4ZWcxNU1PSFJRbHhkUVkwRTFKYWc5aFB4U1FUdXhUMThLcEgwSEd5OXcKVHJqWDYrZlJIUGErVEJENGpMcTROQ2VSOHFZZ2IyVG95VUc3dDdvZ01FZ1VVZ3Jrc1pDTzFRY2NEeDRrSVRYVgo0K0QzNm9sa0JBK2VadEx0QWR4ZnYySWNBQVlYQllKcjVXYkJnNVVaRU83d2JFbkx6SG5sai9LVUl4QS9yeXJPCmVsTEpzaUpsVFd1YzZYdHN1VjVCYzFNbzdzeUllSUE5R1QvSDZMeHlMbVVSMHZNS1d1SGU3T0x0Mit0TnY4LysKYmp1UGtNVUNnWUVBNi9lcnJ2bEo4M0l1NmJpemh0K0xhRGt6NjM3Nmpud0YyTURKMmJEeVdnTUdmT25OVEpNKwp5bXFLMHBWOHNRbUtyekxzVWg4TGN5MGk3UlI4Q1VrN2ZRb2FtZlk4dW9sUzljZldlOWF6cXRWZWgvUFZ3L0UrClJpVVhqaFhwaklickNQZmxzWTJ5S1BtZ0svdGhHTzVWaU9IMlNkZTRBZ3RObU1BQitxWm1aK3NDZ1lFQTJ4QnkKUmV2aXNKYnk2L1FEcWVtbG52bHNvN013WVdEb1ZMY1FpMzVuMmlsOTVlZXlrTm1EZGRVZ1dUbFcyNHB2UVd1cgpSMVkyYThrMms1TUw0c0RZcmRuNEttY01HNjhsRWlyUUJHOGk5TERYbEZpUXh1Qm9ZN3Y4Sm1HR3dJMFI4dlhSCkczUUI4TmxDaGp5d2M1Sk1OVXpMNEV6ekJmZlZlb2NyV3lKYlpzc0NnWUVBMmVoQThuZWg5Q0FvOUlzdHRzcXYKYVpNUndGTGx2VGtKQ1M2WCtPRndIUEdZUnpoOTcwNDIrU1JFaU0ybGRiUHpEM0crVE9RQVpkOXoxbTVKVVNZQQp1cXJlLy9rbUFia1pGSUgwTHk2SmdxUkNCTmlIT3NpSWtxeGtRVUU1Q1IzNjVMQlF2Sk8yeUNJbDZSZmVoZkJxCnF0ckkzMDVIemhOMEdEQ1FZMURSVnZzQ2dZRUF0MlV6WmRvdk5BdUxYNEl2dHdZR1Erc295bnR2VzNiWHltUmcKRTRoRnhWekxLN2dueENCMWNDWjNLSHRhZmYyTldzV2E1T1FHTjRLQ2tGV2dzN3NqSzVpNXJEWU02dmhjSHJOOAo1dGxyK0ZJOGlOTUVrWnE1aWhXTTZVem9sVGNFK2RSVnRaZ1BMK1dUVGZKcy9yUlIzS1ZvWVdYS1p3cXV6Qjl4CmFxQit5TFVDZ1lCWGpiVHpXMVlXdWRRa3hkTnFCTi9ETHBBWitLV3Yxa3RLKzlRd2xIdCtSQjl3ZWRBVGVtaloKcS81REtrWDErMlY5TjZ4UktvZ1NXQnVDWHZwajB5WkthQ2ZUdjZuZ0wxSVhoeDZpSDh4aCtiakIxMEpjeENtRwpDaUVXMWw0OVJFeWlZVmdyU28yWEdiNVNDbFVPekFQTGJuOWJUSUV0ZEpUSTZoZkJmQ21SM3c9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=

stringData 필드는 쓰기 전용이며, 값을 설정할 때만 사용 가능하다. kubectl get -o yaml 명령으로 시크릿의 YAML 정의를 가져올 때 stringData필드는 표시되지 않는다. 대신 stringData 필드로 지정한 모든 항목은 data 항목 아래 다른 모든 항목처럼 Base64로 인코딩되어 표시된다.

Pod에서 시크릿 항목 읽기

secret Volume을 통해 시크릿을 Container에 노출하면 시크릿 항목의 값이 디코딩되어 파일에 기록된다. (환경변수로 시크릿 항목을 노출할 때도) Application은 디코딩 할 필요없이 파일 내용을 읽거나 환경변수 값을 찾아 직접 이용 가능하다.

Pod에서 시크릿 사용

파드에서 시크릿 사용 예제


인증서와 키 파일을 모두 포함하는 fortune-https 시크릿을 Nginx에서 사용할 수 있도록 한다.

HTTPS 활성화를 위한 ‘fortune-config’ ConfigMap 수정

zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl edit configmap fortune-config
W1224 19:58:24.493313   90562 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
configmap/fortune-config edited
apiVersion: v1
data:
  my-nginx-config.conf: |-
    server{
        listen                  80;
        listen                  443 ssl;
        server_name             www.kubia-example.com;
        ssl_certificate         certs/https.cert;
        ssl_certificate_key     certs/https.key;
        ssl_protocols           TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers             HIGH:!aNULL:!MD5;
        location / {
            root    /usr/share/nginx/html;
            index   index.html index.htm;
        }
    }
  sleep-interval: "25"
kind: ConfigMap
metadata:
  creationTimestamp: "2022-12-24T05:13:25Z"
  name: fortune-config
  namespace: default
  resourceVersion: "3677859"
  uid: 52769c87-95bc-4360-bea5-517932e6ed19

/etc/nginx/certs 경로에 대한 secret Volume Mount 설정

# fortune-pod-https.yaml
apiVersion: v1
kind: Pod
metadata:
  name: fortune-https
spec:
  containers:
  - image: luksa/fortune:env
    name: html-generator
    env:
    - name: INTERVAL
      valueFrom: 
        configMapKeyRef:
          name: fortune-config
          key: sleep-interval
    volumeMounts:
    - name: html
      mountPath: /var/htdocs
  - image: nginx:alpine
    name: web-server
    **volumeMounts:**
    - name: html
      mountPath: /usr/share/nginx/html
      readOnly: true
    - name: config
      mountPath: /etc/nginx/conf.d
      readOnly: true
    **- name: certs
      mountPath: /etc/nginx/certs/
      readOnly: true**
    ports:
    - containerPort: 80
    - containerPort: 443
  volumes:
  - name: html
    emptyDir: {}
  - name: config
    configMap:
      name: fortune-config
      items:
      - key: my-nginx-config.conf
        path: https.conf
  **- name: certs
    secret:
      secretName: fortune-https #fortune-https 시크릿을 참조하도록 시크릿 볼륨을 정의**

Untitled

Nginx가 시크릿의 인증서와 키를 사용하는지 확인

# Pod 생성
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create -f fortune-pod-https.yml
W1224 20:28:58.338084   91072 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
Warning: Autopilot set default resource requests for Pod default/fortune-https, as resource requests were not specified. See http://g.co/gke/autopilot-defaults
pod/fortune-https created

# Pod 확인
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get pods
W1224 20:30:56.146105   91153 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
NAME            READY   STATUS    RESTARTS   AGE
fortune-https   2/2     Running   0          113s

# Port Forwarding
zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl port-forward fortune-https 8443:443 &
[1] 91165
 ⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  W1224 20:31:20.355441   91165 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
Forwarding from 127.0.0.1:8443 -> 443
Forwarding from [::1]:8443 -> 443

# CURL Test
⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  curl https://localhost:8443 -k -v
*   Trying 127.0.0.1:8443...
* Connected to localhost (127.0.0.1) port 8443 (#0)
Handling connection for 8443
* ALPN: offers h2
* ALPN: offers http/1.1
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (IN), TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES256-GCM-SHA384
* ALPN: server accepted http/1.1
*** Server certificate:  #시크릿에 생성한 인증서와 일치
*  subject: CN=www.kubia-example.com
*  start date: Dec 24 09:30:37 2022 GMT
*  expire date: Dec 21 09:30:37 2032 GMT
*  issuer: CN=www.kubia-example.com
*  SSL certificate verify result: self signed certificate (18), continuing anyway.**
> GET / HTTP/1.1
> Host: localhost:8443
> User-Agent: curl/7.84.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: nginx/1.23.3
< Date: Sat, 24 Dec 2022 11:32:11 GMT
< Content-Type: text/html
< Content-Length: 178
< Last-Modified: Sat, 24 Dec 2022 11:32:05 GMT
< Connection: keep-alive
< ETag: "63a6e335-b2"
< Accept-Ranges: bytes
<
A hundred years from now it is very likely that [of Twain's works] "The
Jumping Frog" alone will be remembered.
        -- Harry Thurston Peck (Editor of "The Bookman"), January 1901.
* Connection #0 to host localhost left intact

시크릿 Volume을 메모리에 저장하는 이유

secret Volume은 시크릿 파일을 저장하는 데 인메모리 파일시스템(tmpfs)를 사용한다.

⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl exec fortune-https -c web-server -- mount | grep certs
W1224 20:38:11.889542   91311 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
**tmpfs on /etc/nginx/certs type tmpfs (ro,relatime,size=4194304k)**

tmpfs를 사용하는 이유는 민감한 데이터를 노출시킬 수도 있는 디스크에 저장하지 않기 위해서 이다.

환경변수로 시크릿 항목 노출

env:
    - name: FOO_SECRET
      valueFrom: # 변수는 시크릿 항목에서 설정
        secretKeyRef:
          key: foo            #노출할 시크릿의 Key 이름
          name: fortune-https #Key를 가지고 있는 시크릿 이름

INTERVAL 환경변수와 설정하는 것이 유사하다. configMapKeyRef 대신 secretKeyRef를 사용해 시크릿을 참조하는 것이 다르다.

Kubernetes에서 시크릿을 환경변수로 노출할 수 있게 해주지만 Application은 일반적으로 오류 보고서에 환경변수를 기록하거나 시작하면서 로그에 환경변수를 남겨 시크릿을 노출할 수 있기에 가장 좋은 방법은 아니다. 또한 자식 프로세스는 상위 프로세스의 모든 환경변수를 상속받는데, Application이 타사(서드파티:third-party) Binary를 실행할 경우 시크릿 데이터가 어떻게 사용되는지 알 수 있는 방법이 없다.

*안전을 위해서 시크릿을 노출할 때는 항상 secret Volume을 사용한다.

이미지를 가져올 때 사용하는 시크릿

Kubernetes에서 자격증명을 전달하는 것이 필요할 때(private container image registry를 사용하려는 경우) 시크릿이 사용된다.

대부분의 조직은 자신들의 이미지를 모든 사람들이 사용하는 것을 원치 않기 때문에 private image registry를 사용한다. Pod 배포 시 container image가 private registry 안에 있다면 Kubernetes는 이미지를 가져오기 위해 필요한 자격증명을 알아야한다.

Docker Hub에서 private image 사용

http://hub.docker.com 에 로그인 후 원하는 저장소를 찾아 private용으로 표시 가능하다.

Docker Registry 인증을 위한 시크릿 생성

⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create secret docker-registry mydockerhubsecret \
> --docker-username=seojeonghyeon0630 --docker-password=PASSWORD \
> --docker-email=seojeonghyeon0630@gmail.com
W1224 21:11:54.704976   91909 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
secret/mydockerhubsecret created

 ⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get secrets
W1224 21:12:07.439425   91918 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
NAME                TYPE                             DATA   AGE
fortune-https       Opaque                           3      160m
**mydockerhubsecret   kubernetes.io/dockerconfigjson   1      13s**

generic 시크릿과 다르게 docker-registry형식을 가진다.

Pod 정의에서 Docker Registry 시크릿 사용

Pod 정의에서 Docker Registry 시크릿 사용 예제


#pod-with-private-image.yml
apiVersion: v1
kind: Pod
metadata:
  name: private-pod
spec:
  **imagePullSecrets:
  - name: mydockerhubsecret
  containers:
  - image: seojeonghyeon0630/coffeeorderservice-eurekaservice:0.0.1**
    name: main
⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl create -f pod-with-private-image.yml
W1224 21:17:15.743806   92027 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
Warning: Autopilot set default resource requests for Pod default/private-pod, as resource requests were not specified. See http://g.co/gke/autopilot-defaults
**pod/private-pod created**

 ⚙ zayden@Zaydenui-MacBookPro  ~/Documents/Work/kubernetes-repo  kubectl get pods
W1224 21:17:23.581181   92036 gcp.go:119] WARNING: the gcp auth plugin is deprecated in v1.22+, unavailable in v1.26+; use gcloud instead.
To learn more, consult https://cloud.google.com/blog/products/containers-kubernetes/kubectl-auth-changes-in-gke
NAME            READY   STATUS    RESTARTS   AGE
fortune-https   2/2     Running   0          48m
**private-pod     0/1     Pending   0          7s**

모든 Pod에서 이미지를 가져올 때 사용할 시크릿을 모두 지정할 필요 없다.

서비스 어카운트에 시크릿을 추가해 이미지를 가져올 때 자동으로 시크릿이 추가될 수 있게 가능하다.

seojeonghyeon commented 1 year ago

끝!