ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [따배쿠] Pod - init container & infra container
    kubernetes 2024. 12. 1. 16:27

    Init Container

    • Main Container 실행 전에 미리 동작시킬 컨테이너
    • 본 Container가 실행되기 전에 사전 작업이 필요할 경우 사용
    • 즉, Init Container가 실행되어야, Main Container를 구동시킬 수 있다.
      • 예시 1. node.js 이미지로 만들어진 로그인 지원 application을 담당 main container가 있다고 가정한다. 해당 main container에서 로그인을 지원하기 위해서는 db에서 로그인 관련 정보를 가져와야한다. 여기서 db에 접속을 해서 데이터를 가져오는 컨테이너가 init container가 된다.
      • 이를 하나의 pod로 만들어 놓으면, init container에서 작업이 성공해야 main container를 동작시킬 수 있다
      • init container에서 동작이 실패하면 main container도 동작이 실패한다.

    예시

    # yaml 파일 작성

    root@master:~/Getting-Start-Kubernetes/5# vi init-container-exam.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: myapp-pod
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp-container
        image: busybox:1.28
        command: ['sh', '-c', 'echo The app is running! && sleep 3600']
      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 2; 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 2; done"]

     

    여기서 containers가 main container, init containers가 init container로 작동한다.

     

     

    [코드 설명]

    더보기

    apiVersion: v1
    - Kubernetes API의 버전을 지정합니다. 여기서는 v1을 사용하고 있습니다.


    kind: Pod
    - 생성할 리소스의 종류를 정의합니다. 여기서는 Pod을 생성합니다.


    metadata
    - Pod의 메타데이터를 정의합니다.

      name: Pod의 이름을 myapp-pod로 설정합니다.
      labels: Pod에 대한 레이블을 설정합니다. 여기서는 app: myapp이라는 레이블이 있습니다.


    spec
    - Pod의 사양을 정의합니다.
      containers : 일반 컨테이너를 정의합니다.
        name: 컨테이너의 이름을 myapp-container로 설정합니다.
        image: 사용할 Docker 이미지를 busybox:1.28로 설정합니다.
        command: 컨테이너가 시작될 때 실행할 명령어를 정의합니다. 여기서는 "The app is running!"이라는 메시지를 출력하고 3600초(1시간) 동안 대기합니다.

     

      initContainers : Init 컨테이너를 정의합니다. Init 컨테이너는 일반 컨테이너가 시작되기 전에 실행되는 특별한 컨테이너입니다.
      #첫 번째 Init 컨테이너 (init-myservice):

        name: Init 컨테이너의 이름을 init-myservice로 설정합니다.
        image: 사용할 Docker 이미지를 busybox:1.28로 설정합니다.
        command: myservice라는 서비스의 DNS 이름이 해결될 때까지 대기하는 명령어를 실행합니다. 이 명령어는 nslookup을 사용하여 서비스의 DNS를 확인하고, 서비스가 준비될 때까지 2초 간격으로 "waiting for myservice"라는 메시지를 출력합니다. 즉, myservice라는 서비스가 실행되지 않으면 무한루프고 myservice라는 서비스가 실행되면 완료 


      #두 번째 Init 컨테이너 (init-mydb):
        name: Init 컨테이너의 이름을 init-mydb로 설정합니다.
        image: 사용할 Docker 이미지를 busybox:1.28로 설정합니다.
        command: mydb라는 서비스의 DNS 이름이 해결될 때까지 대기하는 명령어를 실행합니다. 이 명령어도 nslookup을 사용하여 서비스의 DNS를 확인하고, 서비스가 준비될 때까지 2초 간격으로 "waiting for mydb"라는 메시지를 출력합니다.


    <요약>
    이 YAML 파일은 myapp-pod라는 이름의 Pod을 정의하며, 두 개의 Init 컨테이너(init-myservice와 init-mydb)가 각각 myservice와 mydb 서비스가 준비될 때까지 대기한 후, 일반 컨테이너(myapp-container)가 실행됩니다. Init 컨테이너는 일반 컨테이너가 시작되기 전에 반드시 완료되어야 하며, 이를 통해 서비스의 의존성을 관리할 수 있습니다.

    # pod 생성

    root@master:~/Getting-Start-Kubernetes/5# kubectl create -f init-container-exam.yaml
    pod/myapp-pod created

     

    # 확인

    root@master:~/Getting-Start-Kubernetes/5# kubectl get pods -o wide
    NAME        READY   STATUS     RESTARTS   AGE   IP                NODE    NOMINATED NODE   READINESS GATES
    myapp-pod   0/1     Init:0/2   0          6m    192.168.166.153   node1   <none>           <none>

     

    pod가 실행되지 않고 있는 것을 확인


    아마 myservice와 mydb라는 service가 없어서 init container 또한 실행되지 않았고,

    자연스레 main container 또한 실행되지 않았다.

     

    # myservice와 mydb라는 service 생성

    root@master:~/Getting-Start-Kubernetes/5# vi init-container-svc.yaml
    ---
    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
    root@master:~/Getting-Start-Kubernetes/5# kubectl create -f init-container-svc.yaml
    service/myservice created
    service/mydb created

     

    # 재확인

    root@master:~/Getting-Start-Kubernetes/5# kubectl get pods -o wide

     

     

    Infra container (pause)

    • Pod의 환경을 만들어주는 컨테이너 (Pod 대한 IP, hostname 관리 및 생성하는 컨테이너)
    • Pod 생성 시, 자동으로 생성되고 삭제 시 자동으로 삭제 됨
    • 보통 컨테이너 조회 명령어로 보이진 않지만, 실제로는 존재함 !

     

    예시

     

    # pod 생성 (nginx 이미지를 쓰는 webserver라는 이름의 컨테이너를 보유하고 있다)

     

    root@master:~/Getting-Start-Kubernetes/5# kubectl run webserver --image=nginx:1.14 --port=80
    pod/webserver created

     

    *CLI로 pod를 생성하고 싶을 땐,  kubectl run ~ 명령어 사용

    root@master:~/Getting-Start-Kubernetes/5# kubectl get pods -o wide
    NAME        READY   STATUS    RESTARTS   AGE     IP                NODE    NOMINATED NODE   READINESS GATES
    webserver   1/1     Running   0          2m46s   192.168.166.156   node1   <none>           <none>

     

    node1에서 webserver pod가 생성되었다.

     

    # node1 접속 (...을 하기 위해서) master 서버의 공개키를 node1 서버에 등록

     

    [master]

    root@master:~/Getting-Start-Kubernetes/5# ssh-keygen -t rsa

     

    ssh 공개키 생성

    root@master:~/.ssh# ls
    authorized_keys  id_rsa  id_rsa.pub  known_hosts
    root@master:~/.ssh# cat id_rsa.pub
    ssh-rsa ~~~ root@master

     

    ~/.ssh 경로의 id_rsa.pub을 cat 명령어로 출력 후, 복사

     

    [node1]

     

    root@node1:~/.ssh# vi authorized_keys

    ~/.ssh 경로의 authorized_keys 파일에 master 서버 공개키 붙여넣기

     

    [master > node1 SSH 접속]

    root@master:~# ssh node1
    Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.8.0-1017-azure x86_64)
    
     * Documentation:  https://help.ubuntu.com
     * Management:     https://landscape.canonical.com
     * Support:        https://ubuntu.com/pro
    
     System information as of Mon Dec  2 06:23:34 UTC 2024
    
      System load:  0.0                Processes:             163
      Usage of /:   21.5% of 28.02GB   Users logged in:       1
      Memory usage: 7%                 IPv4 address for eth0: 10.100.0.101
      Swap usage:   0%

     

    master 서버에서 node1으로 SSH 접속 시도해보면, 별도의 패스워드 인증 없이 SSH 접속 가능 확인

     

    # ps aux 명령어로 확인

    root@node1:~# ps aux
    root       26367  0.0  0.2 1238424 17656 ?       Sl   06:13   0:00 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id a377
    65535      26388  0.0  0.0    996   512 ?        Ss   06:13   0:00 /pause
    root       26417  0.0  0.0  32636  5632 ?        Ss   06:13   0:00 nginx: master process nginx -g daemon off;
    message+   26429  0.0  0.0  33084  2536 ?        S    06:13   0:00 nginx: worker process

     

    webserver pod 생성하면서 nginx 컨테이너가 생성됨과 동시에, pause 컨테이너도 생성된 것을 확인할 수 있다.

     


    참고 영상 

    https://www.youtube.com/watch?v=ChArV14J6Ek&list=PLApuRlvrZKohaBHvXAOhUD-RxD0uQ3z0c&index=13

     

     

    참고 문서

    https://kubernetes.io/ko/docs/concepts/workloads/pods/init-containers/

Designed by Tistory.