1 - 데몬셋(DaemonSet)에서 롤링 업데이트 수행
이 페이지는 데몬셋에서 롤링 업데이트를 수행하는 방법을 보여준다.
시작하기 전에
쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와 통신할 수 있도록 설정되어 있어야 한다. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 적어도 2개 포함된 클러스터에서 실행하는 것을 추천한다. 만약, 아직 클러스터를 가지고 있지 않다면, minikube를 사용해서 생성하거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.
데몬셋 업데이트 전략
데몬셋에는 두 가지 업데이트 전략 유형이 있다.
OnDelete
:OnDelete
업데이트 전략을 사용하여, 데몬셋 템플릿을 업데이트한 후, 이전 데몬셋 파드를 수동으로 삭제할 때 만 새 데몬셋 파드가 생성된다. 이것은 쿠버네티스 버전 1.5 이하에서의 데몬셋의 동작과 동일하다.RollingUpdate
: 기본 업데이트 전략이다.RollingUpdate
업데이트 전략을 사용하여, 데몬셋 템플릿을 업데이트한 후, 오래된 데몬셋 파드가 종료되고, 새로운 데몬셋 파드는 제어 방식으로 자동 생성된다. 전체 업데이트 프로세스 동안 데몬셋의 최대 하나의 파드가 각 노드에서 실행된다.
롤링 업데이트 수행
데몬셋의 롤링 업데이트 기능을 사용하려면,
.spec.updateStrategy.type
에 RollingUpdate
를 설정해야 한다.
.spec.updateStrategy.rollingUpdate.maxUnavailable
(기본값은 1),
.spec.minReadySeconds
(기본값은 0),
.spec.updateStrategy.rollingUpdate.maxSurge
(기본값은 0)를
설정할 수도 있다.
RollingUpdate
업데이트 전략으로 데몬셋 생성
이 YAML 파일은 'RollingUpdate'를 업데이트 전략으로 사용하여 데몬셋을 명시한다.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
# 이 톨러레이션(toleration)은 데몬셋이 컨트롤 플레인 노드에서 실행될 수 있도록 만든다.
# 컨트롤 플레인 노드가 이 파드를 실행해서는 안 되는 경우, 이 톨러레이션을 제거한다.
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
데몬셋 매니페스트의 업데이트 전략을 확인한 후, 데몬셋을 생성한다.
kubectl create -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml
또는, kubectl apply
로 데몬셋을 업데이트하려는 경우, 동일한 데몬셋을
생성하는 데 kubectl apply
를 사용한다.
kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml
데몬셋 RollingUpdate
업데이트 전략 확인
데몬셋의 업데이트 전략을 확인하고, RollingUpdate
로 설정되어 있는지
확인한다.
kubectl get ds/fluentd-elasticsearch -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}' -n kube-system
시스템에서 데몬셋을 생성하지 않은 경우, 대신 다음의 명령으로 데몬셋 매니페스트를 확인한다.
kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset.yaml --dry-run=client -o go-template='{{.spec.updateStrategy.type}}{{"\n"}}'
두 명령의 출력 결과는 다음과 같아야 한다.
RollingUpdate
출력 결과가 RollingUpdate
가 아닌 경우, 이전 단계로 돌아가서 데몬셋 오브젝트나 매니페스트를
적절히 수정한다.
데몬셋 템플릿 업데이트
RollingUpdate
데몬셋 .spec.template
에 대한 업데이트는 롤링 업데이트를
트리거한다. 새 YAML 파일을 적용하여 데몬셋을 업데이트한다. 이것은 여러 가지 다른 kubectl
명령으로 수행할 수 있다.
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd-elasticsearch
namespace: kube-system
labels:
k8s-app: fluentd-logging
spec:
selector:
matchLabels:
name: fluentd-elasticsearch
updateStrategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
template:
metadata:
labels:
name: fluentd-elasticsearch
spec:
tolerations:
# 이 톨러레이션(toleration)은 데몬셋이 컨트롤 플레인 노드에서 실행될 수 있도록 만든다.
# 컨트롤 플레인 노드가 이 파드를 실행해서는 안 되는 경우, 이 톨러레이션을 제거한다.
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
resources:
limits:
memory: 200Mi
requests:
cpu: 100m
memory: 200Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: varlibdockercontainers
mountPath: /var/lib/docker/containers
readOnly: true
terminationGracePeriodSeconds: 30
volumes:
- name: varlog
hostPath:
path: /var/log
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
선언적 커맨드
구성 파일을
사용하여 데몬셋을 업데이트하는 경우,
kubectl apply
를 사용한다.
kubectl apply -f https://k8s.io/examples/controllers/fluentd-daemonset-update.yaml
명령형 커맨드
명령형 커맨드를
사용하여 데몬셋을 업데이트하는 경우,
kubectl edit
를 사용한다.
kubectl edit ds/fluentd-elasticsearch -n kube-system
컨테이너 이미지만 업데이트
데몬셋 템플릿(예: .spec.template.spec.containers[*].image
)에 의해 정의된 컨테이너 이미지만 업데이트하려면,
kubectl set image
를 사용한다.
kubectl set image ds/fluentd-elasticsearch fluentd-elasticsearch=quay.io/fluentd_elasticsearch/fluentd:v2.6.0 -n kube-system
롤링 업데이트 상태 관찰
마지막으로, 최신 데몬셋 롤링 업데이트의 롤아웃 상태를 관찰한다.
kubectl rollout status ds/fluentd-elasticsearch -n kube-system
롤아웃이 완료되면, 출력 결과는 다음과 비슷하다.
daemonset "fluentd-elasticsearch" successfully rolled out
문제 해결
데몬셋 롤링 업데이트가 더 이상 진행되지 않는다(stuck)
가끔씩, 데몬셋 롤링 업데이트가 더 이상 진행되지 않을 수 있다. 이와 같은 상황이 발생할 수 있는 원인은 다음과 같다.
일부 노드에 리소스가 부족하다
적어도 하나의 노드에서 새 데몬셋 파드를 스케줄링할 수 없어서 롤아웃이 중단되었다. 노드에 리소스가 부족할 때 발생할 수 있다.
이 경우, kubectl get nodes
의 출력 결과와 다음의 출력 결과를 비교하여
데몬셋 파드가 스케줄링되지 않은 노드를 찾는다.
kubectl get pods -l name=fluentd-elasticsearch -o wide -n kube-system
해당 노드를 찾으면, 데몬셋이 아닌 파드를 노드에서 삭제하여 새 데몬셋 파드를 위한 공간을 생성한다.
참고:
삭제된 파드가 컨트롤러에 의해 제어되지 않거나 파드가 복제되지 않은 경우 서비스 중단이 발생한다. 이 때 PodDisruptionBudget정책도 적용되지 않는다.롤아웃 실패
최근 데몬셋 템플릿 업데이트가 중단된 경우(예를 들어, 컨테이너가 계속 크래시되거나, 컨테이너 이미지가 존재하지 않는 경우(종종 오타로 인해)), 데몬셋 롤아웃이 진행되지 않는다.
이 문제를 해결하려면, 데몬셋 템플릿을 다시 업데이트한다. 이전의 비정상 롤아웃으로 인해 새로운 롤아웃이 차단되지는 않는다.
클럭 차이(skew)
데몬셋에 .spec.minReadySeconds
가 명시된 경우, 마스터와 노드 사이의
클럭 차이로 인해 데몬셋이 올바른 롤아웃 진행 상황을 감지할 수
없다.
정리
네임스페이스에서 데몬셋을 삭제한다.
kubectl delete ds fluentd-elasticsearch -n kube-system
다음 내용
- 데몬셋에서 롤백 수행을 참고한다.
- 기존 데몬셋 파드를 채택하기 위한 데몬셋 생성을 참고한다.
2 - 데몬셋(DaemonSet)에서 롤백 수행
이 페이지는 데몬셋에서 롤백을 수행하는 방법을 보여준다.
시작하기 전에
쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와 통신할 수 있도록 설정되어 있어야 한다. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 적어도 2개 포함된 클러스터에서 실행하는 것을 추천한다. 만약, 아직 클러스터를 가지고 있지 않다면, minikube를 사용해서 생성하거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.
쿠버네티스 서버의 버전은 다음과 같거나 더 높아야 함. 버전: 1.7. 버전 확인을 위해서, 다음 커맨드를 실행kubectl version
.
데몬셋에서 롤링 업데이트를 수행하는 방법을 이미 알고 있어야 한다.
데몬셋에서 롤백 수행
1단계: 롤백할 데몬셋 리비전 찾기
마지막 리비전으로 롤백하려는 경우 이 단계를 건너뛸 수 있다.
데몬셋의 모든 리비전을 나열한다.
kubectl rollout history daemonset <daemonset-name>
이 명령은 데몬셋 리비전 목록을 반환한다.
daemonsets "<daemonset-name>"
REVISION CHANGE-CAUSE
1 ...
2 ...
...
- 변경 원인은 데몬셋 어노테이션
kubernetes.io/change-cause
에서 생성 시의 리비전으로 복사된다. 변경 원인 어노테이션에서 실행된 명령을 기록하도록kubectl
에--record=true
를 지정할 수 있다.
특정 리비전의 세부 사항을 보려면 다음을 수행한다.
kubectl rollout history daemonset <daemonset-name> --revision=1
이 명령은 해당 리비전의 세부 사항을 반환한다.
daemonsets "<daemonset-name>" with revision #1
Pod Template:
Labels: foo=bar
Containers:
app:
Image: ...
Port: ...
Environment: ...
Mounts: ...
Volumes: ...
2단계: 특정 리비전으로 롤백
# --to-revision에 1단계에서 얻는 리비전 번호를 지정한다
kubectl rollout undo daemonset <daemonset-name> --to-revision=<revision>
성공하면, 명령은 다음을 반환한다.
daemonset "<daemonset-name>" rolled back
참고:
--to-revision
플래그를 지정하지 않은 경우, kubectl은 가장 최신의 리비전을 선택한다.3단계: 데몬셋 롤백 진행 상황 확인
kubectl rollout undo daemonset
은 서버에 데몬셋 롤백을 시작하도록
지시한다. 실제 롤백은 클러스터 컨트롤 플레인
내에서 비동기적으로 수행된다.
롤백 진행 상황을 보려면 다음의 명령을 수행한다.
kubectl rollout status ds/<daemonset-name>
롤백이 완료되면, 출력 결과는 다음과 비슷하다.
daemonset "<daemonset-name>" successfully rolled out
데몬셋 리비전의 이해
이전 kubectl rollout history
단계에서, 데몬셋 리비전 목록을
얻었다. 각 리비전은 ControllerRevision이라는 리소스에 저장된다.
각 리비전에 저장된 내용을 보려면, 데몬셋 리비전 원시 리소스를 찾는다.
kubectl get controllerrevision -l <daemonset-selector-key>=<daemonset-selector-value>
이 명령은 ControllerRevision의 목록을 반환한다.
NAME CONTROLLER REVISION AGE
<daemonset-name>-<revision-hash> DaemonSet/<daemonset-name> 1 1h
<daemonset-name>-<revision-hash> DaemonSet/<daemonset-name> 2 1h
각 ControllerRevision은 데몬셋 리비전의 어노테이션과 템플릿을 저장한다.
kubectl rollout undo
는 특정 ControllerRevision을 가져와 데몬셋
템플릿을 ControllerRevision에 저장된 템플릿으로 바꾼다.
kubectl rollout undo
는 kubectl edit
또는 kubectl apply
와 같은 다른 명령을 통해
데몬셋 템플릿을 이전 리비전으로 업데이트하는 것과
같다.
참고:
데몬셋 리비전은 롤 포워드만 한다. 즉, 롤백이 완료된 후, 롤백될 ControllerRevision의 리비전 번호(.revision
필드)가 증가한다. 예를 들어,
시스템에 리비전 1과 2가 있고, 리비전 2에서 리비전 1으로 롤백하면,
ControllerRevision은 .revision: 1
에서 .revision: 3
이 된다.문제 해결
- 데몬셋 롤링 업데이트 문제 해결을 참고한다.