일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- MySQL
- PETERICA
- aws
- mysql 튜닝
- minikube
- kotlin querydsl
- Spring
- APM
- Kubernetes
- kotlin spring
- 공부
- 오블완
- Linux
- AWS EKS
- 티스토리챌린지
- CKA 기출문제
- kotlin
- IntelliJ
- CKA
- 코틀린 코루틴의 정석
- 정보처리기사 실기 기출문제
- Pinpoint
- 정보처리기사 실기
- CloudWatch
- kotlin coroutine
- 기록으로 실력을 쌓자
- Java
- AI
- 정보처리기사실기 기출문제
- Elasticsearch
- Today
- Total
피터의 개발이야기
[Kubernetes] Pod 상태 문제 확인하는 방법, CrashLoopBackOff 원인분석 본문
[Kubernetes] Pod 상태 문제 확인하는 방법, CrashLoopBackOff 원인분석
기록하는 백앤드개발자 2022. 6. 27. 23:16
ㅁ 개요
ㅇ Amazon Elastic Kubernetes Service(Amazon EKS)환경에서 Jenkins를 Pod로 생성하여 사용 중이다
ㅇ 검수계의 경우 비용절감을 위해 일과시간만 사용하다보니 포드가 생성되는 과정에서 에러가 발생할 때가 있다.
ㅇ 젠킨스의 error 상황을 확인하고 조치하는 과정을 정리해 보았다.
ㅁ 포드 상태 확인
kubectl get pod | grep jenkins
ㅇ CrashLoopBackOff 상태로 현재 포드는 기동되어 있지 않은 상태이다.
ㅇ CrashLoopBackOff에 걸린 포드가 반복적으로 시작되고 충돌합니다.
ㅇ "Back-Off restarting failed container" 출력 메시지를 수신하는 경우
Kubernetes가 컨테이너를 시작한 직후에 컨테이너가 종료되었을 수 있다.
ㅇ 현재 Pod의 로그에서 오류를 찾으려면 로그를 확인해야한다.
ㅁ 포드의 LOG 확인
kubectl logs jenkins-kubernetes-6547dbfd9-xsmcj
Error from server (BadRequest): container "jenkins-kubernetes" in pod "jenkins-kubernetes-6547dbfd9-xsmcj" is waiting to start: PodInitializing
ㅇ container가 제대로 생성되지 않는 문제점이 발생하였다.
ㅁ CrashLoopBackOff 상태에서 포드 이벤트 확인
kubectl describe pod jenkins-kubernetes-6547dbfd9-r7jh6
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 54m (x432 over 11h) default-scheduler no nodes available to schedule pods
Warning FailedScheduling 49m default-scheduler 0/1 nodes are available: 1 node(s) had taint {dedicated: rsts}, that the pod didn't tolerate.
Normal SuccessfulAttachVolume 48m attachdetach-controller AttachVolume.Attach succeeded for volume "pvc-aaaaaaa"
Warning FailedCreatePodSandBox 47m kubelet Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container "ae109fef236d4d328a8e864ff96c22b65d23e34e1e3f9767fe9be13b7b0feffa" network for pod "jenkins-kubernetes-6547dbfd9-r7jh6": networkPlugin cni failed to set up pod "jenkins-kubernetes-6547dbfd9-r7jh6_default" network: add cmd: failed to assign an IP address to container
Normal SandboxChanged 47m kubelet Pod sandbox changed, it will be killed and re-created.
Normal Pulled 46m kubelet Successfully pulled image "jenkins/jenkins:lts" in 1m22.581886955s
Normal Pulled 45m kubelet Successfully pulled image "jenkins/jenkins:lts" in 2.245270856s
Normal Pulled 45m kubelet Successfully pulled image "jenkins/jenkins:lts" in 2.187960494s
Normal Pulled 45m kubelet Successfully pulled image "jenkins/jenkins:lts" in 2.214754191s
Normal Created 45m (x4 over 46m) kubelet Created container copy-default-config
Normal Pulling 44m (x5 over 47m) kubelet Pulling image "jenkins/jenkins:lts"
Normal Started 42m (x6 over 46m) kubelet Started container copy-default-config
Warning BackOff 2m46s (x196 over 45m) kubelet Back-off restarting failed container
ㅇ 첫 이벤트는 Node의 CPU 부족으로 인해 node를 할당 받지 못하였다. ( Warning FailedScheduling)
ㅇ 1차 의심을 Node의 리소스 부족을 확인하였다.
ㅁ 쿠버네티스의 리소스 확인
$ kubectl describe deployments.apps jenkins
Containers:
jenkins-kubernetes:
Image: jenkins/jenkins:lts
Ports: 8080/TCP, 50000/TCP
Host Ports: 0/TCP, 0/TCP
Args:
--argumentsRealm.passwd.$(ADMIN_USER)=$(ADMIN_PASSWORD)
--argumentsRealm.roles.$(ADMIN_USER)=admin
Limits:
cpu: 1800m
memory: 2Gi
Requests:
cpu: 50m
memory: 256Mi
ㅇ 리소스 Limits와 Requests에 근본적인 문제는 없어 보였다. CPU의 Limit가 적은 것도 아니었다.
ㅇ Containers > Image tag가 lts, 즉 최신으로 정의 되어 있는 부분이 의심스러웠다.
ㅇ 그래서 Image tag를 lts가 아닌 다운그레이드 버젼을 지정하기로 하였다.
ㅇ 자세한 describe는 아래 더보기를 참조하세요.
Name: jenkins-kubernetes
Namespace: default
CreationTimestamp: Mon, 23 Nov 2020 11:15:18 +0900
Labels: app.kubernetes.io/component=jenkins-master
app.kubernetes.io/instance=jenkins-kubernetes
app.kubernetes.io/managed-by=Tiller
app.kubernetes.io/name=jenkins
helm.sh/chart=jenkins-1.3.6
Annotations: deployment.kubernetes.io/revision: 8
Selector: app.kubernetes.io/component=jenkins-master,app.kubernetes.io/instance=jenkins-kubernetes
Replicas: 1 desired | 1 updated | 1 total | 0 available | 1 unavailable
StrategyType: Recreate
MinReadySeconds: 0
Pod Template:
Labels: app.kubernetes.io/component=jenkins-master
app.kubernetes.io/instance=jenkins-kubernetes
app.kubernetes.io/managed-by=Tiller
app.kubernetes.io/name=jenkins
helm.sh/chart=jenkins-1.3.6
Annotations: checksum/config:
Service Account: jenkins-kubernetes
Init Containers:
copy-default-config:
Image: jenkins/jenkins:lts
Port: <none>
Host Port: <none>
Command:
sh
/var/jenkins_config/apply_config.sh
Limits:
cpu: 1200m
memory: 2Gi
Requests:
cpu: 50m
memory: 256Mi
Environment:
ADMIN_PASSWORD: <set to the key 'jenkins-admin-password' in secret 'jenkins-kubernetes'> Optional: false
ADMIN_USER: <set to the key 'jenkins-admin-user' in secret 'jenkins-kubernetes'> Optional: false
Mounts:
/tmp from tmp (rw)
/usr/share/jenkins/ref/plugins from plugins (rw)
/usr/share/jenkins/ref/secrets/ from secrets-dir (rw)
/var/jenkins_config from jenkins-config (rw)
/var/jenkins_home from jenkins-home (rw)
/var/jenkins_plugins from plugin-dir (rw)
Containers:
jenkins-kubernetes:
Image: jenkins/jenkins:lts
Ports: 8080/TCP, 50000/TCP
Host Ports: 0/TCP, 0/TCP
Args:
--argumentsRealm.passwd.$(ADMIN_USER)=$(ADMIN_PASSWORD)
--argumentsRealm.roles.$(ADMIN_USER)=admin
Limits:
cpu: 1800m
memory: 2Gi
Requests:
cpu: 50m
memory: 256Mi
Liveness: http-get http://:http/login delay=90s timeout=5s period=10s #success=1 #failure=5
Readiness: http-get http://:http/login delay=60s timeout=5s period=10s #success=1 #failure=3
Environment:
JAVA_OPTS: -Dorg.apache.commons.jelly.tags.fmt.timeZone=Asia/Seoul
-Dorg.csanchez.jenkins.plugins.kubernetes.pipeline.ContainerExecDecorator.websocketConnectionTimeout=180
JENKINS_OPTS:
JENKINS_SLAVE_AGENT_PORT: 50000
ADMIN_PASSWORD: <set to the key 'jenkins-admin-password' in secret 'jenkins-kubernetes'> Optional: false
ADMIN_USER: <set to the key 'jenkins-admin-user' in secret 'jenkins-kubernetes'> Optional: false
Mounts:
/tmp from tmp (rw)
/usr/share/jenkins/ref/plugins/ from plugin-dir (rw)
/usr/share/jenkins/ref/secrets/ from secrets-dir (rw)
/var/jenkins_config from jenkins-config (ro)
/var/jenkins_home from jenkins-home (rw)
Volumes:
plugins:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
tmp:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
jenkins-config:
Type: ConfigMap (a volume populated by a ConfigMap)
Name: jenkins-kubernetes
Optional: false
plugin-dir:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
secrets-dir:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
jenkins-home:
Type: PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
ClaimName: jenkins-kubernetes
ReadOnly: false
Conditions:
Type Status Reason
---- ------ ------
Progressing True NewReplicaSetAvailable
Available False MinimumReplicasUnavailable
OldReplicaSets: jenkins-kubernetes-6547dbfd9 (1/1 replicas created)
NewReplicaSet: <none>
Events: <none>
ㅇ 파드 및 컨테이너 리소스 관리에 대한 구체적인 정보는 아래의 링크를 참조하면 된다.
ㅁ Jenkins Docker image version 확인
ㅇ Docker hub의 jenkins/jenkins에서 적절한 Tag를 찾아야한다.
ㅇ Jenkins Tag정보 확인을 위해 DockerHub Jenkins로 이동한다.
ㅇ 최종적으로 찾은 버젼은 2.355-jdk11이었다.
ㅇ 2.2XX 버젼으로 다운 그레이드를 하여 진행하였지만, 플러그인의 호완성 문제가 발견되어 2.355까지 올리는 과정을 거치게 되었다.
ㅁ Kubenetes pod resource edit
kubectl edit deploy jenkins-kubernetes
spec:
containers:
image: jenkins/jenkins:2.355-jdk11
imagePullPolicy: Always
ㅇ image tag를 lts -> 2.355-jdk11로 수정한다.
ㅇ 실제 편집 작업 시의 모습이다.
ㅁ 젠킨스 정상작동 확인