3. K8s 실전 활용을 위한 10단계

김하영·2021년 9월 30일
0
post-custom-banner

'15단계로 배우는 도커와 쿠버네티스' 기반으로 내용 정리하였습니다.

  • 쿠버네티스 첫걸음
    hello-world 컨테이너를 쿠버네티스에서 돌려 보기

( 쿠버네티스 환경을 어떻게 구성했는지...? )

6.2 파드 실행

  • 쿠버네티스에서 hello-world 컨테이너 실행

(1)kubectl (2)run (3)hello-world (4)--image=hello-world (5)-it (6)--restart=Never

(1) kubectl : K8s 클러스터를 조작하기 위해 사용되는 커맨드

(2) run : 컨테이너 실행을 명령하는 서브 커맨드

(3) hello-world : 쿠버네티스 오브젝트의 이름(파드나 컨트롤러 등)

(4) --image=hello-world : 컨테이너의 이미지, 쿠버네티스에서는 파드 단위로 컨테이너가 기동되며 리포지터리명이 생략된 경우에는 도커 허브를 사용

(5) -it : -i 는 키보드를 표준 입력에 연결하고, -t 는 유사 터미널과 연결하여 대화 모드 설정
옵션 '--restart=Never' 인 경우에만 유효하며, 그 외에는 백그라운드로 실행

(6) --restart=Never : 이 옵션에 따라 파드의 기동 방법 변경. Never는 직접 파드가 가동되며,
Always 나 OnFailure는 컨트롤러를 통해 파드가 가동
( Never은 재시작이 자동으로 X / Always 나 OnFailure은 재시작을 자동으로 )

[ 'kubectl run' 명령어 흐름 ]

  1. kubectl이 쿠버네티스에게 명령을 전달한다.
  2. 노드에 이미지가 없으면 원격 리포지터리에서 다운로드 한다. (docker hub)
  3. 노드의 containerd 가 컨테이너를 실행한다.
  4. kubectl이 터미널에 메시지를 표시한다.

6.3 컨트롤러에 의한 파드 실행

[ 디플로이먼트가 만든 오브젝트 ]

디플로이먼트를 실행하면 4개의 오브젝트 > pod, service, deployment, replicatset 이 생성된다.

  1. deployment.apps/test-deployment
    만들어진 디플로이먼트 오브젝트의 이름은 test-deployment 다.
    이 컨트롤러는 레플리카셋 컨트롤러와 함께 파드를 관리하며 이미지 버전, 파드의 개수등이 목표 상태가 되도록 관리한다.

  2. replicaset.apps/test-deployment-54f57cf6bf
    디플로이먼트와 함께 만들어진 레플리카셋 오브젝트로 이름 뒤에 해시 문자열이 붙어 유일한 이름을 부여 받는다. 레플리카셋은 디플로이먼트와 함께 파드의 수가 지정된 개수가 되도록 제어한다. 유저가 직접 레플리카셋을 조작하는 것은 권장되지 않는다.

  3. pod/test-deployment-54f57cf6bf-231sdaw3
    파드 안에는 하나 혹은 여러 개의 컨테이너가 실행된다. 레플리카셋 이름 뒤에 추가적인 해시 문자열이 추가되어 역시 유일한 이름을 부여 받았다.

[ kubectl get deployment 각 항목의 의미 ]

  • NAME : 디플로이먼트의 오브젝트 명
  • DESIRED : 희망 파드 개수, 디플로이먼트를 만들 때 설정한 파드 수
  • CURRENT : 현재 실행 중인 파드의 개수. 재기동 대기 등을 포함한 모든 파드 수
  • UP-TO-DATE : 최근에 업데이트된 파드의 개수. 즉, 컨트롤러에 의해 조정된 파드 수
  • AVAILABLE : 사용 가능한 파드 개수. 즉 정상적으로 기동되어 서비스 가능한 파드 수
  • AGE : 오브젝트가 만들어진 후 경과 시간

[ kubectl get pod 각 항목의 의미 ]

  • NAME : 파드의 오브젝트 명
  • READY : 기동 완료 수. 분자와 분모의 형태로 숫자가 표시.
    분자 측은 파드 내의 컨테이너가 기동된 개수이며, 분모 측은 파드 내의 정의한 컨테이너의 총 개수.
    즉 0/1의 의미는 파드에 컨테이너가 하나 정의되어 있으나 기동된 컨테이너는 없다는 걸 의미
  • STATUS : 파드의 상태 ( ex : CrashLoopBackOff - 재시작 반복 후, 다음 재시작 전 대기 상태 )
  • RESTARTS : 파드가 재시작된 횟수
  • AGE : 파드 오브젝트가 만들어진 후 경과 시간

마무리

  • 파드는 쿠버네티스에서 컨테이너의 최소 기둥 단위다.
  • 파드를 관리하는 여러 컨트롤러가 있으며 워크로드에 맞게 선택해야 한다.
  • 디플로이먼트는 웹 서버나 API 서버처럼 지속적으로 서비스를 제공해야 하는 워크로드에 적합한 컨트롤러다.
  • 잡 컨트롤러는 배치 처리와 같은 워크로드에 적합한 컨트롤러다.

[ 파드와 컨트롤러 관계 ]

  1. 단독(알몸) 파드 구동
  • 비정상으로 종료해도 기동하지 않음
  • 컨테이너 종료 후, 삭제 필요
  • 수평 스케일이 안 됨

ex) 딱 한번 구동되서 데이터 변경하는 프로그램?

  1. 서버 타입의 파드 제어
  • 요구를 계속 대기하면서 종료하지 않는 타입
  • 수평 스케일
  • 비정상 종료 시 기동함

ex) 구글

  1. 배치 처리 타입 파드 제어
  • 처리가 정상 종료 시 완료함
  • 처리가 실패파면 재시도
  • 병렬 처리 수를 설정해서 시간 단축

ex) 데이터 업데이트 하는 배치 프로그램

[ 이번 스텝에서 새로 사용한 kubectl 명령어 ]

  • kubectl cluster-info : K8s 클러스터의 엔드포인트를 표시

  • kubectl get no : K8s 클러스터를 구성하는 노드 목록 표시

  • kubectl run : 파드 실행

  • kubectl get po : 파드의 목록 출력

  • kubectl delete po : 파드의 이름을 지정해서 삭제

  • kubectl get all : 모든 오브젝트 출력

  • kubectl logs : 컨테이너 프로세스가 STDOUT 이나 STDERR로 출력하는 로그 표시

  • kubectl get deploy.po : 디플로이먼트와 파드의 목록 표시

  • kubectl get deploy : 디플로이먼트 목록 표시

  • kubectl delete deploy : 디플로이먼트와 관련 레플리카셋 및 피드를 일괄 삭제

  • kubectl get jobs : 잡의 실행 상태를 출력

  • kubectl create job : 잡 컨트롤러 제어하에서 파드를 실행

  • kubectl create deployment : 디플로이먼트 컨트롤러 제어하에서 파드를 실행

  • kubectl scale : 레플리카 수 변경


  • 매니페스트와 파드
    파드 API를 구사하여 컨테이너 기동하기

- 매니페스트란 ?
쿠버네티스의 오브젝트를 생성하기 위한 메타 정보를 YAML이나 JSON으로 기술한 파일이다.
실제 파드를 단독하는 매니페스트 보다 컨트롤러에 대한 매니페스트를 작성하여 컨트롤러를 사용한다.

7.1 매니페스트 작성법

매니페스트는 YAML이나 JSON으로 기술할 수 있다. YAML이 좀 더 간결하고 가독성이 좋다.

apiVersion: v1 
	kind: Pod 
    metadata: 
    name: springboot-web 
    spec: 
    	containers: 
    	- name: springboot-web 
        image: 1223yys/springboot-web:0.1.6 
        ports: 
        - containerPort: 8080

[ 파드 API ]

  • apiVersion : v1 설정
  • kind : pod 설정
  • metadata : 파드의 이름을 지정하는 name은 필수 항목이며, 네임스페이스 내에 유일해야함
  • spec : 파드의 사양을 기술

[ 파드의 사양 ]

  • containers : 컨테이너 사양을 배열로 기술
  • initContainers : 초기화 전용 컨테이너 사양을 배열로 기술
  • nodeSelector : 파드가 배포될 노드의 레이블을 지정
  • volumes : 파드 내 컨테이너 간에 공유할 수 있는 볼륨을 설정

[ 컨테이너 설정 ]

  • image : 이미지의 리포지터리명과 태그
  • name : 컨테이너를 여러 개 기술할 경우 필수 항목
  • livenessProbe : 컨테이너 애플리케이션이 정상적으로 동작 중인지 검사하는 프로브
  • readnessProbe : 컨테이너 애플리케이션이 사용자의 요청을 받을 준비가 되었는지 검사하는 프로브
  • ports : 외부로부터 요청을 전달받기 위한 포트 목록
  • resources : CPU와 메모리 요구량과 상한치
  • volumeMounts : 파드에 정의한 볼륨을 컨테이너의 파일 시스템에 마운트하는 설정. 복수 개 기술 가능.
  • command : 컨테이너 기동 시 실행할 커맨드. args가 인자로 적용
  • args : command의 실행 인자
  • env : 컨테이너 내에 환경 변수를 설정

7.2 매니페스트 적용 방법

  • 매니페스트로 부터 쿠버네티스 오브젝트를 생성

    kubectl apply -f 매니페스트_파일명

  • 매니페스트를 지정하여 API 오브젝트를 제거하는 예

    kubectl delete -f YAML 파일명

7.3 파드의 동작 확인

(네트워크 설명에 더 가까움..)

클러스터 네트워크는 K8s 클러스터를 구성하는 노드 간의 통신을 위한 폐쇄형 네트워크다.
다른 말로 파드 네트워크라고도 불린다.

클러스터 네트워크에서 오픈한 포트는 K8s 클러스터를 호스팅하는 컴퓨터에서도 접근할 수 없다.

외부에서 클러스터 네트워크에 있는 파드의 포트에 접근하기 위해서는 서비스를 이용해야 한다.

7.4 파드의 헬스 체크 기능

파드의 컨테이너에는 애플리케이션이 정상적으로 기동 중인지 확인하는 기능, 즉 헬스 체크 기능을 설정할 수 있어, 이상이 감지되면 컨테이너를 강제 종료하고 재 시작할 수 있다.

다음 두 종류의 프로브를 사용하여 실행 중인 파드의 컨테이너를 감시한다.

  1. 활성 프로브 (liveness probe)
    : 컨테이너의 애플리케이션이 정상적으로 실행 중인 것을 검사. 검사에 실패하면 파드 상의 컨테이너를 강제로 종료하고 재시작한다.
    이 기능을 사용하기 위해서는 매니페스트에 명시적으로 설정한다.

  2. 준비 상태 프로브 (readiness probe)
    : 컨테이너의 애플리케이션이 요청을 받을 준비가 되었는지 아닌지를 검사. 검사에 실패하면 서비스에 의한 요청 트래픽 전송을 중지한다. 파드가 가동하고 나서 준비가 될 때까지 요청이 전송되지 않기 위해 사용한다. 이 기능을 사용하기 위해서는 매니페스트에 명시적으로 설정해야 한다.

[ 프로브 대응 핸들러의 종류와 설명 ]

  • exec : 컨테이너 내 커맨드를 실행. Exit 코드 0으로 종료하면 진단 결과는 성공으로 간주되며 그 외의 값은 실패로 간주

  • tcpSocket : 지정한 TCP 포트번호로 연결할 수 있다면, 진단 결과는 성공으로 간주

  • httpGet : 지정한 포트와 경로로 HTTP GET 요청이 정기적으로 실행. HTTP 상태 코드가 200 이상 400미만이면 성공으로 간주되고 그 외에는 실패로 간주, 지정 포트가 열려 있지 않은 경우도 실패로 간주

spec:
	containers:
      - name: readiness
        image: gcr.io/terrycho-sandbox/readiness:v1
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        readinessProbe:
          httpGet:
            path: /readiness
            port: 8080
          initialDelaySeconds: 3
          periodSeconds: 5

[ 프로브 대응 핸들러 기술 ]

  • httpGet : HTTP 핸들러
  • path / port : 핸들러의 경로 / HTTP 서버의 포트번호
  • tcpSocket : TCP 포트 접속 핸들러
  • port : 감시 대상의 포트 번호
  • exec : 컨테이너 내의 커맨드 실행 핸들러
  • command : 컨테이너의 커맨드를 배열로 기술
  • initialDelaySeconds : 프로브 검사 시작 전 대기 시간
  • periodSeconds : 검사 간격

기본 설정으로는 활성 프로브 (livenessProbe)가 연속해서 3번 실패하면 kubeletd이 컨테이너를 강제 종료하고 재기동한다. 컨테이너가 재시작되면 별도로 저장하지 않는 이상 날라간다.

헬스 체크는 파드가 스케줄된 노드에 있는 kubelet이 수행한다.
하드웨어 장애 시, kubelet 도 정지가 되기 때문에 노드의 장애 대책으로는 적합하지 않다.
따라서 노드의 장애 대책을 위해서는 헬스 체크가 아닌 컨트롤러를 사용해야 한다.

이러한 용도로 자주 사용되는 컨트롤러가 디플로이먼트와 스테이트풀셋이다.

7.5 초기화 전용 컨테이너

파드 내에 초기화만을 담당하는 컨테니어를 설정할 수 있다. 그러면 초기화만을 수행하는 컨테이너와
요청을 처리하는 컨테이너를 별도로 개발하여 각각 재사용할 수 있다.

initContainers에서 초기화 전용 컨테이너를 설정하고 있다.

apiVersion: v1
kind: Pod
metadata:
  name: init-demo
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: workdir
      mountPath: /usr/share/nginx/html
  # 이 컨테이너들은 파드 초기화 중에 실행된다.
  initContainers:
  - name: install
    image: busybox
    command:
    - wget
    - "-O"
    - "/work-dir/index.html"
    - http://info.cern.ch
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  dnsPolicy: Default
  volumes:
  - name: workdir
    emptyDir: {}

7.6 사이드카 패턴

하나의 파드 안에 여러 개의 컨테이너를 담아서 동시에 실행시키는 패턴이다.

위 그림의 사이드 카 패턴은 Web Server가 메인 컨테이너가 되며 같은 파일시스템을 공유하는 로그수집기가 사이드카 컨테이너가 되는 구조이다.

(멀티 컨테이너 디자인 패턴이라고도 한다.. 클라우드 관련 다양한 디자인 패턴이 존재한다..
https://docs.microsoft.com/ko-kr/azure/architecture/patterns/sidecar)

[ 사이드카 패턴 사용의 장점 ]

  • 사이드카는 런타임 환경 및 프로그래밍 언어와 관련하여 해당 기본 애플리케이션과 독립적이므로 언어마다 하나의 사이드카를 개발할 필요가 없다.

  • 사이드카는 기본 애플리케이션과 동일한 리소스에 액세스할 수 있다. 예를 들어 사이드카는 사이드카 및 기본 애플리케이션 둘 다에서 사용하는 시스템 리소스를 모니터링할 수 있다.

  • 기본 애플리케이션에 대한 사이드카의 근접도로 인해 둘 간의 통신 시 대기 시간이 길지 않다.

  • 확장성 메커니즘을 제공 하지 않는 응용 프로그램의 경우에도 사이드카를 사용하여 기본 응용 프로그램과 동일한 호스트 또는 하위 컨테이너에서 자체 프로세스로 연결 하여 기능을 확장할 수 있다.

사이드 카 구성의 매니페스트

apiVersion: v1
kind: Pod
metadata: 
  name: web-app
spec:
  containers:
    - name: app
      image: docker.io/centos/httpd // HTTP로 파일을 제공하는 기본 애플리케이션 컨테이너 
      ports:
        - containerPort: 80
      volumeMounts:
        - mountPath: /var/www/html  // 사이드카와 기본 애플리케이션 컨테이너 간에 데이터를 교환하기 위해 공유된 장소
          name: git
    - name: poll
      image: axeclbr/git            // 깃 서버로부터 데이터를 가져오고 병렬로 실행하는 사이드카 컨테이너 
      volumeMounts:
        - mountPath: /var/lib/data  // 사이드카와 기본 애플리케이션 컨테이너 간에 데이터를 교환하기 위해 공유된 장소
          name: git
      env:
      - name: GIT_REPO
        value: https://github.com/mdn/beginner-html-site-scripted
      command:
        - "sh"
        - "-c"
        - "git clone ${GIT_REPO} . && watch -n 600 git pull"
        workingDir: /var/lib/data
      volumes:
        - emptyDir: {}
          name: git    

[ 컨테이너 종료 처리 ]

SIGTERM 시그널이 (scheduler-controller 에서 보내겠지?) 왔을 때 exit 처리를 하도록 구현 해야한다. 만약 종료 처리를 구현하지 않았다면 대기 시간 만큼 기다렸다가 SIGKILL 시그널을 보내 강제 종료를 하게 된다.
(종료 하는 데 시간이 오래 걸림..)

## SIGTERM 수신 시 처리

save(){
	exit 0
}
trap save TERM

[ 이번 스텝에서 새로 사용한 kubectl 명령어 ]

  • kubectl create -f 파일명 : 파일에 기술된 오브젝트를 생성
  • kubectl delete -f 파일명 : 파일에 기술된 오브젝트를 삭제
  • kubectl apply -f 파일명 : 파일에 기재된 오브젝트가 있으면 변경하고 없으면 생성
profile
Back-end Developer
post-custom-banner

0개의 댓글