도커/쿠버네티스를 활용한 컨테이너 개발 실전 입문 - 07. 쿠버네티스 실전편

백근영·2020년 1월 28일
0
post-thumbnail

01. 쿠버네티스의 그 외 리소스

지금까지 살펴본 리소스

  • 파드
  • 레플리카세트
  • 디플로이먼트
  • 서비스
  • 인그레스
  • 스테이트풀세트
  • 스토리지클래스
  • 컨시스턴트볼륨
  • 컨시스턴트볼륨클레임

지금까지 살펴본 리소스는 데몬으로 동장하는 서버 애플리케이션을 구축할 때 주로 사용되는 리소스들이다. 쿠버네티스는 데몬으로 동작하는 서버 애플리케이션 외에도
배치 서버 등 다양한 형태의 애플리케이션을 구축할 수 있다. 그러한 경우에 사용할 수 있는 리소스들을 살펴보자.

하나 이상의 파드를 생성해 지정된 수의 파드가 정상 종료될 때까지 이를 관리하는 리소스. 잡이 생성한 파드는 정상 종료된 후에도 삭제되지 않고 그대로 남아 있기 때문에
작업이 종료된 후에 파드의 로그나 실행 결과를 분석할 수 있다. 그러므로 데몬형 애플리케이션보다는 배치 작업 위즈의 애플리케이션에 적합하다.

예시 매니페스트 파일

simple-job.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: pingpong
  labels:
    app: pingpong
spec:
  parallelism: 3
  template:
    metadata:
      labels:
        app: pingpong
    spec:
      containers:
      (생략(파드 정의와 같음))

spec.parallelism 속성을 정의해 여러 개의 파드가 병렬 실행되도록 할 수 있다.

크론잡

잡 리소스는 파드가 단 한 번만 실행되는 데 반해, 크론잡 리소스는 스케줄을 지정해 정기적으로 파드를 실행할 수 있다.
이 리소스 덕분에 Cron을 이용해 이벤트를 일으키는 애플리케이션을 따로 만들지 않아도 된다. 컨테이너 친화적인 특성을 유지하면서 스케줄에 따른 작업을
수행할 수 있다는 점이 가장 큰 장점이다. 또한 크론잡 리소스는 일반적인 Cron 작업과 달리 그 작업의 내용이 코드로 관리된다는 장점도 있다.

예시 매니페스트 파일

simple-conjob.yaml

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: pingpong
spec:
  schedul: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        metadata:
          labels:
            app: pingpong
        spec:
          containers:
      (생략(파드 정의와 같음))

spec.schedule 속성에 cron과 같은 포맷으로 파드를 실행할 스케줄을 정의할 수 있다.

시크릿

시크릿은 인증서나 비밀키, 패스워드 같은 기밀정보를 Base64로 인코딩해서 저장할 수 있도록 하는 리소스이다.

예시 매니페스트 파일

apiVersion: v1
kind: Secret
metadata:
  name: nginx-secret
type: Opaque
data:
  .htpasswd: [base64 인코딩된 문자열]

이렇게 클러스터 내에 secret을 하나 생성하고, 이를 볼륨으로 마운트함으로써 다른 리소스에서 참조할 수 있다.

...
volumeMounts:
  - mountPath: /etc/nginx/secret
    name: nginx-secret
env:
  - name: BASIC_AUTH_FILE
    value: "/etc/nginx/secret/.htpasswd"
...

시크릿이 볼륨의 형태로 목표 컨테이너에 마운트될 때는 데이터가 디코딩되어 저장된다.

03. 헬름

헬름(helm)

쿠버네티스를 운영하다보면 같은 애플리케이션을 여러 클러스터에 배포해야 하는 경우가 생긴다.
(개발용/서비스용을 나누거나 부하 테스트용 클러스터를 따로 두거나)

여러 클러스터를 배포할 각각의 환경에 맞는 설정값만 적절히 설정해둔 다음 이에 따라 배포하는 메커니즘이 필요했다.
이것이 바로 헬름(helm)이다.

헬름은 쿠버네티스 '차트'를 관리하기 위한 도구이다. 차트는 사전 구성된 쿠버네티스 리소스의 패키지다.

헬름, 차트, 매니페스트, 쿠버네티스 간 관계는 대략 아래와 같다.

  • 헬름은 차트를 관리
  • 차트를 통해 매니페스트 파일을 생성
  • 매니페스트 파일을 기반으로 쿠버네티스 클러스터 구축

틸러(tiller)

책에서는 틸러라는 개념을 소개하고 있지만, 헬름 3.0 버전부터는 틸러를 없애는 등 책의 내용과 달라진 점이 꽤 많아보였다.
그래서 책과 인터넷 자료를 같이 참고해가며 학습했다.

커스텀 차트 생성하기

우선 차트를 만드는 명령어를 입력한다.

$ helm create echo
Creating echo

그러면 명령어를 입력한 디렉토리에 echo라는 디렉토리가 생성되고, 그 구조는 아래와 같다.

.
|-- Chart.yaml
|-- charts
|-- templates
|   |-- NOTES.txt
|   |-- _helpers.tpl
|   |-- deployment.yaml
|   |-- ingress.yaml
|   |-- service.yaml
|   |-- serviceaccount.yaml
|   `-- tests
|       `-- test-connection.yaml
`-- values.yaml

우리가 해야할 일을 정리해보면 다음과 같다.
1. templates 폴더안의 템플릿 파일들 작성하기
2. 기본 values.yaml 파일 작성하기
3. 레포지토리 생성 및 차트 등록하기
4. 차트를 다운받아 커스텀 values 파일을 적용해 클러스터 구축하기

템플릿 파일 작성하기

템플릿 파일은 우리가 만들고 싶어하는 매니페스트 파일의 모양새를 고려하여 작성하면 된다.
변수화할만한 부분들을 적절히 골라 values.yaml 파일에서 정의해주어야 한다.

values.yaml 파일 작성하기

환경에 관계없이 공통으로 적용될 변수들은 values.yaml 파일에 작성한다.

예시

replicaCount: 1
nginx:
  image:
    repository: gihyodocker/nginx
    tag: latest
    pullPolicy: Always
  healthCheck: /
  backendHost: localhost:8080

echo:
  image:
    repository: gihyodocker/echo
    tag: latest
    pullPolicy: Always
  httpPort: 8080

레포지토리 생성 및 차트 등록하기

다른 사람들이 내가 만든 차트를 공유할 수 있도록 하려면 차트를 관리하는 원격 레포지토리가 필요하다.
깃헙, AWS S3, google cloud storage 등 다양한 선택지가 있다. 깃헙을 통해 실습을 진행했다.

레포지토리에는 레포지토리 내에 존재하는 차트들의 정보를 담고 있는 index.yaml 파일과 각 차트들의 아카이브 파일이 담겨있어야 한다.
그리고 깃헙 페이지로 이 내용을 공개하도록 설정하면 로컬에서 이 레포지토리를 추가할 수 있고, 그 안의 차트들 또한 열람할 수 있다.

$ helm repo list
NAME            URL
stable          https://kubernetes-charts.storage.googleapis.com
my-stable       https://baekgeunyoung.github.io/helm-chart-practice/stable
$ helm search repo my-stable
NAME                    CHART VERSION   APP VERSION     DESCRIPTION
my-stable/echo          0.1.0           1.16.0          A Helm chart for Kubernetes
my-stable/example       0.1.0           1.16.0          A Helm chart for Kubernetes

04. 쿠버네티스 배포 전략

배포 자동화와 무중단 배포

쿠버네티스와 같은 컨테이너 오케스트레이션 도구를 이용해 배포를 하면서 중요해진 것은 더욱 더 정교한 운영을 위해 어떻게 배포 작업을 자동화하고 서비스 무중단을
유지해야 할지 고민하는 것이다. 쿠버네티스에서 롤링 업데이트와 블루-그린 배포를 하는 방법에 대해 알아보자.

롤링 업데이트

디플로이먼트에서 파드를 교체하는 전략을 .specs.strategy.type 속성에서 정의할 수 있다. 이 속성의 기본값은 RollingUpdate이다. 이 속성을 가진 디플로이먼트는
자신이 관리하는 파드의 내용에 변화가 있을 경우 알아서 롤링 업데이트 방식으로 파드를 교체한다.

롤링 업데이트 동작 제어하기

디플로이먼트의 매니페스트 파일에서 stragegy.rollingUpdate 아래의 maxUnavailable와 maxSurge 속성을 통해 제어할 수 있다.

spec:
  strategy:
    rollingUpdate:
      maxUnavailable: 3
      maxSurge: 4

maxUnavailalbe은 롤링 업데이트 중 동시에 삭제할 수 있는 파드의 최대 개수이다. 이를 늘리면 롤링 업데이트에 걸리는 시간이 짧아지겠지만, 업데이트가 일어나는 동안
남아있는 파드에 몰리는 트래픽의 수가 늘어날 것이다.

maxSurge는 롤링 업데이트 중 동시에 생성하는 파드의 개수이다. 기본값은 replicas의 25퍼센트이다. 이 값을 늘리면 필요한 파드를 빠르게 생성하기 때문에 파드 교체시간이 단축되지만,
순간적으로 필요한 시스템 자원이 급증하는 부작용이 있다.

실행 중인 컨테이너에 대한 헬스 체크 설정

어플리케이션에 따라 컨테이너가 모두 시작된 후에도 요청을 처리할 수 있는 상태가 될 때까지 좀 더 시간이 걸리는 경우가 있다. 이런 경우에는 파드가 running
상태여도 애플리케이션이 제대로 된 응답을 하지 못할 수 있다. 이러한 문제를 해결하기 위해 쿠버네티스는 두 가지 컨테이너 헬스 체크 기능을 제공한다.

livenessProbe

spec:
  template:
    spec:
      containers:
      - name: ~~
        livenessProbe:
          exec:
            command:
            - cat
            - /example.txt
          initialDelaySeconds: 3
          periodSeonds: 5

livenessProbe는 애플리케이션 헬스 체크 기능으로, 애플리케이션이 의존하는 컨테이너 안의 파일이 존재하는지를 확인하는 용도로 사용한다. 위 예시는 컨테이너 내에
example.txt라는 파일이 없으면 헬스 체크 결과가 unhealthy가 되고, 파드를 재시작한다.

readinessProbe

spec:
  template:
    spec:
      containers:
      - name: ~~
        readinessProbe:
          httpGet:
            path: /hc
            port: 8080
          initialDelaySeconds: 15
          timeoutSeconds: 3

readinessProbe는 컨테이너 외부에서 http 요청 같은 트래픽을 발생시켜 이를 처리할 수 있는 상태인지를 확인하는 기능이다. readinessProbe를 설정하면 정상상태가
아닌 컨테이너가 애플리케이션에 투입되는 것을 막을 수 있으므로 반드시 설정해 두는 것이 좋다.

위 두 헬스 체커가 설정되어 있는 컨테이너를 포함한 파드는 상태가 Running이 되어도 헬스 체커를 통과할 때까지 READY의 값이 올라가지 않는다.

블루-그린 배포

블루그린 배포란 기존 서버군과 별도로 새로운 버전이 배포된 서버군을 구성하고, 로드 밸런서 혹은 서비스 디스커버리 수준에서 참조 대상을 교체하는 방식으로 이뤄지는
배포를 말한다. 쿠버네티스에서는 서비스의 셀렉터 레이블을 변경해 참조할 디플로이먼트를 변경할 수 있다. 새로 배포한 버전에 문제가 있어도 셀렉터 레이블의 값을 다시
돌려놓음으로써 손쉽게 롤백이 가능하다. 또한 순간적으로 여러 개의 버전이 공존하게 되는 롤링 업데이트 방식의 문제를 해결할 수 있다.

profile
서울대학교 컴퓨터공학부 github.com/BaekGeunYoung

0개의 댓글