참고 자료
- https://stackoverflow.com/questions/72645650/terminate-istio-proxy-after-cronjob-completion
- https://github.com/wafflestudio/waffle-world/blob/main/apps/snutt-dev/snutt-core/snutt-core.yaml
- https://www.howtogeek.com/devops/how-to-clean-up-old-kubernetes-jobs/
- https://kubernetes.io/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically
1. 문제 정의
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: snutt-ev-batch-lecture-sync
labels:
app: snutt-ev-batch-lecture-sync
namespace: snutt-dev
spec:
concurrencyPolicy: Forbid
schedule: "0 19 * * *"
successfulJobsHistoryLimit: 2
failedJobsHistoryLimit: 3
jobTemplate:
spec:
template:
metadata:
annotations:
sidecar.istio.io/inject: "true"
spec:
restartPolicy: OnFailure
serviceAccountName: snutt-ev-batch
containers:
- image: 405906814034.dkr.ecr.ap-northeast-2.amazonaws.com/snutt-dev/snutt-ev-batch:34
name: snutt-ev-batch-lecture-sync
env:
- name: JOB_NAMES
value: "SYNC_JOB"
- name: JAVA_OPTS
value: "-Duser.timezone=UTC"
- name: SPRING_PROFILES_ACTIVE
value: "dev"
- 수강 편람을 주기적으로 크롤링해오는 Batch Job은 현재 쿠버네티스의 CronJob API 오브젝트로서 동작하고 있습니다.
(가령, "45 */12 * * *" 값이 spec.schedule으로 등록된 CronJob은 매일 12시간 주기로 **시 45분에 동작합니다.)
- 이때 크롤링은 snutt-ev-batch-lecture-sync 컨테이너에서 잘 수행이 되지만 side-car 패턴으로 실행되는 istio를 inject해주면 (spec.template.metadata.annotations.sidecar.istio.io/inject: "true") side-car 컨테이너가 종료되지 않아 Job이 끝나고 Pod가 종료되지 않아 우리가 의도한 CronJob이 제대로 수행되지 않습니다.
2. 해결 방안
- 첫 번째로는 job/cronjob의 spec에 cmd와 args를 정의하여 아래처럼 envoy가 실행 중인 포트에 접근하여 side-car proxy container를 종료하는 것입니다.
command: ["/bin/bash", "-c"]
args:
- |
trap "curl --max-time 2 -s -f -XPOST http://127.0.0.1:15020/quitquitquit" EXIT
while ! curl -s -f http://127.0.0.1:15020/healthz/ready; do sleep 1; done
echo "Ready!"
< your job >
또는,
- command:
- /bin/sh
- -c
- |
until curl -fsI http://localhost:15021/healthz/ready; do echo \"Waiting for Sidecar...\"; sleep 3; done;
echo \"Sidecar available. Running the command...\";
<YOUR_COMMAND>;
x=$(echo $?); curl -fsI -X POST http://localhost:15020/quitquitquit && exit $x
- 두 번째로는 아예 CronJob에 Envoy를 주입하지 않아 서비스메쉬의 범위에서 제외하는 것입니다.
apiVersion: batch/v1beta1
kind: CronJob
metadata:
...
spec:
...
jobTemplate:
spec:
template:
metadata:
annotations:
# disable istio on the pod due to this issue:
# https://github.com/istio/istio/issues/11659
sidecar.istio.io/inject: "false"
위 방식을 사용한다면, 이 포스트 처음에 보여드린 manifest는 다음과 같이 바뀔 수 있겠습니다.
( sidecar.istio.io/inject: "true" -> sidecar.istio.io/inject: "false" )
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: snutt-ev-batch-lecture-sync
labels:
app: snutt-ev-batch-lecture-sync
namespace: snutt-dev
spec:
concurrencyPolicy: Forbid
schedule: "0 19 * * *"
successfulJobsHistoryLimit: 2
failedJobsHistoryLimit: 3
jobTemplate:
spec:
template:
metadata:
annotations:
sidecar.istio.io/inject: "false"
spec:
restartPolicy: OnFailure
serviceAccountName: snutt-ev-batch
containers:
- image: 405906814034.dkr.ecr.ap-northeast-2.amazonaws.com/snutt-dev/snutt-ev-batch:34
name: snutt-ev-batch-lecture-sync
env:
- name: JOB_NAMES
value: "SYNC_JOB"
- name: JAVA_OPTS
value: "-Duser.timezone=UTC"
- name: SPRING_PROFILES_ACTIVE
value: "dev"
- 별개로, Kubernetes v1.23부터 stable하게 지원하는 TTL 메커니즘을 사용하여 Job 또는 CronJob의 status와 관계 없이 일정 시간이 흐르면 Pod를 삭제할 수 있습니다. 다만, manifest를 정의하는 시점에 미리 job의 실행 시간을 예측해서 ttlSecondsAfterFinished 값을 설정해야 하므로 Batch가 제대로 돌지 않았음에도 Pod가 종료되는 불상사가 발생할 가능성도 배제해서는 안 됩니다.
apiVersion: batch/v1
kind: CronJob
metadata:
name: demo-cron
spec:
schedule: "* * * * *"
jobTemplate:
spec:
ttlSecondsAfterFinished: 300
template:
spec:
containers:
- name: demo-cron
image: busybox:latest
command: ["/bin/sh", "-c", "Job complete!"]
[Kubernetes] CKA(Certified Kubernetes Administration) 자격증 후기/접수 방법/출제 범위/할인바우처 (+CKAD, CKS
CNCF(Cloud Native Computing Foundation) 재단에서 주관하는 CKA(관리), CKAD(개발), CKS(보안) 세 자격증 가운데, 가장 대표적인 CKA 자격증에 대해 알아봅니다. 접수 및 시험 예약 방법, 추천하는 강좌 그리고
newstellar.tistory.com
[Kubernetes] Authentication/Authentication(인증/인가) 프로세스 및 User/Role 생성(User, CSR, RBAC, RoleBinding)
1. 쿠버네티스에서의 User 개념 쿠버네티스에서는 User(human)와 ServiceAccount(machine) 두 종류의 사용자가 존재합니다. User에는 클러스터 관리자 및 사용자(일반 개발자)가 있으며, ServiceAccount는 Prometheus
newstellar.tistory.com
[Kubernetes] NetworkPolicy를 통해 Pod끼리의 트래픽을 통제해보자. (Ingress/Egress, from/to, namespaceSelector, pod
[ NetworkPolicy ] 1. Ingress vs Egress 네트워크 트래픽은 외부로부터 유입되는 Ingress(inbound)와 내부로부터 외부로 나가는 Egress(outbound)로 구분됩니다. 우리가 공부하고 있는 쿠버네티스는 기본적으로 non-
newstellar.tistory.com
댓글