본문 바로가기
Docker&k8s

k8s 에서 Application Lifecycle

by fygoo-826 2024. 1. 15.
728x90
반응형

사전 정보

이번 포스팅은 Udemy 강좌를 듣고 요약 정리한 내용입니다. 

개인적인 경험 및 의견도 포함되어 있습니다. 

더 자세한 내용은 공식문서를 확인해주시고, 오타나 문제가 있을 경우 연락바랍니다.

 

---

Rollout Updates / Rollback

 

K8s 에서 Rollout이 진행될 때 절차

  1. 앱을 처음 배포할 때 - 새로운 Deployment를 생성
  2. 해당 deployment는 rollout을 발생
  3. rollout은 새로운 revision을 생성
  4. 버전이 올라가거나 소스코드가 바뀌는 등의 업그레이드가 발생하면, new deployment를 생성
  5. new Rollout이 생성되고, 새로운 revision이 생성

두 개의 revision이 유지되고 있기 때문에 새로운 버전으로 rollout하는 것 / 이전 버전으로 rollback하는 것이 가능하다

 

위 방식을 토대로 ArgoCD 에서는 revision 관리가 가능하다

 

Rollout 명령어 / 상태 확인하는 방법

 

$ kubectl rollout --help
Manage the rollout of one or many resources.

 Valid resource types include:

  *  deployments
  *  daemonsets
  *  statefulsets

Examples:
  # Rollback to the previous deployment
  kubectl rollout undo deployment/abc

  # Check the rollout status of a daemonset
  kubectl rollout status daemonset/foo

  # Restart a deployment
  kubectl rollout restart deployment/abc

  # Restart deployments with the app=nginx label
  kubectl rollout restart deployment --selector=app=nginx

Available Commands:
  history       View rollout history
  pause         Mark the provided resource as paused
  restart       Restart a resource
  resume        Resume a paused resource
  status        Show the status of the rollout
  undo          Undo a previous rollout

Usage:
  kubectl rollout SUBCOMMAND [options]

Use "kubectl <command> --help" for more information about a given command.
Use "kubectl options" for a list of global command-line options (applies to all commands).

 

Deployment Strategy 종류

  • Recreate: 예전 Revision을 다 지운 후에야 새 revision을 띄운다. 자주 사용하지 않는 방식이고, 존재를 모르는 Devops 엔지니어들도 있다. 다만 활용사례가 있음
  • Rolling update: 이전 버전의 pod을 하나씩 죽이고, 새 pod으로 대체하는 방식. downtime이 존재하지 않음. Default 옵션

 

upgrade 내부 동작로직

  • deployment에서 New replicaSet을 생성
  • 이전 replicaset의 pod 개수를 줄이는 동시에, new replicaset의 pod 개수를 늘림

 

Command Argument.

Configuring Application은 아래 세 가지 의미를 포함

  • Configuring Command / Argument on Application
  • Configuring Env variable
  • Configuring secret

예를 들어 JVM 을 띄우는 환경이라 가정해보자. JVM 환경변수 혹은 Hotspot 옵션을 어떻게 추가할 수 있을까? 

  • Dockerfile 에 추가한다
  • Configmap 에 추가한다
  • Secrets 으로 관리한다

위 3가지 방식 중 장단점에 대해 스스로 고민해보자.



 

  • docker run ubuntu를 실행하면, 컨테이너는 실행을 완료하고 종료한다.
  • 종료된 컨테이너까지 확인하려면 docker ps -a 명령어를 써야 한다. 이미 exit한 컨테이너를 확인할 수 있다.

VM과 달리 Container는 OS 호스팅을 하지 않는다. 프로세스 가상화 개념이므로, 프로세스가 끝나는 순간 컨테이너도 종료되어야 한다.

그럼, 어떤 프로세스가 컨테이너에서 실행되는지는 누가 결정하지?

 


Command and Argument in K8s

kubernetes의 yaml 파일에서

  • args : docker 이미지의 파라미터 (cmd) 를 변경하고 싶을 경우. 반드시 문자열 리스트 형태로 입력
  • command : docker 이미지의 entrypoint를 변경하고 싶을 경우 사용

개인적으로 어떻게 관리는 아래와 같이 하고 있다

  • Docker file 에서 실행 명령어 (JAVA, JAVAC 등) 을 Entrypoint 에서 관리한다
  • 기본이 되는 JVM 환경변수들을 CMD 에 작성해놓는다 -> CI 과정까지 영향을 끼칠 수 있음 (이미지 빌드)
  • k8s 에서 해당 이미지를 배포할 때, 옵션의 변경이 필요할 수 있기에 Arg 로 변경할 수 있게 한다
    • 굳이 옵션을 숨겨놓을 필요는 없다고 생각하기 때문에 configmap 으로 관리하면 k9s, lens 를 이용해 쉽게 확인이 가능하다 

Configuring Environment Variable in Applicatioin.

> configmap

> secrets

혹시 `kubectl` 명령어를 이용해서 디코딩 해서 확인려면 링크를 참조한다

Multi Container Pods

마이크로서비스 아키텍처가 등장하면서, 각각의 서비스를 scale up / down하는 작업이 수월해졌다.

하지만 마이크로서비스임에도 불구하고 특정 서비스의 경우 같이 써야 효과적인 경우가 있다. 모니터링을 위해서 혹은 보안을 위한 network ingress, egress 를 관리하는 경우가 대표적인 예시일 것 같다. 정리하자면 아래 2개의 케이스의 경우 init container 혹은 multi container pod 를 사용하면 좋을 것 같다

  • 둘을 굳이 합쳐서 지저분하게 코드를 수정하고 싶지 않다. 각각 개발은 별개로 진행한다.
  • 한 몸처럼 같이 움직이며 동작했으면 좋겠다.

 

LifeCycle을 공유하는 Multi-Container Pod를 사용하는 이유.

  • 같은 네트워크를 사용하므로, 서로 localhost처럼 접근 가능하다
  • 쿠버네티스에서 같은 생애주기(?)
  • 동일한 storage volume을 사용한다.

따라서 두 개의 서비스를 연결하기 위한 Service 오브젝트라던가 Volume Sharing 기능을 별도로 구현할 필요가 없음.

 

생성하는 방법은 간단하다. spec.containers로 Array 선언해서 사용하면 된다.

Design Pattern

 

  • multi-container에서 사용하는 디자인 패턴은 크게 세 개.
    • SideCar: Logging 프로그램을 웹 서비스에 붙이는 식으로 사용할 때
    • Adapters / Ambassador 패턴도 있지만, CAKD 커리큘럼에서 다루는 내용이고 CKA에서는 깊이 다루지 않음.. 궁금하면 찾아보자

sidecar 방식의 멀티 컨테이너 환경이라면, 둘 다 컨테이너가 살아있어야 정상적으로 목적을 달성할 수 있음.

  • 특히 logging의 경우, 로그를 만드는 애플리케이션이 살아 있어야 그 역할을 다할 수 있다. 따라서 이 경우 컨테이너 둘 중에 하나라도 죽으면, Pod 자체가 재시작한다.

그러나

  • 꼭 계속 같이 실행해야만 하는 프로세스가 아닐 수도 있다. 예컨대 처음 시작할 때에는 같이 실행되지만, 목적을 다하면 먼저 종료해도 되는 프로세스.
    • pulls a code / binary from a repository 코드의 경우 pod가 실행되는 시점에 한 번만 실행하면 된다.
  • 또는 특정 service나 DB가 실행될 때까지 대기해야 하는 경우의 애플리케이션이 있다.

위와 같은 특징을 가진 container의 경우 InitContainers 형태로 정의해서 사용할 수 있다.

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']

# pod가 처음 실행될 때 '한 번만' 실행하고 종료되는 프로세스. 이 예시의 경우 initContainer가 정상적으로 종료된 후에야 본래 컨테이너를 실행할 수 있다고 한다.
  initContainers:
  - name: init-myservice
    image: busybox
    command: ['sh', '-c', 'git clone <some-repository-that-will-be-used-by-application> ; done;']

When a POD is first created the initContainer is run, and the process in the initContainer must run to a completion before the real container hosting the application starts. 

You can configure multiple such initContainers as well, like how we did for multi-pod containers. In that case each init container is run one at a time in sequential order.
# 멀티 컨테이너를 initContainer를 사용해 구성할 경우, initContainer는 한 번에 하나씩 순차적으로 실행된다.

# 만약 initContainer 어느 하나라도 중간에 실패할 경우, pod를 죽이고 처음부터 다시 실행한다.
If any of the initContainers fail to complete, Kubernetes restarts the Pod repeatedly until the Init Container succeeds.

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; do echo waiting for myservice; sleep 2; done;']
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']

cf. Self-healing Application

  • replicaSet 또는 replicationController를 사용해서 '특정 pod 개수'를 반드시 유지하도록 할 수 있다.
  • 특정 pod의 상태 체크를 위해 readiness / Liveness 라는 부가 기능을 적용할 수 있다.
  • 이건 CKAD 시험에나 나오는 내용이라서 CKA에서는 다루지 않는다.
728x90
반응형

'Docker&k8s' 카테고리의 다른 글

[K8S] Overview  (1) 2024.06.12
k8s 에서 security  (0) 2024.01.29
k8s에서 Cluster Maintenance  (3) 2024.01.22
k8s 에서 Logging / Monitoring  (0) 2024.01.15