학습일지/kubernetes

Kubernetes Deep Dive - (4). Pods and Containers

inspirit941 2021. 9. 26. 09:12
반응형

Pods / Containers in k8s

스크린샷 2021-08-23 오후 7 39 22

스크린샷 2021-08-23 오후 8 22 13

Manage Application Configuration in k8s

스크린샷 2021-08-23 오후 8 24 01

일반적으로 Application의 Config는 Dynamical하게 관리되는 경우가 많음.

k8s의 경우 runtime 시점에서 config을 자유롭게 변경해서 적용할 수 있도록 지원하고 있다.

스크린샷 2021-08-23 오후 8 25 31

  • Non-sensitive : 토큰이나 auth key 등 confidential을 제외한 데이터들
  • ConfigMap과 pods / containers는 M:N 관계. 숫자나 범위 제한 없이 자유롭게 매핑이 가능하다.

스크린샷 2021-08-23 오후 8 28 04

스크린샷 2021-08-23 오후 8 45 54

  • secret 파일 생성에 쓰인 username.txt와 password.txt는 secret을 생성한 뒤에는 서버에서 삭제해도 된다. Secret 객체가 encoded username / password 값을 가지고 있기 때문.

스크린샷 2021-08-23 오후 8 47 41

스크린샷 2021-08-23 오후 8 48 39

Container에는 Env 환경변수 형태로 적용할 수 있다. 위 사진에서

  • 컨테이너에서 사용할 환경변수의 이름은 SPECIAL_LEVEL_KEY
  • configMap object의 이름은 name 필드 (special-config)
  • configMap에서 읽어들일 key-value pair에서 key값: special-how.

즉 runtime에서 special-config라는 이름의 ConfigMap 객체를 참조한 뒤, special-how라는 key값을 읽어들인다. 해당 key값에 대응되는 value가 SPECIAL_LEVEL_KEY에 저장된다.

스크린샷 2021-08-24 오전 9 41 11


Hands-On: ConfigMap, Secret

configMap.yaml 파일을 생성하고,

  • kubectl apply -f configMap.yaml로 객체 생성
  • kubectl get configmaps 로 생성한 객체를 확인한다.
  • kubectl describe configmap <이름> 으로 특정 configMap의 상세내용을 확인할 수 있다.
apiVersion: v1
kind: ConfigMap
metadata:
  name: player-pro-demo # ConfigMap 이름.
data:
  # property-like keys; each key maps to a simple value
  # key-value 형태.
  player_lives: "5"
  properties_file_name: "user-interface.properties"

  # file-like keys
  base.properties: | # pipe는 multiple key를 정의하기 위한 형태.
    enemy.types=aliens,monsters
    player.maximum-lives=10   
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true  

스크린샷 2021-08-24 오전 10 41 37

user-interface.properties가 key인 경우 multiple values, 마찬가지로 base.properties에도 multiple values가 할당되어 있는 걸 볼 수 있다.

Secret의 형식은 대략 아래와 같다.

apiVersion: v1
kind: Secret
metadata:
  name: example-secret
type: Opaque
stringData:
  username: YWRtaW4=
  password: YWRtaW5wYXNzd29yZA==
  • Secret에도 여러 가지 Type이 있음.
  • 예시에서는 username, password를 string으로 직접 입력했지만, 이 방법은 그리 권장하지 않음. 여기에는 base64로 인코딩된 값이 들어가는 게 좋다.
    • echo -n 'admin' | base64 -> YWRtaW4=
    • echo -n 'adminpassword' | base64 -> YWRtaW5wYXNzd29yZA==
  • kubectl apply -f secret.yaml로 등록하고, kubectl get secrets로 등록된 객체 확인 가능.

스크린샷 2021-08-24 오후 8 14 41

secret의 경우 describe로 상세정보를 확인하려 해도, 데이터를 정확히 공개하지 않는다.

configMap과 Secret을 Env 환경변수로 쓰기 위한 yaml 파일. pod를 실행한다.

apiVersion: v1
kind: Pod
metadata:
  name: configmap-env-demo
spec:
  containers:
    - name: configmap-demo
      image: alpine
      command: ["sleep", "3600"]
      env:
        # Define the environment variable
        - name: PLAYER_LIVES # 변수명
          valueFrom: # 이 환경변수는 무엇을 참조할 것인지
            configMapKeyRef: 
              name: player-pro-demo  # The ConfigMap this value comes from.
              key: player_lives # The key to fetch.
        - name: PROPERTIES_FILE_NAME
          valueFrom:
            configMapKeyRef:
              name: player-pro-demo
              key: properties_file_name
        - name: SECRET_USERNAME
          valueFrom:
            secretKeyRef:
              name: example-secret
              key: username
        - name: SECRET_PASSWORD
          valueFrom:
            secretKeyRef:
              name: example-secret
              key: password

스크린샷 2021-08-25 오전 9 07 26

Application Config using Mount Volumes

configMap과 같은 오브젝트를 사용하는 대신, Volume에 직접 파일을 두어 사용할 수도 있다.

apiVersion: v1
kind: Pod
metadata:
  name: configmap-vol-demo
spec:
  containers:
    - name: configmap-vol-demo
      image: alpine
      command: ["sleep", "3600"]

      # volumes에서 정의한 객체가 mount될 path를 정의.
      volumeMounts:
      - name: player-map
        mountPath: /etc/config/configMap
      - name: player-secret
        mountPath: /etc/config/secret

  volumes:
    # You set volumes at the Pod level, then mount them into containers inside that Pod
    - name: player-map
      configMap:
        # Provide the name of the ConfigMap you want to mount. 
        # configMap 오브젝트의 이름 등록.
        name: player-pro-demo
    - name: player-secret
    # secret을 등록하려면 secret의 이름을 등록한다.
      secret:
        secretName: example-secret

이 pod를 kubectl apply -f 로 생성하고, 해당 pod로 들어가면

  • kubectl exec configmap-vol-demo -it -- sh

/etc/config/configMap 항목에 파일 형태로 저장되어 있는 걸 확인할 수 있다.

Manage Application Configuration Posix ConfigMap

configMap-env-demo처럼 매번 pod -> container의 환경변수처럼 사용할 수 있지만, container의 환경변수 형태로 선언하는 대신 다른 방법으로 config를 정의해 활용할 수 있다. "posix configMap".

apiVersion: v1
kind: ConfigMap
metadata:
  name: player-posix-demo
data:
  PLAYER_LIVES: "5"
  PROPERTIES_FILE_NAME: "user-interface.properties"
  BASE_PROPERTIES: "Template1"
  USER_INTERFACE_PROPERTIES: "Dark"
  • 환경변수의 key-value 조합은 반드시 1:1이어야 한다.
  • key값은 대문자이며, separate pair는 반드시 언더바 (_)로 지정되어야 한다.
  • 이렇게 정의하면, configMap을 생성하고 등록할 때 컨테이너의 환경변수로 자동 등록해준다. key값은 환경변수의 이름, value값은 해당 환경변수의 값이 된다.
apiVersion: v1
kind: Pod
metadata:
  name: configmap-posix-demo
spec:
  containers:
    - name: configmap-posix
      image: anshuldevops/kubernetes-web:1.10.6
      ports:
        - containerPort: 8080
      envFrom:
        - configMapRef:
            name: player-posix-demo

posix configMap을 적용하기 위한 컨테이너. 환경변수를 envFrom으로 정의하고, configMapRef로 configMap 객체의 이름을 지정하면 된다. 환경변수가 제대로 지정되었는지 확인하려면, configmap-posix-demo 컨테이너로 들어가서 printenv 명령어를 sh에 입력하면 됨.

ConfigMap & Secret from Files

스크린샷 2021-08-28 오후 3 00 28

sudo apt-get update
apt install apache2-utils

htpasswd -c .htpasswd user 
# ht 연결을 위한 username = user, password는 명령어 실행하면 입력창이 뜬다. 이 세션에서 사용하기 위해 계속 기억해야 하는 비밀번호.

# 명령어 실행 결과로 .htpasswd 파일이 생성된다. 들어가보면 username: encrypted_password 형태로 key-value pair가 들어 있다.
# 이렇게 만들어진 파일을 secret으로 사용할 수 있음. nginx-htpasswd라는 이름의 secret을 만들었지만, 이름은 커스터마이즈 가능
kubectl create secret generic nginx-htpasswd --from-file .htpasswd
kubectl describe screts nginx-htpasswd

# kubectl로 secret 파일을 만들었다면, 생성에 사용되었던 파일은 삭제하는 게 좋다.

nginx.conf 파일을 토대로 configMap을 생성하는 방법

  • nginx.conf 파일
    user nginx
    worker_processes auto
    

error_log /var/log/nginx/error.log notice
pid /var/run/nginx.pid

events
{
worker_connections 1024
}

http
{
server
{
listen 80
server_name localhost

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

auth_basic "Secure Site" # basic auth
auth_basic_user_file conf/.htpasswd # auth에 쓰이는 파일의 경로

}
}


이 conf 파일을 토대로 configMap을 생성하려면

`kubectl create configmap nginx-config-file --from-file nginx.conf`


```yml
apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
spec:
  containers:
    - name: nginx-container
      image: 'nginx:1.19.1'
      ports:
        - containerPort: 80
      volumeMounts:
        - name: nginx-config-volume # configMap
          mountPath: /etc/nginx # nginx config 파일의 디폴트 경로
        - name: htpasswd-volume # secret
          mountPath: /etc/nginx/conf
  volumes:
    - name: nginx-config-volume
      configMap:
        name: nginx-config-file
    - name: htpasswd-volume
      secret:
        secretName: nginx-htpasswd

이제 nginx-pod yaml을 토대로 kubectl apply -f nginx-pod.yaml 로 pod를 올리면 된다.

Manage Container Resources in k8s

스크린샷 2021-08-29 오후 1 13 40

k8s에서 컨테이너를 생성하고 관리하는 것 중 '리소스' 관련한 내용.

스크린샷 2021-08-29 오후 1 34 04
  • 특정 user가 container를 생성 요청하고 할당받을 때, 얼마나 resource 요청할 수 있는지 limit을 정할 수 있음.
  • 리소스가 부족한 노드의 경우 kube scheduler에서 스케줄링 대상에서 빼버림. 즉 허용 가능한 리소스보다 더 많은 양이 필요한 경우 아예 컨테이너를 가동하지 않는다.

cf. 리소스를 얼마나 요청할지 결정하는 건 container이다.
또한, container에서 limit 제한을 걸어둔다 해도 정확히 그만큼만 사용할 수 있는 것도 아님.
kube scheduler에서 스케줄링에 참고하기 위해 사용하는 용도라고 보면 된다. 실제 사용량과 동일하지는 않음. 스케줄러는 container가 제시한 리소스를 참고로 해서, 실제로 그 정도 리소스 여유분이 있을 경우 컨테이너에게 제공하는 역할.

스크린샷 2021-08-29 오후 1 38 39
  • 만약 500 CPU unit을 요청했다 -> 1/2 vCPU 사용.
스크린샷 2021-08-29 오후 1 40 56
  • Limit의 경우, container의 리소스 사용량 제한을 위해 존재하며
  • Runtime 시점에서 결정된다. 실제 cpu와 메모리 사용량은 runtime 시점에서부터 측정 가능하기 때문.

limit에 도달했을 경우 처리 방식은 조금씩 다르다. 위의 예시에서

  • cpu 한도에 도달했을 경우: 프로세스 쓰로틀링이 진행되지만 컨테이너를 종료하지는 않는다.
  • memory 한도에 도달했을 경우: 초과 시 kill container -> restart policy를 토대로 container를 재시작한다.

먼저, 같은 양의 resource를 요구하는 두 개의 pod를 만든다.

apiVersion: v1
kind: Pod
metadata:
  name: frontend-1
spec:
  containers:
  - name: app
    image: alpine
    command: ["sleep", "3600"]
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
---
apiVersion: v1
kind: Pod
metadata:
  name: frontend-2
spec:
  containers:
  - name: app
    image: alpine
    command: ["sleep", "3600"]
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
---
apiVersion: v1
kind: Pod
metadata:
  name: frontend-3
spec:
  containers:
  - name: app
    image: alpine
    command: ["sleep", "3600"]
    resources:
      requests: # 요청량
        memory: "64Mi"
        cpu: "750m"
---
apiVersion: v1
kind: Pod
metadata:
  name: frontend-4
spec:
  containers:
  - name: app
    image: alpine
    command: ["sleep", "3600"]
    resources:
      requests:
        memory: "64Mi"
        cpu: "750m"
스크린샷 2021-08-29 오후 2 05 49

cluster에서 top 입력 후 1을 누르면, 해당 클러스터의 리소스 현황을 볼 수 있다.

  • 현재 cpu 사용가능한 양은 1vCPU 정도 (1000 unit) 라고 한다.
  • 3과 4번 포트의 경우 request cpu양을 의도적으로 크게 만든 뒤 kubectl apply를 실행하면 아래와 같은 에러가 발생한다.
스크린샷 2021-08-29 오후 2 09 33

리소스가 부족해서 컨테이너를 실행할 수 없다는 내용. 정확히는, 처음에 250m으로 실행해서 네 개 전부 정상적으로 실행되었지만, 750으로 변경한 pod 요청을 반영할 수 없다는 내용의 에러다.

  • kubectl delete -f 파일명.yaml 로 pods를 지워준다. 위 파일에서는 4개의 pod를 한 파일에 정의했기 때문에 4개 pod 전부 지워진다.
스크린샷 2021-08-29 오후 2 14 23
  • 리소스 요청을 감당할 수 없는 pod의 경우 스케줄러가 아예 관리대상에서 빼 버린다. 그래서 750m을 요청한 Pod의 경우 pending 상태를 유지하게 된다.
  • cpu 요청량을 수용할 수 있을 정도의 resource 여유분이 확보되면, 해당 Pod이 자동으로 실행된다.
apiVersion: v1
kind: Pod
metadata:
  name: frontend-limit
spec:
  containers:
  - name: app
    image: alpine
    command: ["sleep", "3600"]
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

이번엔 limit이 정의되어 있는 pod. 만약 limit을 초과하는 cpu가 할당될 경우 쓰로틀링이 실행되며, memory가 한도를 초과할 경우 컨테이너를 삭제 후 재시작한다.

Monitor k8s Resources.

스크린샷 2021-08-29 오후 2 18 46 스크린샷 2021-08-29 오후 2 20 38

k8s는 active Monitoring을 사용함. container의 상태를 확인하고, failure 발생 시 자동으로 restart하는 기능을 지원하고 있음

Health Check을 제공하는 세 가지 Probe가 존재함.

스크린샷 2021-08-29 오후 2 23 40

Liveness probe

  • 컨테이너의 상태를 확인함
  • 기본적으로는 컨테이너가 실행중이지 않을 경우 down으로 판단함.
  • down으로 판단된 컨테이너는 재시작하지만, 재시작은 restart policy를 따른다.
  • 컨테이너 내에서 cmd를 주기적으로 실행하기 / HTTP health check 두 가지가 가능함.
스크린샷 2021-08-29 오후 2 25 22
  • initialDelaySeconds : 프로세스 처음 시작 후 몇 초 뒤부터 health check를 진행할 것인가. 프로세스가 처음 뜨고 완전히 실행하기까지 시간이 필요한 걸 감안해서 선택.
  • periodSeconds : interval time.
스크린샷 2021-08-29 오후 2 27 40

Startup Probe

스크린샷 2021-08-29 오후 9 00 18

  • 애플리케이션에 따라 startUp time이 길거나 예측할 수 없는 경우가 있다. 이 경우 Liveness probe의 initialDelay만으로 status를 확인하기 쉽지 않음.
  • 컨테이너가 처음 시작할 때 startup probe가 실행되고, startup probe가 success 상태가 되어야만 Liveness probe가 실행되도록 하는 일종의 트리거 역할이라고 보면 됨.

스크린샷 2021-08-29 오후 9 01 00

failureThreshold 디폴트 값은 1.

위 예시의 경우 애플리케이션의 status가 fail로 판정되기까지 최대 5분 (300초)은 startup Probe가 확인할 수 있다는 뜻이다.


Readiness Probe

스크린샷 2021-08-29 오후 9 05 43

  • 트래픽을 받을 준비가 되어 있는지 확인하는 용도의 probe.
  • 애플리케이션이 백엔드 / 프론트엔드 등으로 나뉘어 있을 경우.. end to end의 health check를 담당한다고 보면 됨.

스크린샷 2021-08-29 오후 9 06 16

Liveness와 readiness는 병렬로 실행할 수 있다. Liveness는 컨테이너의 health check이고, readiness는 애플리케이션의 health check이기 때문.


Liveness probe 실습파일.

apiVersion: v1
kind: Pod
metadata:
  name: liveness-probe
spec:
  containers:
    - name: liveness
      image: k8s.gcr.io/busybox 
      args:
        - /bin/sh
        - -c # command
        - touch /tmp/healthcheck; sleep 60; rm -rf /tmp/healthcheck; sleep 600
      livenessProbe:
        exec:
          command: # 해당 파일이 존재하는지 아닌지 체크.
            - cat
            - /tmp/healthcheck
        initialDelaySeconds: 5
        periodSeconds: 5

pod를 실행하면

  1. touch /tmp/healthcheck 로 파일 생성
  2. initDelaySecond 이후 cat /tmp/healthcheck로 파일 존재여부 체크
  3. 60초 뒤 파일이 삭제됨
  4. 삭제된 이후부터는 liveness가 fail이 됨.

kubectl describe liveness-probe로 확인한 결과는 아래와 같다.

스크린샷 2021-09-08 오후 8 58 14

처음에는 성공적으로 Create / Start까지 진행되었지만,

Liveness probe failed가 발생한 후 restart를 자동으로 진행하는 걸 볼 수 있다.

http api로 liveness를 확인하려면

apiVersion: v1
kind: Pod
metadata:
  name: liveness-probe-http
spec:
  containers:
    - name: liveness-nginx
      image: k8s.gcr.io/nginx
      livenessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 3
        periodSeconds: 3

kubectl describe liveness-probe-http로 pod의 IP값을 확인하고, 해당 ip로 curl -u <ip주소> 접근 시 정상적으로 접근되는 걸 확인할 수 있다.

Startup Probe에 필요한 yaml 코드는 liveness와 거의 유사하다.

apiVersion: v1
kind: Pod
metadata:
  name: startup-probe-http
spec:
  containers:
    - name: startup-nginx
      image: k8s.gcr.io/nginx
      startupProbe:
        httpGet:
          path: /
          port: 80
        failureThreshold: 30
        periodSeconds: 10

위 코드의 startupProbe 세팅대로라면 failure 판정 / restart까지 최대 5분이 필요하다. failureThreshold 30 * periodSeconds 10을 곱하면 300초가 되기 때문.

스크린샷 2021-09-08 오후 9 36 58

readiness Probe 예시설정.

apiVersion: v1
kind: Pod
metadata:
  name: hc-probe
spec:
  containers:
    - name: nginx
      image: k8s.gcr.io/nginx
      livenessProbe:
        httpGet:
          path: /
          port: 80
        initialDelaySeconds: 3
        periodSeconds: 3
      readinessProbe:
        httpGet:
          path: /
          port: 9090 # 의도적으로 fail 발생하게 포트설정
        initialDelaySeconds: 3
        periodSeconds: 3

스크린샷 2021-09-09 오후 1 55 51

Status는 Ready이지만, Running 상태로 확정되지는 않는다. Readiness Probe에서 실패하기 때문.

Pods restart Policy

스크린샷 2021-09-09 오후 7 52 16

기본적으로 제공해주는 restart Policy는 크게 셋. always, onFailure, Never

스크린샷 2021-09-09 오후 7 56 07

  • always의 단점: 성공적으로 프로그램이 exit되었을 때에도 container를 삭제하고 재시작한다.
    • 프로그램이 에러를 내고 종료하던, 성공적으로 실행이 끝나던 상관없이 container를 재시작하게 됨.
    • 따라서 '항상 실행되어야만 하는' 프로그램일 경우 적합하며, 특정 작업을 처리한 뒤 종료해야 하는 애플리케이션 컨테이너에는 적절하지 않다.
apiVersion: v1
kind: Pod
metadata:
  name: restart-always-pod
spec:
  restartPolicy: Always
  containers:
    - name: app
      image: alpine
      command: ["sleep", "20"]
# 20초 뒤 컨테이너의 프로그램이 성공적으로 종료됨.

스크린샷 2021-09-09 오후 7 59 59

  • onFailure: container 에러 등으로 failure발생 시에만 restart.
apiVersion: v1
kind: Pod
metadata:
  name: onfailure-always-pod
spec:
  restartPolicy: OnFailure
  containers:
    - name: app
      image: alpine
      command: ["sleep", "20"]
# 20초 뒤 성공적으로 프로그램이 종료되기 때문에 container restart하지 않음.
# kubectl get pods -o wide로 pod상태를 확인하면 status: completed 상태가 된다.
# 만약 failure상태가 될 경우 status: CrashLoopBackOff가 되며, restart 횟수가 올라간 뒤 컨테이너를 재실행한다.

스크린샷 2021-09-09 오후 8 13 55

  • Never: 한 번만 실행되는 게 보장되어야 하는 애플리케이션의 경우 적절함.
apiVersion: v1
kind: Pod
metadata:
  name: never-always-pod
spec:
  restartPolicy: Never
  containers:
    - name: app
      image: alpine
      command: ["sh", "-c", "sleep 20;", "Dummy Command"]
# dummy command라는 명령어는 없으므로, 20초 뒤 프로그램은 failed된다.
# 하지만 status는 completed.

Multi Container Pods

스크린샷 2021-09-10 오전 10 51 42

하나의 Pod 안에 여러 개의 Containers를 생성할 수 있다. (Multiple Containers in a Single Pod.)

스크린샷 2021-09-10 오전 10 52 57

같은 pod 내의 컨테이너끼리는 Network, Volume을 공유함.

apiVersion: v1
kind: Pod
metadata:
  name: two-containers
spec:
  restartPolicy: OnFailure
  containers:
    - name: nginx-container
      image: nginx
      volumeMounts:
        - name: shared-data
          mountPath: /usr/share/nginx/html
    - name: debian-container
      image: debian
      volumeMounts:
        - name: shared-data
          mountPath: /pod-data
      command: ["/bin/sh"]
      args: ["-c", "echo Hello from the Secondary container > /pod-data/index.html"]
  volumes:
    - name: shared-data
      emptyDir: {}
# 두 번째 컨테이너의 경우 command 명령어 실행을 끝내면 정상적으로 종료됨. (onFailure)

스크린샷 2021-09-10 오전 11 24 42

두 개가 shared volumne (shared-data) 을 공유하고 있기 때문에, debian controller의 명령어로 nginx html 파일 이름이 변경된 것을 확인할 수 있다.

Container Initialization in k8s

스크린샷 2021-09-10 오후 1 03 19

  • App Container 실행 전에 먼저 실행되는 특수한 목적의 컨테이너.
  • 애플리케이션을 띄우기 전에 설정이 필요할 경우 보통 사용한다.

스크린샷 2021-09-10 오후 1 05 01

  • mainfest에서 사전에 정의한 순서대로 init Containers가 실행된다
  • 모든 init container가 정상적으로 completed 된 후에야 app container를 실행한다.
    • 따라서, 정의하기에 따라 App Container의 startup을 block / delay하는 등의 작업이 가능하다.
    • 보통 DB나 기타 App dependency를 init container에서 먼저 실행시킨 뒤 App을 실행하게 하는 등의 용도로 사용

스크린샷 2021-09-10 오후 1 07 47

apiVersion: v1
kind: Pod
metadata:
  name: application-pod
spec:
  containers:
    - name: myapp-container # App Container.
      image: busybox:1.28
      command: ["sh", "-c", "echo The app is running! && sleep 3600"]
  initContainers: # initContainers 정의
    - name: init-myservice
      image: busybox:1.28
      command:
        [
          "sh",
          "-c",
          "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 5; done",
        ]
    - name: init-mydb
      image: busybox:1.28
      command:
        [
          "sh",
          "-c",
          "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 5; done",
        ]

nslookup - DNS 주소 조회

  • app container 실행에 필요한 container dependency가 세팅될 때까지 대기한다.
  • myservice와 mydb라는 이름의 service가 먼저 실행될 때까지 대기 상태가 됨.
apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9377

스크린샷 2021-09-11 오전 11 58 15

반응형