Update Korean Documents 74-81

Apply suggestions from code review

update 74-81

translate daemonset.md version 1.27.1 to korean

translate cron-jobs.md version 1.27.1 to korean

Co-Authored-By: Jongwoo Han <jongwooo.han@gmail.com>
pull/46554/head
Yany Choi 2024-05-26 22:27:49 +09:00
parent 4548894b03
commit 24319e233c
8 changed files with 718 additions and 630 deletions

View File

@ -14,44 +14,21 @@ weight: 80
_크론잡은_ 반복 일정에 따라 {{< glossary_tooltip term_id="job" text="잡" >}}을 만든다.
하나의 크론잡 오브젝트는 _크론탭_ (크론 테이블) 파일의 한 줄과 같다.
크론잡은 백업, 리포트 생성 등과 같이 정기적으로 예약된 작업을 수행하기 위한 것이다.
하나의 크론잡 오브젝트는 Unix 시스템의 _크론탭_ (크론 테이블) 파일의 한 줄과 같다.
크론잡은 잡을 [크론](https://ko.wikipedia.org/wiki/Cron) 형식으로 쓰여진 주어진 일정에 따라 주기적으로 동작시킨다.
{{< caution >}}
모든 **크론잡** `일정:` 시간은
{{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}}의 시간대를 기준으로 한다.
크론잡은 한계와 특징이 있다.
예를 들어, 특정 상황에서는 하나의 크론잡이 동시에 여러 개의 잡을 생성할 수 있다. 하단의 [한계](#크론잡의-한계-cron-job-limitations)를 보자.
컨트롤 플레인이 파드 또는 베어 컨테이너에서 kube-controller-manager를 실행하는 경우,
kube-controller-manager 컨테이너에 설정된 시간대는
크론잡 컨트롤러가 사용하는 시간대로 결정한다.
{{< /caution >}}
{{< caution >}}
[v1 CronJob API](/docs/reference/kubernetes-api/workload-resources/cron-job-v1/)은
위에서 설명한 타임존 설정을 공식적으로 지원하지는 않는다.
`CRON_TZ` 또는 `TZ` 와 같은 변수를 설정하는 것은 쿠버네티스 프로젝트에서 공식적으로 지원하지는 않는다.
`CRON_TZ` 또는 `TZ` 와 같은 변수를 설정하는 것은
크론탭을 파싱하고 다음 잡 생성 시간을 계산하는 내부 라이브러리의 구현 상세사항이다.
프로덕션 클러스터에서는 사용을 권장하지 않는다.
{{< /caution >}}
크론잡 리소스에 대한 매니페스트를 생성할 때에는 제공하는 이름이
유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 한다.
이름은 52자 이하여야 한다. 이는 크론잡 컨트롤러는 제공된 잡 이름에
11자를 자동으로 추가하고, 작업 이름의 최대 길이는
63자라는 제약 조건이 있기 때문이다.
컨트롤 플레인이 크론잡에 대한 새 잡과 (간접적으로) 파드를 생성할 때, 크론잡의 `.metadata.name`은 해당 파드의 이름을 지정하는 기준의 일부이다.
크론잡의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름) 값이어야 하지만, 이 경우 파드 호스트네임에 예기치 않은 결과가 발생할 수 있다.
최상의 호환성을 위해, 이름은 [DNS 레이블](/ko/docs/concepts/overview/working-with-objects/names#dns-label-names)에 대한 보다 제한적인 규칙을 따라야 한다.
이름이 DNS 서브도메인인 경우에도 이름은 52자를 넘지 않아야 한다. 이는 크론잡 컨트롤러가 사용자가 제공한 이름에
자동으로 11자를 추가하고, 잡 이름의 길이는 63자를 넘지 않아야 한다는 제약이 있기 때문이다.
<!-- body -->
## 크론잡
크론잡은 백업, 리포트 생성 등의 정기적 작업을 수행하기 위해 사용된다.
각 작업은 무기한 반복되도록 구성해야 한다(예:
1일/1주/1달마다 1회).
작업을 시작해야 하는 해당 간격 내 특정 시점을 정의할 수 있다.
### 예시
## 예시
이 크론잡 매니페스트 예제는 현재 시간과 hello 메시지를 1분마다 출력한다.
@ -60,7 +37,9 @@ kube-controller-manager 컨테이너에 설정된 시간대는
([크론잡으로 자동화된 작업 실행하기](/ko/docs/tasks/job/automated-tasks-with-cron-jobs/)는
이 예시를 더 자세히 설명한다.)
### 크론 스케줄 문법
## 크론잡 스펙 작성하기
### 스케줄 문법
`.spec.schedule` 필드는 반드시 포함되어야 한다. 이 필드의 값은 [크론](https://en.wikipedia.org/wiki/Cron) 문법을 따른다:
```
# ┌───────────── 분 (0 - 59)
@ -74,6 +53,17 @@ kube-controller-manager 컨테이너에 설정된 시간대는
# * * * * *
```
예를 들면, `0 0 13 * 5`은 해당 작업이 매주 금요일 자정에 시작되어야 하고, 매월 13일 자정에도 시작되어야 한다는 뜻이다.
이 표현식은 확장된 "빅시 크론" 스텝 값 또한 포함하고 있다. [FreeBSD 매뉴얼](https://www.freebsd.org/cgi/man.cgi?crontab%285%29)에 따르면
> 스텝 값은 범위와 함께 사용할 수 있다. 범위 뒤에 있는
> `/<숫자>`는 범위 내에서 값을 건너뛰는 주기를 지정한다.
> 예를 들어 `0-23/2`는 시간 필드에서 격시로 실행하도록 지정할 수 있다.
> (V7 표준의 대안은 `0,2,4,6,8,10,12,14,16,18,20,22`이다).
> 스텝은 별표 뒤에도 허용되므로 "매 2시간"이라고 지정 싶다면 `*/2`를 사용하자.
스케줄 내의 물음표(`?`)는 별표 `*`와 같은 의미를 가지고 있다. 즉, 해당 필드에 가능한 모든 값을 의미한다.
| 항목 | 설명 | 상응 표현 |
| ------------- | ------------- |------------- |
@ -85,33 +75,107 @@ kube-controller-manager 컨테이너에 설정된 시간대는
예를 들면, 다음은 해당 작업이 매주 금요일 자정에 시작되어야 하고, 매월 13일 자정에도 시작되어야 한다는 뜻이다.
`0 0 13 * 5`
크론잡 스케줄 표현을 생성하기 위해서 [crontab.guru](https://crontab.guru/)와 같은 웹 도구를 사용할 수도 있다.
## 타임 존
### 잡 템플릿
크론잡에 타임 존이 명시되어 있지 않으면, kube-controller-manager는 로컬 타임 존을 기준으로 스케줄을 해석한다.
`.spec.jobTemplate`는 크론잡이 생성하는 잡의 템플릿을 정의하며, 필수적으로 작성해야 한다.
내부에 중첩되어 있으며 `apiVersion``kind`가 없다는 것을 제외하면 [](/ko/docs/concepts/workloads/controllers/job/)과 동일하다.
{{< glossary_tooltip text="레이블" term_id="label" >}},
{{< glossary_tooltip text="어노테이션" term_id="annotation" >}}과 같이
잡 템플릿의 공통되는 메타데이터를 명시할 수 있다.
잡의 `.spec`을 작성하는 정보에 관해서는 [잡 사양 작성하기](/ko/docs/concepts/workloads/controllers/job/#잡-사양-작성하기)를 참고하자.
{{< feature-state for_k8s_version="v1.25" state="beta" >}}
### 지연된 잡 시작의 데드라인 {#starting-deadline}
`CronJobTimeZone` [기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)를 활성화하면,
크론잡에 대해 타임 존을 명시할 수 있다(기능 게이트를 활성화하지 않거나,
타임 존에 대한 실험적 지원을 제공하지 않는 쿠버네티스 버전을 사용 중인 경우,
클러스터의 모든 크론잡은 타임 존이 명시되지 않은 것으로 동작한다).
`.spec.startingDeadlineSeconds` 필드는 선택사항이다.
이 필드는 잡이 스케줄된 시간을 놓쳤을 때, 잡을 시작하기까지의 데드라인 (초 단위)을 정의한다.
이 기능을 활성화하면, `spec.timeZone`을 유효한 [타임 존](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)으로 지정할 수 있다.
예를 들어, `spec.timeZone: "Etc/UTC"`와 같이 설정하면 쿠버네티스는 협정 세계시를 기준으로 스케줄을 해석한다.
데드라인을 놓치면, 크론잡은 해당 잡을 넘긴다 (이후는 여전히 스케줄링되어 있다).
예를 들어, 백업 관련 잡이 하루에 2번 실행될 때, 8시간 이후까지 실행될 수 있도록 허용할 수 있지만,
그 이후로는 백업이 의미없기 때문에 하지 않을 것이다.
차라리 다음으로 예정된 잡이 실행되는 것을 선호할 것이다.
쿠버네티스는 지정된 데드라인을 놓친 잡들을 실패한 것으로 취급한다.
크론잡의 `startingDeadlineSeconds`을 지정하지 않는다면, 잡 실행에 데드라인은 존재하지 않는다.
`.spec.startingDeadlineSeconds` 필드가 설정되었을 때 (null이 아닐때),
크론잡 컨트롤러는 현재 시간과 다음 예정된 잡 생성시간의 차이를 계산한다.
이 차이가 데드라인보다 높다면, 해당 잡의 실행을 건너뛸 것이다.
예를 들어, `200`으로 설정되어 있으면 잡이 스케줄되고 200초 동안 생성되는 것을 허용한다.
### 동시성 정책
`.spec.concurrencyPolicy` 필드 또한 선택사항이다.
이 필드는 해당 크론잡에 의해 생성된 잡들의 동시 실행을 어떻게 취급할지에 대해 정의한다.
이 스펙은 아래의 동시성 정책 중 한 가지만 지정할 수 있다:
* `Allow` (기본값): 크론잡의 잡이 동시성을 지원한다.
* `Forbid`: 크론잡이 동시성을 지원하지 않는다; 새로운 잡을 생성하는 시간이 되었으나 이전 잡이 완료되지 않았을 때,
크론잡은 새로운 잡을 생성하지 않고 건너뛴다.
* `Replace`: 새로운 잡을 생성하는 시간이 됐으나 이전 잡이 완료되지 않았을 때, 크론잡이 현재 실행되고 있는 잡을
새로운 잡으로 교체한다.
동시성 정책은 같은 크론잡에 의해 생성된 잡 사이에서만 통용된다.
복수의 크론잡이 존재할 때 각자의 잡은 서로에 대해서 항상 동시성을 지원한다.
### 스케줄 지연
선택사항인 `.spec.suspend` 필드를 true로 설정하면 크론잡의 잡의 실행을 연기할 수 있다. 기본값은 false로 지정되어 있다.
이 설정은 크론잡에 의해 이미 시작된 잡들에 영향을 끼치지 _않는다._
이 필드를 true로 설정하면 모든 하위 실행 단위들이 해제할 때까지 지연된다. (스케줄된 상태로 존재하나, 크론잡 컨트롤러가 잡들을 시작하지 않는다)
{{< caution >}}
스케줄된 시간에 지연된 실행들은 놓친 잡으로 포함된다.
[시작 데드라인](#starting-deadline)을 지정하지 않고 존재하는 크론잡의 `spec.suspend``true`에서 `false`로 변경하면
놓친 잡들이 즉시 스케줄된다.
{{< /caution >}}
### 잡 내역 한도
`.spec.successfulJobsHistoryLimit``.spec.failedJobsHistoryLimit` 필드는 선택사항이다.
이 필드들은 완료 그리고 실패한 잡을 얼마나 많이 유지할 것인지 지정한다.
기본값으로 3과 1로 지정된다. 한도를 0으로 설정하면 해당 종류의 잡이 완료된 후에도 해당 잡을 유지하지 않는 것에 해당한다.
잡을 자동적으로 정리하는 다른 방법으로 [완료된 잡을 자동으로 정리](/ko/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically)을 보자.
### 타임 존
{{< feature-state for_k8s_version="v1.27" state="stable" >}}
크론잡에 타임 존이 명시되어 있지 않으면, {{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}}는 로컬 타임 존을 기준으로 스케줄을 해석한다.
크론잡의 `.spec.timeZone`을 유효한 특정 [타임 존](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)으로 지정할 수 있다.
예를 들어, `.spec.timeZone: "Etc/UTC"`와 같이 설정하면 쿠버네티스는 협정 세계시를 기준으로 스케줄을 해석한다.
Go 표준 라이브러리의 타임 존 데이터베이스가 바이너리로 인클루드되며, 시스템에서 외부 데이터베이스를 사용할 수 없을 때 폴백(fallback)으로 사용된다.
## 크론잡의 한계 {#cron-job-limitations}
크론잡은 일정의 실행시간 마다 _약_ 한 번의 잡 오브젝트를 생성한다. "약" 이라고 하는 이유는
특정 환경에서는 두 개의 잡이 만들어지거나, 잡이 생성되지 않기도 하기 때문이다. 보통 이렇게 하지
않도록 해야겠지만, 완벽히 그럴 수는 없다. 따라서 잡은 _멱등원_ 이 된다.
### 타임존 지정 미지원
쿠버네티스 {{< skew currentVersion >}}의 크론잡 API 구현체는 `.spec.schedule` 필드에 `CRON_TZ=UTC * * * * *` 또는 `TZ=UTC * * * * *`와 같이 타임존을 포함할 수 있게 해준다.
이 방법으로 타임존을 지정하는 것은 **공식적으로 지원되지 않는다** (지원한 적도 없다).
`TZ` 또는 `CRON_TZ` 타임존 설정을 포함한 스케줄을 설정하려고 하면 쿠버네티스는 클라이언트에
[warning](/blog/2020/09/03/warnings/)을 보고한다.
향후 쿠버네티스 버전들은 이 비공식적인 타임존 메커니즘을 모두 방지할 예정이다.
### 크론잡의 수정
설계 구조상 크론잡은 _새로운_ 잡을 위한 템플릿을 포함하고 있다.
이미 존재하는 크론잡을 수정하면, 이 수정사항들은 수정이 완료되고 나서 시작할 새로운 잡들에 적용된다.
기존에 이미 시작한 잡 (그리고 파드)들은 변경사항 없이 그대로 유지된다.
즉, 크론잡이 기존 잡이 실행 중인 경우에도 업데이트하지 _않는다_.
### 잡 생성
크론잡은 일정의 실행시간 마다 대략 한 번의 잡 오브젝트를 생성한다. "대략" 이라고 하는 이유는
특정 환경에서는 두 개의 잡이 만들어지거나, 잡이 생성되지 않기도 하기 때문이다. 쿠버네티스는 이러한 상황을
최대한 피하려 하지만, 완벽히 그럴 수는 없다. 따라서 정의하는 잡들은 _멱등원_ 이 되어야 한다.
만약 `startingDeadlineSeconds` 가 큰 값으로 설정되거나, 설정되지 않고(디폴트 값),
`concurrencyPolicy``Allow` 로 설정될 경우, 잡은 항상 적어도 한 번은
@ -143,32 +207,16 @@ Cannot determine if job needs to be started. Too many missed start time (> 100).
크론잡은 오직 그 일정에 맞는 잡 생성에 책임이 있고,
잡은 그 잡이 대표하는 파드 관리에 책임이 있다.
## 컨트롤러 버전 {#new-controller}
쿠버네티스 v1.21부터 크론잡 컨트롤러의 두 번째 버전이
기본 구현이다. 기본 크론잡 컨트롤러를 비활성화하고
대신 원래 크론잡 컨트롤러를 사용하려면, `CronJobControllerV2`
[기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)
플래그를 {{< glossary_tooltip term_id="kube-controller-manager" text="kube-controller-manager" >}}에 전달하고,
이 플래그를 `false` 로 설정한다. 예를 들면, 다음과 같다.
```
--feature-gates="CronJobControllerV2=false"
```
## {{% heading "whatsnext" %}}
* 크론잡이 의존하고 있는 [파드](/ko/docs/concepts/workloads/pods/)와
[](/ko/docs/concepts/workloads/controllers/job/) 두 개념에
대해 배운다.
* 크론잡 `.spec.schedule` 필드의 [형식](https://pkg.go.dev/github.com/robfig/cron/v3#hdr-CRON_Expression_Format)에
* 크론잡 `.spec.schedule` 필드의 구체적인 [형식](https://pkg.go.dev/github.com/robfig/cron/v3#hdr-CRON_Expression_Format)에
대해서 읽는다.
* 크론잡을 생성하고 다루기 위한 지침 및
크론잡 매니페스트의 예제로
[크론잡으로 자동화된 작업 실행](/ko/docs/tasks/job/automated-tasks-with-cron-jobs/)를 읽는다.
* 실패했거나 완료된 잡을 자동으로 정리하도록 하려면,
[완료된 잡을 자동으로 정리](/ko/docs/concepts/workloads/controllers/job/#clean-up-finished-jobs-automatically)를 확인한다.
* `CronJob`은 쿠버네티스 REST API의 일부이다.
{{< api-reference page="workload-resources/cron-job-v1" >}}
오브젝트 정의를 읽고 쿠버네티스 크론잡 API에 대해 이해한다.
자세한 내용은 {{< api-reference page="workload-resources/cron-job-v1" >}}
API 레퍼런스를 참조한다.

View File

@ -105,30 +105,16 @@ kubectl apply -f https://k8s.io/examples/controllers/daemonset.yaml
## 데몬 파드가 스케줄 되는 방법
### 기본 스케줄러로 스케줄
데몬셋은 자격이 되는 모든 노드에서 파드 사본이 실행하도록 보장한다. 데몬셋 컨트롤러는
각 적격 노드에 대해 파드를 생성하고 대상 호스트와 일치하도록 파드의 `spec.affinity.nodeAffinity` 필드를 추가한다.
파드가 생성되면 일반적으로 기본 스케줄러가 넘겨받은 후 `.spec.nodeName` 필드를 설정하여 파드를 대상 호스트에 바인딩한다.
새 파드가 노드에 맞지 않으면, 기본 스케줄러는 새 파드의 [우선순위](/ko/docs/concepts/scheduling-eviction/pod-priority-preemption/#파드-우선순위)에 따라 기존 파드 중 일부를 선점 (축출)할 수 있다.
{{< feature-state for_k8s_version="1.17" state="stable" >}}
사용자는 데몬셋의 `.spec.template.spec.schedulerName` 필드를 설정하여 데몬셋의 파드애 대해
다른 스케줄러를 지정할 수 있다.
데몬셋은 자격이 되는 모든 노드에서 파드 사본이 실행하도록 보장한다. 일반적으로
쿠버네티스 스케줄러에 의해 파드가 실행되는 노드가 선택된다. 그러나
데몬셋 파드는 데몬셋 컨트롤러에 의해 생성되고 스케줄된다.
이에 대한 이슈를 소개한다.
* 파드 동작의 불일치: 스케줄 되기 위해서 대기 중인 일반 파드는 `Pending` 상태로 생성된다.
그러나 데몬셋 파드는 `Pending` 상태로 생성되지 않는다.
이것은 사용자에게 혼란을 준다.
* [파드 선점](/ko/docs/concepts/scheduling-eviction/pod-priority-preemption/)은
기본 스케줄러에서 처리한다. 선점이 활성화되면 데몬셋 컨트롤러는
파드 우선순위와 선점을 고려하지 않고 스케줄 한다.
`ScheduleDaemonSetPods` 로 데몬셋 파드에 `.spec.nodeName` 용어 대신
`NodeAffinity` 용어를 추가해서 데몬셋 컨트롤러 대신 기본
스케줄러를 사용해서 데몬셋을 스케줄할 수 있다. 이후에 기본
스케줄러를 사용해서 대상 호스트에 파드를 바인딩한다. 만약 데몬셋 파드에
이미 노드 선호도가 존재한다면 교체한다(대상 호스트를 선택하기 전에
원래 노드의 어피니티가 고려된다). 데몬셋 컨트롤러는
데몬셋 파드를 만들거나 수정할 때만 이런 작업을 수행하며,
데몬셋의 `spec.template` 은 변경되지 않는다.
`.spec.template.spec.affinity.nodeAffinity` 필드(지정했을 경우)에 지정된 노드 어피니티는
데몬셋 컨트롤러가 적격한 노드를 평가할때 반영되나, 생성된 파드에서는 적격한 노드의 이름과 일치하는 노드 어피니티로 교체된다.
```yaml
nodeAffinity:
@ -141,25 +127,35 @@ nodeAffinity:
- target-host-name
```
또한, 데몬셋 파드에 `node.kubernetes.io/unschedulable:NoSchedule` 이 톨러레이션(toleration)으로
자동으로 추가된다. 기본 스케줄러는 데몬셋 파드를
스케줄링시 `unschedulable` 노드를 무시한다.
### 테인트(taints)와 톨러레이션(tolerations)
데몬 파드는
[테인트와 톨러레이션](/ko/docs/concepts/scheduling-eviction/taint-and-toleration/)을 존중하지만,
다음과 같이 관련 기능에 따라 자동적으로 데몬셋 파드에
톨러레이션을 추가한다.
데몬셋 컨트롤러는 {{< glossary_tooltip text="톨러레이션" term_id="toleration" >}}을
데몬셋 파드에 자동적으로 추가한다.
| 톨러레이션 키 | 영향 | 버전 | 설명 |
| ---------------------------------------- | ---------- | ------- | ------------------------------------------------------------ |
| `node.kubernetes.io/not-ready` | NoExecute | 1.13+ | 네트워크 파티션과 같은 노드 문제가 발생해도 데몬셋 파드는 축출되지 않는다. |
| `node.kubernetes.io/unreachable` | NoExecute | 1.13+ | 네트워크 파티션과 같은 노드 문제가 발생해도 데몬셋 파드는 축출되지 않는다. |
| `node.kubernetes.io/disk-pressure` | NoSchedule | 1.8+ | 데몬셋 파드는 기본 스케줄러에서 디스크-압박(disk-pressure) 속성을 허용한다. |
| `node.kubernetes.io/memory-pressure` | NoSchedule | 1.8+ | 데몬셋 파드는 기본 스케줄러에서 메모리-압박(memory-pressure) 속성을 허용한다. |
| `node.kubernetes.io/unschedulable` | NoSchedule | 1.12+ | 데몬셋 파드는 기본 스케줄러의 스케줄할 수 없는(unschedulable) 속성을 극복한다. |
| `node.kubernetes.io/network-unavailable` | NoSchedule | 1.12+ | 호스트 네트워크를 사용하는 데몬셋 파드는 기본 스케줄러에 의해 이용할 수 없는 네트워크(network-unavailable) 속성을 극복한다. |
{{< table caption="데몬셋 파드를 위한 톨러레이션" >}}
| 톨러레이션 키 | 영향 | 상세정보 |
| ---------------------------------------- | ---------- | ------------------------------------------------------------ |
| [`node.kubernetes.io/not-ready`](/ko/docs/reference/labels-annotations-taints/#node-kubernetes-io-not-ready) | NoExecute | 데몬셋 파드를 상태가 healthy 하지 않거나 파드를 받을 준비가 되지 않는 노드에 스케줄할 수 있다. 이러한 노드에 실행중인 데몬셋 파드들은 축출되지 않는다.|
| [`node.kubernetes.io/unreachable`](/ko/docs/reference/labels-annotations-taints/#node-kubernetes-io-unreachable) | NoExecute | 데몬셋 파드를 노드 컨트롤러에서 접근이 불가능한 노드에 스케줄할 수 있다. 이러한 노드에 실행중인 데몬셋 파드들은 축출되지 않는다.|
| [`node.kubernetes.io/disk-pressure`](/ko/docs/reference/labels-annotations-taints/#node-kubernetes-io-disk-pressure) | NoSchedule | 데몬셋 파드를 디스크 압박(disk pressure) 이슈를 겪고 있는 노드에 데몬셋 파드를 스케줄할 수 있다. |
| [`node.kubernetes.io/memory-pressure`](/ko/docs/reference/labels-annotations-taints/#node-kubernetes-io-memory-pressure) | NoSchedule | 데몬셋 파드를 메모리 압박(memory pressure) 이슈를 겪고 있는 노드에 스케줄할 수 있다. |
| [`node.kubernetes.io/pid-pressure`](/ko/docs/reference/labels-annotations-taints/#node-kubernetes-io-pid-pressure) | NoSchedule | 데몬셋 파드를 프로세스 압박 (process pressure) 이슈를 겪고 있는 노드에 스케줄할 수 있다. |
| [`node.kubernetes.io/unschedulable`](/ko/docs/reference/labels-annotations-taints/#node-kubernetes-io-unschedulable) | NoSchedule | 데몬셋 파드를 스케줄할 수 없는(unschedulable) 상태의 노드에 스케줄할 수 있다. |
| [`node.kubernetes.io/network-unavailable`](/ko/docs/reference/labels-annotations-taints/#node-kubernetes-io-network-unavailable) | NoSchedule | **호스트 네트워킹을 요청하는 데몬셋 파드에 한정된다**. 예를 들어, `spec.hostNetwork: true` 속성을 가진 파드가 있다. 이러한 데몬셋 파드를 네트워크 사용이 불가능한 노드에 스케줄할 수 있다. |
{{< /table>}}
데몬셋의 파드에 대한 톨러레이션 또한 데몬셋의 파드 템플릿에 정의해서 추가할 수 있다.
데몬셋 컨트롤러는 `node.kubernetes.io/unschedulable:NoSchedule` 톨러레이션을 자동으로 설정하기 때문에,
쿠버네티스는 _스케줄 불가능_으로 표시된 노드에서도 데몬셋 파드를 실행할 수 있다.
만약 [클러스터 네트워킹](/ko/docs/concepts/cluster-administration/networking/)과 같은 중요한
노드-레벨 기능을 제공하기 위해 데몬셋을 사용하는 경우, 쿠버네티스가 노드가 준비되기 전에 데몬셋 파드를 배치하는
것이 유용하다. 예를 들어, 특별한 톨러레이션이 없으면 네트워크 플러그인이 해당 노드에서 실행되지 않기 때문에 노드가
준비 상태로 표시되지 않고, 동시에 노드가 아직 준비되지 않았기 때문에 네트워크 플러그인이 해당 노드에서 실행되지
않는 교착 상태에 빠질 수 있다.
## 데몬 파드와 통신

View File

@ -38,6 +38,10 @@ _디플로이먼트(Deployment)_ 는 {{< glossary_tooltip text="파드" term_id=
## 디플로이먼트 생성
디플로이먼트를 생성하기 전 컨테이너의
[환경 변수](/ko/docs/tasks/inject-data-application/define-environment-variable-container/#컨테이너를-위한-환경-변수-정의하기)
를 정의하자.
다음은 디플로이먼트의 예시이다. 예시는 3개의 `nginx` 파드를 불러오기 위한 레플리카셋을 생성한다.
{{% codenew file="controllers/nginx-deployment.yaml" %}}
@ -45,6 +49,8 @@ _디플로이먼트(Deployment)_ 는 {{< glossary_tooltip text="파드" term_id=
이 예시에 대한 설명은 다음과 같다.
* `.metadata.name` 필드에 따라, `nginx-deployment` 이름을 가진 디플로이먼트가 생성된다.
이 이름은 추후 생성될 레플리카셋과 파드의 기초가 된다. 자세한 내용은
[디플로이먼트 사양 작성](#writing-a-deployment-spec)을 참고하자.
* `.spec.replicas` 필드에 따라, 디플로이먼트는 3개의 레플리카 파드를 생성하는 레플리카셋을 생성한다.
* `.spec.selector` 필드는, 생성된 레플리카셋이 관리할 파드를 찾아내는 방법을 정의한다.
이 사례에서는 파드 템플릿에 정의된 레이블(`app: nginx`)을 선택한다.
@ -68,14 +74,12 @@ _디플로이먼트(Deployment)_ 는 {{< glossary_tooltip text="파드" term_id=
시작하기 전에, 쿠버네티스 클러스터가 시작되고 실행 중인지 확인한다.
위의 디플로이먼트를 생성하려면 다음 단계를 따른다.
1. 다음 명령어를 실행해서 디플로이먼트를 생성한다.
```shell
kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
```
2. `kubectl get deployments` 을 실행해서 디플로이먼트가 생성되었는지 확인한다.
만약 디플로이먼트가 여전히 생성 중이면, 다음과 유사하게 출력된다.
@ -122,15 +126,16 @@ kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
* `AGE` 는 애플리케이션의 실행된 시간을 표시한다.
레플리카셋의 이름은 항상 `[DEPLOYMENT-NAME]-[HASH]` 형식으로 된 것을 알 수 있다.
이 이름은 생성될 파드들의 이름의 기초가 된다.
`HASH` 문자열은 레플리카셋의 `pod-template-hash` 레이블과 같다.
6. 각 파드에 자동으로 생성된 레이블을 보려면, `kubectl get pods --show-labels` 를 실행한다.
다음과 유사하게 출력된다.
```
NAME READY STATUS RESTARTS AGE LABELS
nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=3123191453
nginx-deployment-75675f5897-7ci7o 1/1 Running 0 18s app=nginx,pod-template-hash=75675f5897
nginx-deployment-75675f5897-kzszj 1/1 Running 0 18s app=nginx,pod-template-hash=75675f5897
nginx-deployment-75675f5897-qqcnn 1/1 Running 0 18s app=nginx,pod-template-hash=75675f5897
```
만들어진 레플리카셋은 실행 중인 3개의 `nginx` 파드를 보장한다.
@ -172,6 +177,9 @@ kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
```shell
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
```
여기서 `deployment/nginx-deployment`는 디플로이먼트를 나타내고,
`nginx`는 업데이트할 컨테이너를 나타내며
`nginx:1.16.1`는 새로운 이미지와 해당 태그를 나타낸다.
다음과 유사하게 출력된다.
@ -327,7 +335,7 @@ kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml
만약 기존 롤아웃이 진행되는 중에 디플로이먼트를 업데이트하는 경우 디플로이먼트가 업데이트에 따라 새 레플리카셋을 생성하고,
스케일 업하기 시작한다. 그리고 이전에 스케일 업 하던 레플리카셋에 롤오버 한다.
--이것은 기존 레플리카셋 목록에 추가하고 스케일 다운을 할 것이다.
--이것은 기존 레플리카셋 목록에 추가하고 스케일 다운을 할 것이다.
예를 들어 디플로이먼트로 `nginx:1.14.2` 레플리카를 5개 생성을 한다.
하지만 `nginx:1.14.2` 레플리카 3개가 생성되었을 때 디플로이먼트를 업데이트해서 `nginx:1.16.1`
@ -1076,8 +1084,12 @@ echo $?
설정 파일 작업에 대한 일반적인 내용은
[애플리케이션 배포하기](/ko/docs/tasks/run-application/run-stateless-application-deployment/),
컨테이너 구성하기 그리고 [kubectl을 사용해서 리소스 관리하기](/ko/docs/concepts/overview/working-with-objects/object-management/) 문서를 참조한다.
디플로이먼트 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 한다.
컨트롤 플레인이 디플로이먼트에 대한 새 파드를 생성할 때, 디플로이먼트의 `.metadata.name`은 해당 파드의 이름을 지정하는 기준의 일부이다.
디플로이먼트의 이름은 유효한
[DNS 서브도메인](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름) 값이어야 하지만,
이는 파드 호스트네임에 예기치 못한 결과가 발생할 수 있다. 최상의 호환성을 위해, 이름은
[DNS 레이블](/ko/docs/concepts/overview/working-with-objects/names#dns-label-names)에 대한 보다 제한적인 규칙을 따라야 한다.
디플로이먼트에는 [`.spec` 섹션](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)도 필요하다.
@ -1217,11 +1229,9 @@ API 버전 `apps/v1` 에서는 `.spec.selector` 와 `.metadata.labels` 이 설
## {{% heading "whatsnext" %}}
* [파드](/ko/docs/concepts/workloads/pods)에 대해 배운다.
* [파드](/ko/docs/concepts/workloads/pods)에 대해 배운다.
* [디플로이먼트를 사용해서 상태를 유지하지 않는 애플리케이션을 구동한다](/ko/docs/tasks/run-application/run-stateless-application-deployment/).
* `Deployment`는 쿠버네티스 REST API에서 상위-수준 리소스이다.
디플로이먼트 API를 이해하기 위해서
{{< api-reference page="workload-resources/deployment-v1" >}}
오브젝트 정의를 읽는다.
* 디플로이먼트 API를 이해하기 위해 {{< api-reference page="workload-resources/deployment-v1" >}}를 읽는다.
* [PodDisruptionBudget](/ko/docs/concepts/workloads/pods/disruptions/)과
이를 사용해서 어떻게 중단 중에 애플리케이션 가용성을 관리할 수 있는지에 대해 읽는다.
* kubectl를 사용해 [디플로이먼트를 생성한다](/ko/docs/tutorials/kubernetes-basics/deploy-app/deploy-intro/).

View File

@ -56,11 +56,11 @@ job.batch/pi created
{{< tab name="kubectl describe job pi" codelang="bash" >}}
Name: pi
Namespace: default
Selector: controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
Labels: controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
job-name=pi
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"batch/v1","kind":"Job","metadata":{"annotations":{},"name":"pi","namespace":"default"},"spec":{"backoffLimit":4,"template":...
Selector: batch.kubernetes.io/controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
Labels: batch.kubernetes.io/controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
batch.kubernetes.io/job-name=pi
...
Annotations: batch.kubernetes.io/job-tracking: ""
Parallelism: 1
Completions: 1
Start Time: Mon, 02 Dec 2019 15:20:11 +0200
@ -68,8 +68,8 @@ Completed At: Mon, 02 Dec 2019 15:21:16 +0200
Duration: 65s
Pods Statuses: 0 Running / 1 Succeeded / 0 Failed
Pod Template:
Labels: controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
job-name=pi
Labels: batch.kubernetes.io/controller-uid=c9948307-e56d-4b5d-8302-ae2d7b7da67c
batch.kubernetes.io/job-name=pi
Containers:
pi:
Image: perl:5.34.0
@ -86,24 +86,24 @@ Pod Template:
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 14m job-controller Created pod: pi-5rwd7
Normal SuccessfulCreate 21s job-controller Created pod: pi-xf9p4
Normal Completed 18s job-controller Job completed
{{< /tab >}}
{{< tab name="kubectl get job pi -o yaml" codelang="bash" >}}
apiVersion: batch/v1
kind: Job
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"batch/v1","kind":"Job","metadata":{"annotations":{},"name":"pi","namespace":"default"},"spec":{"backoffLimit":4,"template":{"spec":{"containers":[{"command":["perl","-Mbignum=bpi","-wle","print bpi(2000)"],"image":"perl","name":"pi"}],"restartPolicy":"Never"}}}}
creationTimestamp: "2022-06-15T08:40:15Z"
annotations: batch.kubernetes.io/job-tracking: ""
...
creationTimestamp: "2022-11-10T17:53:53Z"
generation: 1
labels:
controller-uid: 863452e6-270d-420e-9b94-53a54146c223
job-name: pi
batch.kubernetes.io/controller-uid: 863452e6-270d-420e-9b94-53a54146c223
batch.kubernetes.io/job-name: pi
name: pi
namespace: default
resourceVersion: "987"
uid: 863452e6-270d-420e-9b94-53a54146c223
resourceVersion: "4751"
uid: 204fb678-040b-497f-9266-35ffa8716d14
spec:
backoffLimit: 4
completionMode: NonIndexed
@ -111,14 +111,14 @@ spec:
parallelism: 1
selector:
matchLabels:
controller-uid: 863452e6-270d-420e-9b94-53a54146c223
batch.kubernetes.io/controller-uid: 863452e6-270d-420e-9b94-53a54146c223
suspend: false
template:
metadata:
creationTimestamp: null
labels:
controller-uid: 863452e6-270d-420e-9b94-53a54146c223
job-name: pi
batch.kubernetes.io/controller-uid: 863452e6-270d-420e-9b94-53a54146c223
batch.kubernetes.io/job-name: pi
spec:
containers:
- command:
@ -127,7 +127,7 @@ spec:
- -wle
- print bpi(2000)
image: perl:5.34.0
imagePullPolicy: Always
imagePullPolicy: IfNotPresent
name: pi
resources: {}
terminationMessagePath: /dev/termination-log
@ -139,8 +139,9 @@ spec:
terminationGracePeriodSeconds: 30
status:
active: 1
ready: 1
startTime: "2022-06-15T08:40:15Z"
ready: 0
startTime: "2022-11-10T17:53:57Z"
uncountedTerminatedPods: {}
{{< /tab >}}
{{< /tabs >}}
@ -149,7 +150,7 @@ status:
잡에 속하는 모든 파드를 기계적으로 읽을 수 있는 양식으로 나열하려면, 다음과 같은 명령을 사용할 수 있다.
```shell
pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath='{.items[*].metadata.name}')
pods=$(kubectl get pods --selector=batch.kubernetes.io/job-name=pi --output=jsonpath='{.items[*].metadata.name}')
echo $pods
```
@ -168,6 +169,12 @@ pi-5rwd7
kubectl logs $pods
```
잡의 로그를 볼 수 있는 다른 방법도 있다.
```shell
kubectl logs jobs/pi
```
출력 결과는 다음과 같다.
```
@ -177,10 +184,17 @@ kubectl logs $pods
## 잡 사양 작성하기
다른 쿠버네티스의 설정과 마찬가지로 잡에는 `apiVersion`, `kind` 그리고 `metadata` 필드가 필요하다.
잡의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 한다.
컨트롤 플레인이 잡에 대한 새 파드를 생성할 때, 잡의
`.metadata.name`은 해당 파드의 이름을 지정하는 기준의 일부이다. 잡의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름) 값이어야 하지만, 이 경우 파드 호스트네임에 예기치 않은 결과가 발생할 수 있다. 최상의 호환성을 위해,
이름은 [DNS 레이블](/ko/docs/concepts/overview/working-with-objects/names#dns-label-names)에 대한 보다 제한적인 규칙을 따라야 한다.
이름이 DNS 서브도메인인 경우에도 이름은 63자를 넘지 않아야 한다.
잡에는 [`.spec` 섹션](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)도 필요하다.
## 잡 레이블
잡 레이블은 `job-name``controller-uid`에 대한 접두사 `batch.kubernetes.io/`가 붙는다.
### 파드 템플릿
`.spec.template``.spec` 의 유일한 필수 필드이다.
@ -271,9 +285,10 @@ _작업 큐_ 잡은 `.spec.completions` 를 설정하지 않은 상태로 두고
각 인덱스에 대해 성공적으로 완료된 파드가 하나 있으면 작업이 완료된 것으로
간주된다. 이 모드를 사용하는 방법에 대한 자세한 내용은
[정적 작업 할당을 사용한 병렬 처리를 위해 인덱싱된 잡](/ko/docs/tasks/job/indexed-parallel-processing-static/)을 참고한다.
참고로, 드물기는 하지만, 동일한 인덱스에 대해 둘 이상의 파드를 시작할 수
있지만, 그 중 하나만 완료 횟수에 포함된다.
{{< note >}}
드물지만, 동일한 인덱스에 대해 둘 이상의 파드가 시작될 수 있다(노드 실패, kubelet 재시작, 파드 축출과 같은 다양한 이유로 인해). 이 경우, 성공적으로 완료된 첫 번째 파드만 완료 횟수에 포함되고 잡의 상태가 업데이트된다. 동일한 인덱스에 대해 실행 중이거나 완료된 다른 파드는 감지되는 즉시 잡 컨트롤러에 의해 삭제된다.
{{< /note >}}
## 파드와 컨테이너 장애 처리하기
@ -315,7 +330,7 @@ _작업 큐_ 잡은 `.spec.completions` 를 설정하지 않은 상태로 두고
종료 중인 파드가 추후 `phase: "Succeded"`로 종료된다고 할지라도,
해당 파드를 실패한 파드로 즉시 간주한다.
### 파드 백오프(backoff) 실패 정책
### 파드 백오프(backoff) 실패 정책{#pod-backoff-failure-policy}
구성에 논리적 오류가 포함되어 있어서 몇 회의 재시도 이후에
잡이 실패되도록 만들어야 하는 경우가 있다.
@ -339,6 +354,95 @@ _작업 큐_ 잡은 `.spec.completions` 를 설정하지 않은 상태로 두고
하려면 `restartPolicy = "Never"` 로 설정하는 것을 권장한다.
{{< /note >}}
### 파드 실패 정책{#pod-failure-policy}
{{< feature-state for_k8s_version="v1.26" state="beta" >}}
{{< note >}}
잡(Job)에 대한 파드 실패 정책은
`JobPodFailurePolicy` [기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)가
클러스터에서 활성화됐을 경우에만 구성할 수 있다. 추가적으로,
파드 장애 정책의 파드 중단 조건 (참조:
[파드 중단 조건](/ko/docs/concepts/workloads/pods/disruptions#pod-disruption-conditions))을
감지하고 처리할 수 있도록 `PodDisruptionConditions` 기능 게이트를 활성화하는 것을 권장한다. 두 기능 게이트 모두
쿠버네티스 {{< skew currentVersion >}}에서 사용할 수 있다.
{{< /note >}}
`.spec.podFailurePolicy` 필드로 정의되는 파드 실패 정책은, 클러스터가
컨테이너 종료 코드와 파드 상태를 기반으로 파드의 실패를
처리하도록 활성화한다.
어떤 상황에서는, 파드의 실패를 처리할 때 잡(Job)의 `.spec.backoffLimit`을 기반으로 하는
[파드 백오프(backoff) 실패 정책](#pod-backoff-failure-policy)에서
제공하는 제어보다 더 나은 제어를 원할 수 있다. 다음은 사용 사례의 몇 가지 예시다.
* 불필요한 파드 재시작을 방지하여 워크로드 실행 비용을 최적화하려면,
파드 중 하나가 소프트웨어 버그를 나타내는 종료 코드와 함께 실패하는 즉시
잡을 종료할 수 있다.
* 중단이 있더라도 잡이 완료되도록 하려면,
중단(예: {{< glossary_tooltip text="선점(preemption)" term_id="preemption" >}},
{{< glossary_tooltip text="API를 이용한 축출(API-initiated Eviction)" term_id="api-eviction" >}}
또는 축출 기반 {{< glossary_tooltip text="테인트(Taints)" term_id="taint" >}})으로 인한
파드 실패를 무시하여 `.spec.backoffLimit` 재시도 한도에 포함되지 않도록 할 수 있다.
위의 사용 사례를 충족하기 위해
`.spec.podFailurePolicy` 필드에 파드 실패 정책을 구성할 수 있다.
이 정책은 컨테이너 종료 코드 및 파드 상태를 기반으로 파드 실패를 처리할 수 있다.
다음은 `podFailurePolicy`를 정의하는 잡의 매니페스트이다.
{{% codenew file="/controllers/job-pod-failure-policy-example.yaml" %}}
위 예시에서, 파드 실패 정책의 첫 번째 규칙은 `main` 컨테이너가 42 종료코드와
함께 실패하면 잡도 실패로 표시되는 것으로
지정한다. 다음은 구체적으로 `main` 컨테이너에 대한 규칙이다.
- 종료 코드 0은 컨테이너가 성공했음을 의미한다.
- 종료 코드 42는 **전체 잡**이 실패했음을 의미한다.
- 다른 모든 종료 코드는 컨테이너 및 전체 파드가 실패했음을
나타낸다. 재시작 횟수인 `backoffLimit`까지 파드가
다시 생성된다. 만약 `backoffLimit`에 도달하면 **전체 잡**이 실패한다.
{{< note >}}
파드 템플릿이 `restartPolicy: Never`로 지정되었기 때문에,
kubelet은 특정 파드에서 `main` 컨테이너를 재시작하지 않는다.
{{< /note >}}
`DisruptionTarget` 컨디션을 갖는 실패한 파드에 대해
`Ignore` 동작을 하도록 명시하고 있는 파드 실패 정책의 두 번째 규칙으로 인해,
`.spec.backoffLimit` 재시도 한도 계산 시 파드 중단(disruption)은 횟수에서 제외된다.
{{< note >}}
파드 실패 정책 또는 파드 백오프 실패 정책에 의해 잡이 실패하고,
잡이 여러 파드를 실행중이면, 쿠버네티스는 아직 보류(Pending) 또는
실행(Running) 중인 해당 잡의 모든 파드를 종료한다.
{{< /note >}}
다음은 API의 몇 가지 요구 사항 및 의미이다.
- 잡에 `.spec.podFailurePolicy` 필드를 사용하려면,
`.spec.restartPolicy``Never`로 설정된 잡의 파드 템플릿 또한 정의해야 한다.
- `spec.podFailurePolicy.rules`에 기재한 파드 실패 정책 규칙은 기재한 순서대로 평가된다.
파드 실패 정책 규칙이 파드 실패와 매치되면 나머지 규칙은 무시된다.
파드 실패와 매치되는 파드 실패 정책 규칙이 없으면
기본 처리 방식이 적용된다.
- `spec.podFailurePolicy.rules[*].containerName`에 컨테이너 이름을 지정하여 파드 실패 규칙을 특정 컨테이너에게만 제한할 수 있다.
컨테이너 이름을 지정하지 않으면 파드 실패 규칙은 모든 컨테이너에 적용된다.
컨테이너 이름을 지정한 경우,
이는 파드 템플릿의 컨테이너 또는 `initContainer` 이름 중 하나와 일치해야 한다.
- 파드 실패 정책이 `spec.podFailurePolicy.rules[*].action`과 일치할 때 취할 동작을 지정할 수 있다.
사용 가능한 값은 다음과 같다.
- `FailJob`: 파드의 잡을 `Failed`로 표시하고
실행 중인 모든 파드를 종료해야 함을 나타낸다.
- `Ignore`: `.spec.backoffLimit`에 대한 카운터가 증가하지 않아야 하고
대체 파드가 생성되어야 함을 나타낸다.
- `Count`: 파드가 기본 방식으로 처리되어야 함을 나타낸다.
`.spec.backoffLimit`에 대한 카운터가 증가해야 한다.
{{< note >}}
`podFailurePolicy`를 사용하는 경우, 잡 컨트롤러는 `Failed` 단계의 파드만 일치시킨다. 삭제 타임스탬프가 있는 파드가 최종 단계(`Failed` 또는 `Succeeded`)에 있지 않으면 여전히 종료 중인 것으로 간주된다. 이는 종료 중인 파드가 최종 단계에 도달할 때까지 [추적 파이널라이저](#job-tracking-with-finalizers)를 유지함을 의미한다. 쿠버네티스 1.27 이후로 Kubelet은 삭제된 파드를 최종 단계로 전환한다(참조: [파드 단계](/ko/docs/concepts/workloads/pods/pod-lifecycle/#파드의-단계)). 이는 삭제된 파드가 잡 컨트롤러에 의해 파이널라이저가 제거되도록 한다.
{{< /note >}}
## 잡의 종료와 정리
잡이 완료되면 파드가 더 이상 생성되지도 않지만, [일반적으로는](#pod-backoff-failure-policy) 삭제되지도 않는다.
@ -620,14 +724,7 @@ Events:
### 가변적 스케줄링 지시
{{< feature-state for_k8s_version="v1.23" state="beta" >}}
{{< note >}}
이 기능을 사용하려면,
[API 서버](/docs/reference/command-line-tools-reference/kube-apiserver/)에
`JobMutableNodeSchedulingDirectives` [기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)를 활성화해야 한다.
이 기능은 기본적으로 활성화되어 있다.
{{< /note >}}
{{< feature-state for_k8s_version="v1.27" state="stable" >}}
병렬 잡에서 대부분의 경우 파드를 특정 제약 조건 하에서 실행하고 싶을 것이다.
(예를 들면 동일 존에서 실행하거나, 또는 GPU 모델 x 또는 y를 사용하지만 둘을 혼합하지는 않는 등)
@ -642,7 +739,7 @@ Events:
이는 이전에 재개된 적이 없는 중지된 잡에 대해서만 허용된다.
잡의 파드 템플릿 필드 중, 노드 어피니티(node affinity), 노드 셀렉터(node selector),
톨러레이션(toleration), 레이블(label), 어노테이션(annotation) 업데이트가 가능하다.
톨러레이션(toleration), 레이블(label), 어노테이션(annotation), 그리고 [스케줄링게이트](/ko/docs/concepts/scheduling-eviction/pod-scheduling-readiness/)는 업데이트가 가능하다.
### 자신의 파드 셀렉터를 지정하기
@ -685,12 +782,12 @@ metadata:
spec:
selector:
matchLabels:
controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
batch.kubernetes.io/controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
...
```
그런 이후에 이름이 `new` 인 새 잡을 생성하고, 동일한 셀렉터를 명시적으로 지정한다.
기존 파드에는 `controller-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002`
기존 파드에는 `batch.kubernetes.io/controller-uid=a8f3d00d-c6d2-11e5-9f87-42010af00002`
레이블이 있기에 잡 `new` 에 의해서도 제어된다.
시스템이 일반적으로 자동 생성하는 셀렉터를 사용하지 않도록 하기 위해
@ -705,7 +802,7 @@ spec:
manualSelector: true
selector:
matchLabels:
controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
batch.kubernetes.io/controller-uid: a8f3d00d-c6d2-11e5-9f87-42010af00002
...
```
@ -713,89 +810,6 @@ spec:
`manualSelector: true` 를 설정하면 시스템에게 사용자가 무엇을 하는지 알고 있으며
이런 불일치를 허용한다고 알릴 수 있다.
### 파드 실패 정책{#pod-failure-policy}
{{< feature-state for_k8s_version="v1.26" state="beta" >}}
{{< note >}}
잡(Job)에 대한 파드 실패 정책은
`JobPodFailurePolicy` [기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)가
클러스터에서 활성화됐을 경우에만 구성할 수 있다. 추가적으로,
파드 장애 정책의 파드 중단 조건 (참조:
[파드 중단 조건](/ko/docs/concepts/workloads/pods/disruptions#pod-disruption-conditions))을
감지하고 처리할 수 있도록 `PodDisruptionConditions` 기능 게이트를 활성화하는 것을 권장한다. 두 기능 게이트 모두
쿠버네티스 {{< skew currentVersion >}}에서 사용할 수 있다.
{{< /note >}}
`.spec.podFailurePolicy` 필드로 정의되는 파드 실패 정책은, 클러스터가
컨테이너 종료 코드와 파드 상태를 기반으로 파드의 실패를
처리하도록 활성화한다.
어떤 상황에서는, 파드의 실패를 처리할 때 잡(Job)의 `.spec.backoffLimit`을 기반으로 하는
[파드 백오프(backoff) 실패 정책](#pod-backoff-failure-policy)에서
제공하는 제어보다 더 나은 제어를 원할 수 있다. 다음은 사용 사례의 몇 가지 예시다.
* 불필요한 파드 재시작을 방지하여 워크로드 실행 비용을 최적화하려면,
파드 중 하나가 소프트웨어 버그를 나타내는 종료 코드와 함께 실패하는 즉시
잡을 종료할 수 있다.
* 중단이 있더라도 잡이 완료되도록 하려면,
중단(예: {{< glossary_tooltip text="선점(preemption)" term_id="preemption" >}},
{{< glossary_tooltip text="API를 이용한 축출(API-initiated Eviction)" term_id="api-eviction" >}}
또는 축출 기반 {{< glossary_tooltip text="테인트(Taints)" term_id="taint" >}})으로 인한
파드 실패를 무시하여 `.spec.backoffLimit` 재시도 한도에 포함되지 않도록 할 수 있다.
위의 사용 사례를 충족하기 위해
`.spec.podFailurePolicy` 필드에 파드 실패 정책을 구성할 수 있다.
이 정책은 컨테이너 종료 코드 및 파드 상태를 기반으로 파드 실패를 처리할 수 있다.
다음은 `podFailurePolicy`를 정의하는 잡의 매니페스트이다.
{{% codenew file="/controllers/job-pod-failure-policy-example.yaml" %}}
위 예시에서, 파드 실패 정책의 첫 번째 규칙은 `main` 컨테이너가 42 종료코드와
함께 실패하면 잡도 실패로 표시되는 것으로
지정한다. 다음은 구체적으로 `main` 컨테이너에 대한 규칙이다.
- 종료 코드 0은 컨테이너가 성공했음을 의미한다.
- 종료 코드 42는 **전체 잡**이 실패했음을 의미한다.
- 다른 모든 종료 코드는 컨테이너 및 전체 파드가 실패했음을
나타낸다. 재시작 횟수인 `backoffLimit`까지 파드가
다시 생성된다. 만약 `backoffLimit`에 도달하면 **전체 잡**이 실패한다.
{{< note >}}
파드 템플릿이 `restartPolicy: Never`로 지정되었기 때문에,
kubelet은 특정 파드에서 `main` 컨테이너를 재시작하지 않는다.
{{< /note >}}
`DisruptionTarget` 컨디션을 갖는 실패한 파드에 대해
`Ignore` 동작을 하도록 명시하고 있는 파드 실패 정책의 두 번째 규칙으로 인해,
`.spec.backoffLimit` 재시도 한도 계산 시 파드 중단(disruption)은 횟수에서 제외된다.
{{< note >}}
파드 실패 정책 또는 파드 백오프 실패 정책에 의해 잡이 실패하고,
잡이 여러 파드를 실행중이면, 쿠버네티스는 아직 보류(Pending) 또는
실행(Running) 중인 해당 잡의 모든 파드를 종료한다.
{{< /note >}}
다음은 API의 몇 가지 요구 사항 및 의미이다.
- 잡에 `.spec.podFailurePolicy` 필드를 사용하려면,
`.spec.restartPolicy``Never`로 설정된 잡의 파드 템플릿 또한 정의해야 한다.
- `spec.podFailurePolicy.rules`에 기재한 파드 실패 정책 규칙은 기재한 순서대로 평가된다.
파드 실패 정책 규칙이 파드 실패와 매치되면 나머지 규칙은 무시된다.
파드 실패와 매치되는 파드 실패 정책 규칙이 없으면
기본 처리 방식이 적용된다.
- `spec.podFailurePolicy.rules[*].containerName`에 컨테이너 이름을 지정하여 파드 실패 규칙을 특정 컨테이너에게만 제한할 수 있다.
컨테이너 이름을 지정하지 않으면 파드 실패 규칙은 모든 컨테이너에 적용된다.
컨테이너 이름을 지정한 경우,
이는 파드 템플릿의 컨테이너 또는 `initContainer` 이름 중 하나와 일치해야 한다.
- 파드 실패 정책이 `spec.podFailurePolicy.rules[*].action`과 일치할 때 취할 동작을 지정할 수 있다.
사용 가능한 값은 다음과 같다.
- `FailJob`: 파드의 잡을 `Failed`로 표시하고
실행 중인 모든 파드를 종료해야 함을 나타낸다.
- `Ignore`: `.spec.backoffLimit`에 대한 카운터가 증가하지 않아야 하고
대체 파드가 생성되어야 함을 나타낸다.
- `Count`: 파드가 기본 방식으로 처리되어야 함을 나타낸다.
`.spec.backoffLimit`에 대한 카운터가 증가해야 한다.
### 종료자(finalizers)를 이용한 잡 추적
{{< feature-state for_k8s_version="v1.26" state="stable" >}}
@ -826,6 +840,14 @@ API 서버로부터 제거된 파드가 있는지에 대해 알려준다. 이를
그 대신, 파드 종료자를 사용하여
추적이 가능한 잡을 재생성하면 된다.
### 탄력적 인덱스 잡 (Elastic Indexed Jobs)
{{< feature-state for_k8s_version="v1.27" state="beta" >}}
인덱스 잡(Indexed Jobs)은 `.spec.parallelism``.spec.completions`를 동시에 변경하여 `.spec.parallelism == .spec.completions`가 되도록 조정함으로써 스케일 업 또는 스케일 다운할 수 있다. `ElasticIndexedJob` [기능 게이트](/ko/docs/reference/command-line-tools-reference/feature-gates/)가 [API 서버](/ko/docs/reference/command-line-tools-reference/kube-apiserver/)에서 비활성화된 경우, `.spec.completions`는 변경할 수 없다.
탄력적 인덱스 잡은 MPI, Horovord, Ray, PyTorch 학습 잡과 같이 인덱스 잡을 스케일링해야 하는 배치 워크로드와 같은 유스케이스가 있다.
## 대안
### 베어(Bare) 파드

View File

@ -69,7 +69,7 @@ kubectl get rs
그리고 생성된 프런트엔드를 볼 수 있다.
```shell
```
NAME DESIRED CURRENT READY AGE
frontend 3 3 3 6s
```
@ -118,7 +118,7 @@ kubectl get pods
다음과 유사한 파드 정보를 볼 수 있다.
```shell
```
NAME READY STATUS RESTARTS AGE
frontend-b2zdv 1/1 Running 0 6m36s
frontend-vcmts 1/1 Running 0 6m36s
@ -228,8 +228,9 @@ pod2 1/1 Running 0 36s
레플리카셋은 모든 쿠버네티스 API 오브젝트와 마찬가지로 `apiVersion`, `kind`, `metadata` 필드가 필요하다.
레플리카셋에 대한 `kind` 필드의 값은 항상 레플리카셋이다.
레플리카셋 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 한다.
컨트롤 플레인이 레플리케이션 컨트롤러에 대한 새 파드를 생성할 때, 레플리케이션 컨트롤러의 `.metadata.name`은 해당 파드의 이름을 지정하는 기준의 일부이다.
레플리케이션 컨트롤러의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름) 값이어야 하지만, 파드 호스트네임에 예기치 않은 결과가 발생할 수 있다.
최상의 호환성을 위해, 이름은 [DNS 레이블](/ko/docs/concepts/overview/working-with-objects/names#dns-label-names)에 대한 보다 제한적인 규칙을 따라야 한다.
레플리카셋도 [`.spec` 섹션](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)이 필요하다.
@ -284,8 +285,8 @@ REST API 또는 `client-go` 라이브러리를 이용할 때는 -d 옵션으로
```shell
kubectl proxy --port=8080
curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
> -H "Content-Type: application/json"
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Foreground"}' \
-H "Content-Type: application/json"
```
### 레플리카셋만 삭제하기
@ -299,8 +300,8 @@ REST API 또는 `client-go` 라이브러리를 이용할 때는 `propagationPoli
```shell
kubectl proxy --port=8080
curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/frontend' \
> -d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
> -H "Content-Type: application/json"
-d '{"kind":"DeleteOptions","apiVersion":"v1","propagationPolicy":"Orphan"}' \
-H "Content-Type: application/json"
```
원본이 삭제되면 새 레플리카셋을 생성해서 대체할 수 있다.
@ -338,8 +339,8 @@ curl -X DELETE 'localhost:8080/apis/apps/v1/namespaces/default/replicasets/fron
{{< feature-state for_k8s_version="v1.22" state="beta" >}}
[`controller.kubernetes.io/pod-deletion-cost`](/ko/docs/reference/labels-annotations-taints/#pod-deletion-cost) 어노테이션을 이용하여,
레플리카셋을 스케일 다운할 때 어떤 파드부터 먼저 삭제할지에 대한 우선순위를 설정할 수 있다.
[`controller.kubernetes.io/pod-deletion-cost`](/ko/docs/reference/labels-annotations-taints/#pod-deletion-cost)
어노테이션을 이용하여, 레플리카셋을 스케일 다운할 때 어떤 파드부터 먼저 삭제할지에 대한 우선순위를 설정할 수 있다.
이 어노테이션은 파드에 설정되어야 하며, [-2147483647, 2147483647] 범위를 갖는다.
이 어노테이션은 하나의 레플리카셋에 있는 다른 파드와의 상대적 삭제 비용을 나타낸다.
@ -355,8 +356,8 @@ kube-apiserver와 kube-controller-manager에 대해 `PodDeletionCost`
{{< note >}}
- 이 기능은 best-effort 방식으로 동작하므로, 파드 삭제 순서를 보장하지는 않는다.
- 이 값을 자주 바꾸는 것은 피해야 한다 (예: 메트릭 값에 따라 변경).
apiserver에서 많은 양의 파드 업데이트를 동반하기 때문이다.
{{< /note >}}
apiserver에서 많은 양의 파드 업데이트를 동반하기 때문이다.
{{< /note >}}
#### 사용 예시
@ -440,4 +441,3 @@ kubectl autoscale rs frontend --max=10 --min=3 --cpu-percent=50
오브젝트 정의를 읽는다.
* [PodDisruptionBudget](/ko/docs/concepts/workloads/pods/disruptions/)과
이를 사용해서 어떻게 중단 중에 애플리케이션 가용성을 관리할 수 있는지에 대해 읽는다.

View File

@ -112,11 +112,14 @@ nginx-3ntk0 nginx-4ok8v nginx-qrm3m
다른 형식의 파일인 `replication.yaml` 의 것과 동일하다. `--output=jsonpath`
반환된 목록의 각 파드의 이름을 출력하도록 하는 옵션이다.
## 레플리케이션 컨트롤러의 Spec 작성
## 레플리케이션 컨트롤러의 매니페스트 작성
다른 모든 쿠버네티스 컨피그와 마찬가지로 레플리케이션 컨트롤러는 `apiVersion`, `kind`, `metadata` 와 같은 필드가 필요하다.
레플리케이션 컨트롤러 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 한다.
컨트롤 플레인이 레플리케이션 컨트롤러에 대한 새로운 파드를 생성할 때, 레플리케이션 컨트롤러의 `.metadata.name`은 해당 파드의 이름을 지정하는 기준의 일부이다.
레플리케이션 컨트롤러의 이름은 유효한 [DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름) 값이어야 하지만, 파드 호스트네임에 예기치 않은 결과가 발생할 수 있다.
최고의 호환성을 위해, 이름은 [DNS 레이블](/ko/docs/concepts/overview/working-with-objects/names#dns-label-names)에 대한 보다 제한적인 규칙을 따라야 한다.
환경설정 파일의 동작에 관련된 일반적인 정보는 [쿠버네티스 오브젝트 관리](/ko/docs/concepts/overview/working-with-objects/object-management/)를 참고한다.
레플리케이션 컨트롤러는 또한 [`.spec` section](https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status)도 필요하다.

View File

@ -121,7 +121,7 @@ spec:
안정적인 스토리지를 제공한다.
스테이트풀셋 오브젝트의 이름은 유효한
[DNS 서브도메인 이름](/ko/docs/concepts/overview/working-with-objects/names/#dns-서브도메인-이름)이어야 한다.
[DNS 레이블](/ko/docs/concepts/overview/working-with-objects/names#dns-label-names)이어야 한다.
### 파드 셀렉터
@ -160,7 +160,7 @@ N개의 [레플리카](#레플리카)가 있는 스테이트풀셋은 스테이
### 시작 순서
{{< feature-state for_k8s_version="v1.26" state="alpha" >}}
{{< feature-state for_k8s_version="v1.27" state="beta" >}}
`.spec.ordinals`은 각 파드에 할당할 순서에 대한
정수값을 설정할 수 있게 해주는 선택적인 필드로, 기본값은 nil이다.
@ -360,7 +360,7 @@ web-0이 실패할 경우 web-1은 web-0이 Running 및 Ready 상태가
## 퍼시스턴트볼륨클레임 유보
{{< feature-state for_k8s_version="v1.23" state="alpha" >}}
{{< feature-state for_k8s_version="v1.27" state="beta" >}}
선택적 필드인 `.spec.persistentVolumeClaimRetentionPolicy`
스테이트풀셋의 생애주기동안 PVC를 삭제할 것인지,

View File

@ -4,71 +4,80 @@
title: 완료된 잡 자동 정리
content_type: concept
weight: 70
description: >-
실행이 완료된 오래된 작업을 정리하기 위한 time-to-live 메커니즘
---
<!-- overview -->
{{< feature-state for_k8s_version="v1.23" state="stable" >}}
완료-이후-TTL(TTL-after-finished) {{<glossary_tooltip text="컨트롤러" term_id="controller">}}는
실행이 완료된 리소스 오브젝트의 수명을 제한하는
잡이 완료되면, 잡이 성공했는지 실패했는지 알 수 있도록 API에 보관(즉시 삭제하지 않고)하는 것이 유용하다.
쿠버네티스의 완료-이후-TTL(TTL-after-finished) {{<glossary_tooltip text="컨트롤러" term_id="controller">}}는
실행이 완료된 잡 오브젝트의 수명을 제한하는
TTL (time to live) 메커니즘을 제공한다.
TTL 컨트롤러는 {{< glossary_tooltip text="잡" term_id="job" >}}만을 제어한다.
<!-- body -->
## 완료-이후-TTL 컨트롤러
## 완료된 잡의 정리
완료-이후-TTL 컨트롤러는 잡만을 지원한다. 클러스터 운영자는
완료-이후-TTL 컨트롤러는 잡만을 지원한다.
[예시](/ko/docs/concepts/workloads/controllers/job/#완료된-잡을-자동으로-정리)
와 같이 `.spec.ttlSecondsAfterFinished` 필드를 명시하여
완료된 잡(`완료` 또는 `실패`)을 자동으로 정리하기 위해 이 기능을 사용할 수 있다.
완료된 잡(`완료` 또는 `실패`)을 자동으로 정리하기 위해 이 매커니즘을 사용할 수 있다.
잡의 작업이 완료된 TTL 초(sec) 후 (다른 말로는, TTL이 만료되었을 때),
완료-이후-TTL 컨트롤러는 해당 잡이 정리될 수 있다고 가정한다.
타이머는 작업의 상태 컨디션이 `완료` 또는 `실패`로 변경되면 시작되며,
TTL이 만료되면 해당 잡은 [캐스케이딩(Cascading)](/ko/docs/concepts/architecture/garbage-collection/#cascading-deletion)
삭제 대상이 된다.
완료-이후-TTL 컨트롤러가 잡을 정리할때 잡을 연속적으로 삭제한다. 이는
의존하는 오브젝트도 해당 잡과 함께 삭제되는 것을 의미한다. 잡이 삭제되면 완료자(finalizers)와
같은 라이프 사이클 보증이 적용 된다.
의존하는 오브젝트도 해당 잡과 함께 삭제되는 것을 의미한다.
쿠버네티스는 [파이널라이저](/ko/docs/concepts/overview/working-with-objects/finalizers/) 대기와 같은 잡의 오브젝트 라이프사이클 보증을 준수한다.
TTL 초(sec)는 언제든지 설정이 가능하다. 여기에 잡 필드 중
`.spec.ttlSecondsAfterFinished` 를 설정하는 몇 가지 예시가 있다.
* 작업이 완료된 다음, 일정 시간 후에 자동으로 잡이 정리될 수 있도록
잡 메니페스트에 이 필드를 지정한다.
* 이미 완료된 기존 잡에 이 새 기능을 적용하기 위해서 이 필드를
설정한다.
* [어드미션 웹후크 변형](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
* 이미 완료된 기존 잡의 이 필드를 수동으로 설정하여 정리할 수
있도록 한다.
* [어드미션 웹후크 변형](/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook)
을 사용해서
잡 생성시 이 필드를 동적으로 설정 한다. 클러스터 관리자는 이것을
사용해서 완료된 잡에 대해 TTL 정책을 적용할 수 있다.
* 잡이 완료된 이후에
[어드미션 웹후크 변형](/docs/reference/access-authn-authz/extensible-admission-controllers/#admission-webhooks)
[어드미션 웹후크 변형](/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook)
을 사용해서 이 필드를 동적으로 설정하고, 잡의 상태,
레이블 등에 따라 다른 TTL 값을 선택한다.
이 경우, 웹후크는 잡이 완료됐다고 기록될 때만 TTL을 지정하기 위해 잡의 `.status`의 변경을 감지해야 한다.
* 특정 {{< glossary_tooltip term_id="selector" text="selector-selector" >}}와 일치하는 잡의 정리 TTL을 관리하기 위해
컨트롤러를 직접 작성한다.
## 경고
### TTL 초(sec) 업데이트
### 완료된 작업에 대한 TTL 업데이트
TTL 기간은, 예를 들어 잡의 `.spec.ttlSecondsAfterFinished` 필드는
잡을 생성하거나 완료한 후에 수정할 수 있다. 그러나, 잡을
삭제할 수 있게 되면(TTL이 만료된 경우) 시스템은 TTL을 연장하기
위한 업데이트가 성공적인 API 응답을 리턴하더라도
잡을 생성하거나 완료한 후에 수정할 수 있다. 존재하는 `ttlSecondsAfterFinished`가 만료된 후에 TTL을 연장하면,
시스템은 TTL을 연장하기 위한 업데이트가 성공적인 API 응답을 리턴하더라도
작업이 유지되도록 보장하지 않는다.
### 시간 차이(Skew)
완료-이후-TTL 컨트롤러는 쿠버네티스 잡에
저장된 타임스탬프를 사용해서 TTL의 만료 여부를 결정하기 때문에, 이 기능은 클러스터 간의
시간 차이에 민감하며, 시간 차이에 의해서 완료-이후-TTL 컨트롤러가 잘못된 시간에 잡
시간 차이에 민감하며, 시간 차이에 의해서 컨트롤 플레인이 잘못된 시간에 잡
오브젝트를 정리하게 될 수 있다.
시계가 항상 정확한 것은 아니지만, 그 차이는
아주 작아야 한다. 0이 아닌 TTL을 설정할때는 이 위험에 대해 유의해야 한다.
## {{% heading "whatsnext" %}}
* [자동으로 잡 정리](/ko/docs/concepts/workloads/controllers/job/#완료된-잡을-자동으로-정리)
* [자동으로 잡 정리](/ko/docs/concepts/workloads/controllers/job/#완료된-잡을-자동으로-정리)를 읽는다.
* [디자인 문서](https://github.com/kubernetes/enhancements/blob/master/keps/sig-apps/592-ttl-after-finish/README.md)
* 이 매커니즘을 추가하기 위해 [Kubernetes Enhancement Proposal](https://github.com/kubernetes/enhancements/blob/master/keps/sig-apps/592-ttl-after-finish/README.md)
(KEP)를 참고한다.