학습일지/kubernetes

Kubernetes Deep Dive - (5). Deployment

inspirit941 2021. 9. 30. 21:20
반응형

Scaling Application in k8s

스크린샷 2021-09-12 오후 2 04 57

  • Application scalability : 애플리케이션의 트래픽이 증가할 때 / 감소할 때 유연하게 대처할 수 있는 능력

스크린샷 2021-09-12 오후 2 06 43

  • Stateless App : 클라이언트 데이터를 서버에서 세션 단위로 저장하지 않는 애플리케이션.
    • Horizontal Scale에 유리한 구조 (Pod 개수를 늘려서 트래픽에 대응할 수 있음)

스크린샷 2021-09-12 오후 2 08 09

  • Stateful App : 클라이언트 데이터를 서버에 저장하고, 서버의 interal state가 로직에 필요한 형태.

스크린샷 2021-09-12 오후 2 09 20

K8s에서는 ReplicationController를 사용해서 pod의 개수를 조절함.

ReplicationController의 형태

apiVersion: v1
kind: ReplicationController
metadata:
  name: alipne-box-replicationcontroller
spec:
  replicas: 3
  selector:
    app: alpine-box # selector와 metatdata의 label은 동일해야 한다.
  template:
    metadata:
      name: alpine
      labels:
        app: alpine-box # 여기.
    spec:
      containers:
      - name: alpine-box
        image: alpine
        command: ["sleep", "3600"]

ReplicaSet

스크린샷 2021-09-12 오후 5 47 29

  • ReplicationController와 비슷한 기능을 하는 또다른 Object.
  • 핵심 차이점: Selector Support 여부. matchExpression 기능 사용이 가능하다. in / NotIn / Exists 등을 사용할 수 있음

스크린샷 2021-09-12 오후 5 48 47스크린샷 2021-09-12 오후 6 52 06

유의점

  • 일반적인 형태의 Pod을 생성할 때, replicaSet에서 정의한 label은 가급적이면 피하는 게 좋다.
  • replicaSet 객체의 적용범위는 replicaSet에서 정의한 템플릿에만 적용되는 게 아니기 때문.
    • 쉽게 말하면, replicaSet에 정의한 pod label은 bare Pod에 동일한 label을 붙였을 경우 bare pod에도 영향을 줄 수 있다.
    • replicaSet은 pod의 label을 토대로 연산을 적용할 뿐, 그게 어느 템플릿에서 생성되었는지 (bare Pod vs Template in replicaSet)을 따지지 않기 때문

Deployment

스크린샷 2021-09-12 오후 6 57 33

  • ReplicaSet보다 한 단계 추상화된 Object.
  • ReplicaSet과 Pod를 선언형으로 관리함

Deployment의 구조 간단요약

스크린샷 2021-09-12 오후 6 57 47

Deployment가 제공하는 기능

스크린샷 2021-09-12 오후 7 00 56

  • 애플리케이션 pod 생성 + 배포, 버전 업그레이드
  • Rolling Update와 rollback 제공

스크린샷 2021-09-12 오후 7 02 29

업데이트할 버전의 ReplicaSet과 현재 버전의 ReplicaSet을 생성해두기 때문에 Rolling update / Rollback이 용이한 구조.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: chef-server
  labels:
    app: chef
spec:
  replicas: 3
  selector:
    matchLabels:
      app: chef-server # 아래 template의 label과 동일한 key-value여야 한다.
  template:
    metadata:
      labels:
        app: chef-server # 여기. 매칭이 안 되면 이슈 발생.
    spec:
      containers:
        - name: chef-server
          image: 'chef/chefdk:4.9'
          ports:
            - containerPort: 8080
          command:
            - /bin/sh
          args:
            - '-c'
            - echo Hello from the Chef container; sleep 3600
        - name: ubuntu
          image: 'ubuntu:18.04'
          ports:
            - containerPort: 8080
          command:
            - /bin/sh
          args:
            - '-c'
            - echo Hello from the Ubantu container; sleep 3600

스크린샷 2021-09-12 오후 7 10 21

  1. Deployment는 ReplicaSet 객체를 생성한다. 위의 예시 yaml이면 3개의 ReplicaSet을 생성함.
  2. ReplicaSet은 각각 Pod를 생성하고 관리한다. pod는 containers로 정의한 스펙을 의미하고, 스펙에 2개의 container (chef / ubuntu) 가 정의되어 있으므로 get pods를 할 경우 2개의 pod가 확인된다.

스크린샷 2021-09-12 오후 9 12 33

Rollout의 예시 (no downtime)

  • kubectl set image deployment/chef-server=chef/chefdk:4.9.10 --record 으로 container image 변경
  • kubectl rollout status deployment.apps/chef-server 로 rollout update 실행
  • 새로운 pods를 올린 뒤, 이전 pods를 삭제하는 작업이 진행된다.
  • --record 파라미터를 넣으면, kubectl rollout history deployment.apps/chef-server 를 실행했을 때 변경이력을 확인할 수 있다.

Rollback

  • kubectl rollout undo deployment.apps/chef-server를 활용하면 직전 상태로 rollback할 수 있다.
  • rollout history 메소드로 확인 시 revision은 단조증가함.
  • 특정 revision으로 rollback하려면 --to-revision=1 처럼 revision 번호를 파라미터로 넣어주면 된다.

cf. 터미널에서 deployment.yaml 파일을 kubectl edit으로 직접 수정하면, 수정 완료 후 바로 rollout update가 적용된다.

단, edit으로 수정할 경우 rollout history에서 변경이력을 제대로 확인하기 어렵다 (revision은 있지만, record가 남지는 않는다)

반응형