반응형

프로덕션에서 생성하고 사용할 것은 deployment이다.
deployment는 replicaSet을 매니징한다.
1 deployment 당 1서비스이다.

Demo

아래 파일을 생성 후 적용해보면 결과를 확인할 수 있다.

#01-simple-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deploy
spec:
  selector:
    matchLabels:
      app: my-app
  replicas: 3
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: nginx
          image: nginx
kubectl create -f 01-simple-deploy.yaml


적용하면 deployment를 생성하고 해당 deployment가 replicaset을 생성하며 replicaset이 pod들을 생성하는걸 확인할 수 있다.

 

kubectl craete와 kubectl apply의 차이점

Command Description
kubectl create -f [파일이름] 주어진 파일로 리소스를 생성한다.
kubectl create -f . 현재 디렉토리에서 모든 yaml파일을 기반으로 리소스를 생성한다.
kubectl create -f http://vinsguru.com/k8s.yaml 주어진 url로 리소스를 생성한다.

 

Command Description
kubectl apply -f [파일이름]  주어진 파일로 리소스를 생성/업데이트한다.
kubectl apply -f . 현재 디렉토리에서 모든 yaml파일을 기반으로 리소스를 생성/업데이트한다.
kubectl apply -f http://vinsguru.com/k8s.yaml 주어진 url로 리소스를 생성/업데이트한다.


create는 없으면 생성 있으면 에러를 내지만
apply는 없으면 생성 있으면 변경사항을 적용하며, 변경사항이 없으면 무시된다.
위 01 파일이 실행된 삭제된 상태로 아래 명령어들을 차례로 실행해보면 결과를 알 수 있다.

# 정상적으로 생성
kubectl create -f 01-simple-deploy.yaml

# 다시 실행시 에러
kubectl create -f 01-simple-deploy.yaml
=> Error from server (AlreadyExists): error when creating "01-simple-deploy.yaml": deployments.apps "my-deploy" already exists

# 만들어진 deploy 삭제
kubectl delete -f 01-simple-deploy.yaml

# 새로 생성
kubectl apply -f 01-simple-deploy.yaml
=> deployment.apps/my-deploy created

# 변경 사항 적용 (없으면 무시) 몇번을 반복해도 같은 결과만 나온다
kubectl apply -f 01-simple-deploy.yaml
=> deployment.apps/my-deploy configured

 

Log & Port forward

kubectl get 관련 커맨드는 아래와 같다.

Command Description
kubectl get [kind명] 특정 종류의 리소스를 나열한다.
kubectl get [kind명] [resource-name] 특정 리소스를 조회한다.
kubectl get [kind명] --show-labels 라벨을 표시한다.
kubectl get [kind명] -l app=my-app 리소스를 쿼리한다.
kubectl get [kind명] -o yaml 출력형식을 yaml형식으로 지정한다.

 

Command Description
kubectl describe [kind] [resource-name] 리소스 설명하기
kubectl delete [kind] [resource-name] 리소스 삭제하기
kubectl logs [kind]/[resource-name] 로그 확인
kubectl exec -it [kind]/[resource-name] – bash 파드 컨테이너에 접근
kubectl port-forward [kind]/[resource-name] 8080:80  포트포워딩 설정

 

Deployment revisions

deploy는 서비스의 버전을 관리할 수 있다. 아래 예시를 통해 확인해보자

# 02-deploy-rs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-deployment
spec:
  selector:
    matchLabels:
      app: order-service
  replicas: 3
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service-container
          image: vinsdocker/k8s-app:v1
          ports:
            - name: "app-port"
              containerPort: 80
kubectl apply -f 02-deploy-rs.yaml

생성된걸 확인후 아래 파일처럼 변경해보자

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-deployment
spec:
  selector:
    matchLabels:
      app: order-service
  replicas: 2
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service-container
          image: vinsdocker/k8s-app:v1
          ports:
            - name: "app-port"
              containerPort: 80
kubectl apply -f 02-deploy-rs.yaml



이렇게 진행하면 레플리카셋을 2개로 변경한다 컨테이너 스펙을 변경 해야 새로운 변경으로 감지 한다.
이제 v2로 변경해보자

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-deployment
spec:
  selector:
    matchLabels:
      app: order-service
  replicas: 2
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service-container
          image: vinsdocker/k8s-app:v2
          ports:
            - name: "app-port"
              containerPort: 80

# 적용
kubectl apply -f 02-deploy-rs.yaml


명령어를 치고 확인해보면 새로운 레플리카셋이 생기고 기존 레플리카셋의 ready 갯수는 0인걸 확인할 수 있다.

이번에는 환경변수를 변경해보자

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-deployment
spec:
  selector:
    matchLabels:
      app: order-service
  replicas: 2
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service-container
          image: vinsdocker/k8s-app:v2
          env:
            - name: DUMMY
              value: "8"
          ports:
            - name: "app-port"
              containerPort: 80

# 적용
 kubectl apply -f 02-deploy-rs.yaml

변경 사항을 적용해보면 또 새로운 레플리카 셋이 생길 수 있다.
이로 인해 알 수 있는 사실은 컨테이너 동작에 새로운 변경 사항이 생기면 레플리카셋을 새로 생성하지만 레플리카셋의 갯수만 변경하면 단순히 pod의 갯수만 변경되는걸 확인할 수있다.

Rollout history

새로운 파일을 생성한 후 적용하고 포트 포워딩을 설정해주자.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-deployment
spec:
  selector:
    matchLabels:
      app: order-service
  replicas: 2
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service-container
          image: vinsdocker/k8s-app:v1
          ports:
            - name: "app-port"
              containerPort: 80

# 적용
kubectl apply -f 03-deploy-rollout.yaml
# 포트포워딩
kubectl port-forward deploy/order-service-deployment 8080:80

 

이제 localhost:8080으로 접속해보면 V1 화면이 나오는 걸 확인할 수 있다.

이제 v2 로 버젼을 바꿔서 진행해보자

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-deployment
spec:
  selector:
    matchLabels:
      app: order-service
  replicas: 2
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service-container
          image: vinsdocker/k8s-app:v2
          ports:
            - name: "app-port"
              containerPort: 80


kubectl apply -f 03-deploy-rollout.yaml
kubectl port-forward deploy/order-service-deployment 8080:80



이 후 다시 브라우저로 들어간 후 새로고칭하면 V2 화면이 나오는 것을 확인할 수 있다.

이제 터미널에서 아래 명령어를 입력한다.

kubectl rollout history deploy


그럼 2가지 수정본이 나오는것을 확인할 수 있다.



그럼 이제 containers의 버전을 3로 바꾸고 다시 적용해보자

        # 생략
          image: vinsdocker/k8s-app:v3
        # 생략

 kubectl apply -f 03-deploy-rollout.yaml


다시  kubectl rollout history deploy로 확인해보면 3개의 버전이 있는것을 확인할 수 있다.

이제 port-forward를 한 후 localhost:8080으로 접속하면 V3 화면이 뜨는것을 확인할 수 있다.

이제 롤백을 진행해보자

# 이전 버전으로 돌아간다.
kubectl rollout undo deploy/order-service-deployment


다시 port-forward를 한 후 localhost:8080으로 접속하면 V2 화면이 뜨는것을 확인할 수 있다.



다시 history를 확인해보자

kubectl rollout history deploy
# 결과
deployment.apps/order-service-deployment
REVISION  CHANGE-CAUSE
1         <none>
3         <none>
4         <none>


다시 같은 명령을 실행한다

kubectl rollout undo deploy/order-service-deployment

포트포워딩 적용 후 확인해보면 version3로 돌아간것을 확인할 수 있다.

 

Rollback

이전 정의는 그대로 두고 새로 v1 부터 시작한다
또한 annotations을 추가하자

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-deployment
  annotations:
    kubernetes.io/change-cause: "deploying v1"
spec:
  selector:
    matchLabels:
      app: order-service
  replicas: 2
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service-container
          image: vinsdocker/k8s-app:v1
          ports:
            - name: "app-port"
              containerPort: 80


이제 이전 deploy를 삭제하고 적용해보자

kubectl apply -f 03-deploy-rollout.yaml


다시 히스토리를 확인해보면 CHANGE-CAUSE가 바뀐것을 확인할 수 있다.

kubectl rollout history deploy

# 결과
REVISION  CHANGE-CAUSE
1         deploying v1


이제 위 작업에서 컨테이너를 v2 로 변경하고 annotaions도 v2로 변경 후 다시 확인하면 아래와 같다

kubectl rollout history deploy

# 결과
REVISION  CHANGE-CAUSE
1         deploying v1
2         deploying v2


이제 위 작업에서 컨테이너를 v3 로 변경하고 annotaions도 v3로 변경 후 적용하자

#결과
REVISION  CHANGE-CAUSE
1         deploying v1
2         deploying v2
3         deploying v3


이전 섹션에서 3인 상태에서 undo를 실행하면 v2로 가고 v2에서 undo를 실행하면 v3로 돌아갔다.
1로 돌아가보자

kubectl rollout undo deploy/order-service-deployment --to-revision=1

kubectl rollout history deploy

# 결과
REVISION  CHANGE-CAUSE
2         deploying v2
3         deploying v3
4         deploying v1

 

Checking Rollout Changes

간단한 정보만 보면 헷갈릴수 있다.
아래 명령어를 통해 자세히 알 수 있다.

kubectl rollout history deploy --revision=[번호]
ex) kubectl rollout history deploy --revision=4

#결과
deployment.apps/order-service-deployment with revision #4
Pod Template:
  Labels:       app=order-service
        pod-template-hash=56864789dc
  Annotations:  kubernetes.io/change-cause: deploying v1
  Containers:
   order-service-container:
    Image:      vinsdocker/k8s-app:v1
    Port:       80/TCP
    Host Port:  0/TCP
    Environment:        <none>
    Mounts:     <none>
  Volumes:      <none>
  Node-Selectors:       <none>
  Tolerations:  <none>

 

Min ready Seconds (최소 준비 시간)

실제로 애플리케이션이 실행되는데는 시간이 걸린다.
이 때 실제로 걸리는 시간을 deploy yaml 파일에 정의해 둘 수 있다.
원래는 heath check, Probe등으로 확인하며 이 방법은 하드 코딩해서 알려주는 방법이다.

# 04-min-ready-seconds.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deploy
spec:
  minReadySeconds: 10
  selector:
    matchLabels:
      app: my-app
  replicas: 3
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
        - name: nginx
          image: nginx
kubectl apply -f 04-min-ready-seconds.yaml


적용후 watch로 확인해보면 deploy의 AVAILABLE이 10초 뒤에 활성화 되는것을 확인 할 수 있다.

 

배포 전략

만약 version1에서 version2를 배포하고 싶다고 할 때 변경사항을 어떻게 적용할건지를 정의한다.

전략 설명  
recreate 기존 파드를 종료하고 새로운 파드를 생성합니다.
rolling update 변경 사항을 점진적으로 배포합니다. 기존 파드와 새로운 파드가 일시적으로 혼합될 수 있습니다. 아래 속성 들은 0 또는 %가 될 수 있다.
  속성 설명
maxSurge         생성할 수 있는 추가 파드의 최대 수
maxUnavailable         종료할 수 있는 파드의 최대 수

 

recreate 전략

# 05-deploy-recreate.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-deployment
  annotations:
    kubernetes.io/change-cause: "deploying v1"
spec:
  minReadySeconds: 10
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: order-service
  replicas: 2
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service-container
          image: vinsdocker/k8s-app:v1
          ports:
            - name: "app-port"
              containerPort: 80
              
              
# 적용
kubectl apply -f 05-deploy-recreate.yaml


위 파일을 정의 한 후 실행한다.

이 후 아래 파일처럼 변경하고 다시 apply 해보자

apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-deployment
spec:
  minReadySeconds: 10
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: order-service
  replicas: 3
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service-container
          image: vinsdocker/k8s-app:v2
          ports:
            - name: "app-port"
              containerPort: 80

# 적용
kubectl apply -f 05-deploy-recreate.yaml

 

확인해보면 먼저 존재하던 모든 파드들이 삭제되고 새로운 파드들이 새로 한번에 생기는걸 확인할 수 있다.

 

Rolling update - maxSurge

아래 파일을 생성 후 실행해보자

# 06-deploy-max-surge.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-deployment
spec:
  minReadySeconds: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: "100%"
  selector:
    matchLabels:
      app: order-service
  replicas: 3
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service-container
          image: vinsdocker/k8s-app:v1
          ports:
            - name: "app-port"
              containerPort: 80


kubectl apply -f 06-deploy-max-surge.yaml


pod 3개가 켜진것을 확인할 수 있다.
이제 이미지를 v2로 바꿔보자

...
image: vinsdocker/k8s-app:v2
...


이후 실행을 해보면 순간적으로 파드가 6개가 되는것을 확인할 수 있다.


이제 v3를 maxSurge 1 로 변경한 후 적용해보자

...
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
...
image: vinsdocker/k8s-app:v3
...


이제 결과를 살펴보면 하나씩 파드가 교체되는 과정을 확인할 수 있다.

 

Rolling update - maxUnavailable

파일을 생성하고 실행해보자

# 07-deploy-max-unavailable.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: order-service-deployment
spec:
  minReadySeconds: 10
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 1
  selector:
    matchLabels:
      app: order-service
  replicas: 3
  template:
    metadata:
      labels:
        app: order-service
    spec:
      containers:
        - name: order-service-container
          image: vinsdocker/k8s-app:v1
          ports:
            - name: "app-port"
              containerPort: 80


kubectl apply -f 07-deploy-max-unavailable.yaml

v2로 변경한 후 실행해보면 하나씩 변경되는것을 확인할 수 있다

반응형

'Kubernetes' 카테고리의 다른 글

[Kubernetes] Namespace  (0) 2024.12.19
[Kubernetes] Service  (0) 2024.12.17
[Kubernetes] ReplicaSet  (0) 2024.12.12
[Kubernetes] Pod 기초 - 2  (1) 2024.12.06
[Kubernetes] Pod 기초 - 1  (0) 2024.11.27
얼은펭귄