본문 바로가기
Infra & Cloud/DevOps

[Istio] Batch Job에서 불가능한 Side-car 패턴(Envoy proxy)의 한계를 극복해보자 (Kubernetes, Pod, Container, CronJob)

by newstellar 2022. 12. 26.
반응형
참고 자료
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!"]

 

 

 


2022.11.26 - [Infra & Cloud/DevOps] - [Kubernetes] CKA(Certified Kubernetes Administration) 자격증 후기/접수 방법/출제 범위/할인바우처 (+CKAD, CKS 소개)

 

[Kubernetes] CKA(Certified Kubernetes Administration) 자격증 후기/접수 방법/출제 범위/할인바우처 (+CKAD, CKS

CNCF(Cloud Native Computing Foundation) 재단에서 주관하는 CKA(관리), CKAD(개발), CKS(보안) 세 자격증 가운데, 가장 대표적인 CKA 자격증에 대해 알아봅니다. 접수 및 시험 예약 방법, 추천하는 강좌 그리고

newstellar.tistory.com

 

2022.12.13 - [Infra & Cloud/DevOps] - [Kubernetes] Authentication/Authentication(인증/인가) 프로세스 및 User/Role 생성(User, CSR, RBAC, RoleBinding)

 

[Kubernetes] Authentication/Authentication(인증/인가) 프로세스 및 User/Role 생성(User, CSR, RBAC, RoleBinding)

1. 쿠버네티스에서의 User 개념 쿠버네티스에서는 User(human)와 ServiceAccount(machine) 두 종류의 사용자가 존재합니다. User에는 클러스터 관리자 및 사용자(일반 개발자)가 있으며, ServiceAccount는 Prometheus

newstellar.tistory.com

2022.12.14 - [Infra & Cloud/DevOps] - [Kubernetes] NetworkPolicy를 통해 Pod끼리의 트래픽을 통제해보자. (Ingress/Egress, from/to, namespaceSelector, podSelector, port)

 

[Kubernetes] NetworkPolicy를 통해 Pod끼리의 트래픽을 통제해보자. (Ingress/Egress, from/to, namespaceSelector, pod

[ NetworkPolicy ] 1. Ingress vs Egress 네트워크 트래픽은 외부로부터 유입되는 Ingress(inbound)와 내부로부터 외부로 나가는 Egress(outbound)로 구분됩니다. 우리가 공부하고 있는 쿠버네티스는 기본적으로 non-

newstellar.tistory.com

 

반응형

댓글