Code change:
<ins> --- # reviewers: # - enisoc # - erictune # - foxish # - janetkuo # - kow3ns # - smarterclayton title: 복제 스테이트풀 애플리케이션 실행하기 content_type: tutorial weight: 30 --- <!-- overview --> 이 페이지에서는 {{< glossary_tooltip term_id="statefulset" >}} 으로 복제 스테이트풀 애플리케이션을 실행하는 방법에 대해 소개한다. 이 애플리케이션은 복제 MySQL 데이터베이스이다. 이 예제의 토폴로지는 단일 주 서버와 여러 복제 서버로 이루어져있으며, row-based 비동기 복제 방식을 사용한다. {{< note >}} **해당 설정은 프로덕션 설정이 아니다**. 쿠버네티스에서 스테이트풀한 애플리케이션을 실행하기 위한 일반적인 패턴에 집중하기 위해 MySQL 세팅이 안전하지 않은 기본 설정으로 되어 있다. {{< /note >}} ## {{% heading "prerequisites" %}} * {{< include "task-tutorial-prereqs.md" >}} {{< version-check >}} * {{< include "default-storage-class-prereqs.md" >}} * 이 튜토리얼은 [퍼시스턴트볼륨](/ko/docs/concepts/storage/persistent-volumes/) 그리고 [스테이트풀셋](/ko/docs/concepts/workloads/controllers/statefulset/), [파드](/ko/docs/concepts/workloads/pods/), [서비스](/ko/docs/concepts/services-networking/service/), [컨피그맵(ConfigMap)](/docs/tasks/configure-pod-container/configure-pod-configmap/)와 같은 핵심 개념들에 대해 알고 있다고 가정한다. * MySQL에 대한 지식이 있으면 도움이 되지만, 이 튜토리얼은 다른 시스템을 활용하였을 때도 도움이 되는 일반적인 패턴을 다루는데 중점을 둔다. * default 네임스페이스를 사용하거나, 다른 오브젝트들과 충돌이 나지 않는 다른 네임스페이스를 사용한다. ## {{% heading "objectives" %}} * 스테이트풀셋을 이용한 복제 MySQL 토폴로지를 배포한다. * MySQL 클라이언트에게 트래픽을 보낸다. * 다운타임에 대한 저항력을 관찰한다. * 스테이트풀셋을 확장/축소한다. <!-- lessoncontent --> ## MySQL 배포하기 MySQL 디플로이먼트 예시는 컨피그맵과, 2개의 서비스, 그리고 스테이트풀셋으로 구성되어 있다. ### 컨피그맵 생성하기 {#configmap} 다음 YAML 설정 파일로부터 컨피그맵을 생성한다. {{< codenew file="application/mysql/mysql-configmap.yaml" >}} ```shell kubectl apply -f https://k8s.io/examples/application/mysql/mysql-configmap.yaml ``` 이 컨피그맵은 당신이 독립적으로 주 MySQL 서버와 레플리카들의 설정을 컨트롤할 수 있도록 `my.cnf` 을 오버라이드한다. 이 경우에는, 주 서버는 복제 로그를 레플리카들에게 제공하고 레플리카들은 복제를 통한 쓰기가 아닌 다른 쓰기들은 거부하도록 할 것이다. 컨피그맵 자체가 다른 파드들에 서로 다른 설정 영역이 적용되도록 하는 것이 아니다. 스테이트풀셋 컨트롤러가 제공해주는 정보에 따라서, 각 파드들은 초기화되면서 설정 영역을 참조할지 결정한다. ### 서비스 생성하기 {#services} 다음 YAML 설정 파일로부터 서비스를 생성한다. {{< codenew file="application/mysql/mysql-services.yaml" >}} ```shell kubectl apply -f https://k8s.io/examples/application/mysql/mysql-services.yaml ``` 헤드리스 서비스는 스테이트풀셋 {{< glossary_tooltip text="컨트롤러" term_id="controller" >}}가 집합의 일부분인 파드들을 위해 생성한 DNS 엔트리들(entries)의 위한 거점이 된다. 헤드리스 서비스의 이름이 `mysql`이므로, 파드들은 같은 쿠버네티스 클러스터나 네임스페이스에 존재하는 다른 파드들에게 `<pod-name>.mysql`라는 이름으로 접근될 수 있다. `mysql-read`라고 불리우는 클라이언트 서비스는 고유의 클러스터 IP를 가지며, Ready 상태인 모든 MySQL 파드들에게 커넥션을 분배하는 일반적인 서비스이다. 잠재적인 엔드포인트들의 집합은 주 MySQL 서버와 해당 레플리카들을 포함한다. 오직 읽기 쿼리들만 로드-밸런싱된 클라이언트 서비스를 이용할 수 있다는 사실에 주목하자. 하나의 주 MySQL 서버만이 존재하기 떄문에, 클라이언트들은 쓰기 작업을 실행하기 위해서 주 MySQL 파드에 (헤드리스 서비스 안에 존재하는 DNS 엔트리를 통해) 직접 접근해야 한다. ### 스테이트풀셋 생성하기 {#statefulset} 마지막으로, 다음 YAML 설정 파일로부터 스테이트풀셋을 생성한다. {{< codenew file="application/mysql/mysql-statefulset.yaml" >}} ```shell kubectl apply -f https://k8s.io/examples/application/mysql/mysql-statefulset.yaml ``` 다음을 실행하여, 초기화되는 프로세스들을 확인할 수 있다. ```shell kubectl get pods -l app=mysql --watch ``` 잠시 뒤에, 3개의 파드들이 `Running` 상태가 되는 것을 볼 수 있다. ``` NAME      READY     STATUS    RESTARTS   AGE mysql-0   2/2       Running   0          2m mysql-1   2/2       Running   0          1m mysql-2   2/2       Running   0          1m ``` **Ctrl+C**를 입력하여 watch를 종료하자. {{< note >}} 만약 아무 진행 상황도 보이지 않는다면, [시작하기 전에](#before-you-begin) 에 언급된 동적 퍼시스턴트볼륨 프로비저너(provisioner)가 활성화되어 있는지 확인한다. {{< /note >}} 해당 메니페스트에는 스테이트풀셋의 일부분인 스테이트풀 파드들을 관리하기 위한 다양한 기법들이 적용되어 있다. 다음 섹션에서는 스테트풀셋이 파드들을 생성할 때 일어나는 일들을 이해할 수 있도록 일부 기법들을 강조하여 설명한다. ## 스테이트풀 파드 초기화 이해하기 스테이트풀셋 컨트롤러는 파드들의 인덱스에 따라 순차적으로 시작시킨다. 컨트롤러는 다음 파드 생성 이전에 각 파드가 Ready 상태가 되었다고 알려줄 때까지 기다린다. 추가적으로, 컨트롤러는 각 파드들에게 `<스테이트풀셋 이름>-<순차적 인덱스>` 형태의 고유하고 안정적인 이름을 부여하는데, 결과적으로 파드들은 `mysql-0`, `mysql-1`, 그리고 `mysql-2` 라는 이름을 가지게 된다. 스테이트풀셋 매니페스트의 파드 템플릿은 해당 속성들을 통해 순차적인 MySQL 복제의 시작을 수행한다. ### 설정 생성하기 파드 스펙의 컨테이너를 시작하기 전에, 파드는 순서가 정의되어 있는 [초기화 컨테이너](/ko/docs/concepts/workloads/pods/init-containers/)들을 먼저 실행시킨다. `init-mysql`라는 이름의 첫 번째 초기화 컨테이너는, 인덱스에 따라 특별한 MySQL 설정 파일을 생성한다. 스크립트는 인덱스를 `hostname` 명령으로 반환되는 파드 이름의 마지막 부분에서 추출하여 결정한다. 그리고 인덱스(이미 사용된 값들을 피하기 위한 오프셋 숫자와 함께)를 MySQL의 `conf.d` 디렉토리의 `server-id.cnf` 파일에 저장한다. 이는 스테이트풀셋에게서 제공된 고유하고, 안정적인 신원을 같은 속성을 필요로 하는 MySQL 서버 ID의 형태로 바꾸어준다. 또한 `init-mysql` 컨테이너의 스크립트는 컨피그맵을 `conf.d`로 복사하여, `primary.cnf` 또는 `replica.cnf`을 적용한다. 이 예제의 토폴로지가 하나의 주 MySQL 서버와 일정 수의 레플리카들로 이루어져 있기 때문에, 스크립트는 `0` 인덱스를 주 서버로, 그리고 나머지 값들은 레플리카로 지정한다. 스테이트풀셋 컨트롤러의 [디플로이먼트와 스케일링 보증](/ko/docs/concepts/workloads/controllers/statefulset/#디플로이먼트와-스케일링-보증)과 합쳐지면, 복제를 위한 레플리카들을 생성하기 전에 주 MySQL 서버가 Ready 상태가 되도록 보장할 수 있다. ### 기존 데이터 복제(cloning) 일반적으로, 레플리카에 새로운 파드가 추가되는 경우, 주 MySQL 서버가 이미 데이터를 가지고 있다고 가정해야 한다. 또한 복제 로그가 첫 시작점부터의 로그들을 다 가지고 있지는 않을 수 있다고 가정해야 한다. 이러한 보수적인 가정들은 스테이트풀셋이 초기 크기로 고정되어 있는 것보다, 시간에 따라 확장/축소하게 할 수 있도록 하는 중요한 열쇠가 된다. `clone-mysql`라는 이름의 두 번째 초기화 컨테이너는, 퍼시스턴트볼륨에서 처음 초기화된 레플리카 파드에 복제 작업을 수행한다. 이 말은 다른 실행 중인 파드로부터 모든 데이터들을 복제하기 때문에, 로컬의 상태가 충분히 일관성을 유지하고 있어서 주 서버에서부터 복제를 시작할 수 있다는 의미이다. MySQL 자체가 이러한 메커니즘을 제공해주지는 않기 때문에, 이 예제에서는 XtraBackup이라는 유명한 오픈소스 도구를 사용한다. 복제 중에는, 복제 대상 MySQL 서버가 성능 저하를 겪을 수 있다. 주 MySQL 서버의 이러한 충격을 최소화하기 위해, 스크립트는 각 파드가 자신의 인덱스보다 하나 작은 파드로부터 복제하도록 지시한다. 이것이 정상적으로 동작하는 이유는 스테이트풀셋 컨트롤러가 파드 `N+1`을 실행하기 전에 항상 파드 `N`이 Ready 상태라는 것을 보장하기 때문이다. ### 복제(replication) 시작하기 초기화 컨테이너들의 성공적으로 완료되면, 일반적인 컨테이너가 실행된다. MySQL 파드는 `mysqld` 서버를 구동하는 `mysql` 컨테이너로 구성되어 있으며, `xtrabackup` 컨테이너는 [사이드카(sidecar)](/blog/2015/06/the-distributed-system-toolkit-patterns)로서 작동한다. `xtrabackup` 사이드카는 복제된 데이터 파일들을 보고 레플리카에 MySQL 복제를 시작해야 할 필요가 있는지 결정한다. 만약 그렇다면, `mysqld`이 준비될 때까지 기다린 후 `CHANGE MASTER TO`, 그리고 `START SLAVE`를 XtraBackup 복제(clone) 파일들에서 추출한 복제(replication) 파라미터들과 함께 실행시킨다. 레플리카가 복제를 시작하면, 먼저 주 MySQL 서버를 기억하고, 서버가 재시작되거나 커넥션이 끊어지면 다시 연결한다. 또한 레플리카들은 주 서버를 안정된 DNS 이름 (`mysql-0.mysql`)으로 찾기 때문에, 주 서버가 리스케쥴링에 의해 새로운 파드 IP를 받아도 주 서버를 자동으로 찾는다. 마지막으로, 복제를 시작한 후에는, `xtrabackup` 컨테이너는 데이터 복제를 요청하는 다른 파드들의 커넥션을 리스닝한다. 이 서버는 스테이트풀셋이 확장하거나, 다음 파드가 퍼시스턴트볼륨클레임을 잃어서 다시 복제를 수행해햐 할 경우를 대비하여 독립적으로 존재해야 한다. ## 클라이언트 트래픽 보내기 임시 컨테이너를 `mysql:5.7` 이미지로 실행하고 `mysql` 클라이언트 바이너리를 실행하는 것으로 테스트 쿼리를 주 MySQL 서버(`mysql-0.mysql` 호스트네임)로 보낼 수 있다. ```shell kubectl run mysql-client --image=mysql:5.7 -i --rm --restart=Never -- mysql -h mysql-0.mysql <<EOF CREATE DATABASE test; CREATE TABLE test.messages (message VARCHAR(250)); INSERT INTO test.messages VALUES ('hello'); EOF ``` `mysql-read` 호스트네임을 사용하여 Ready 상태가 되었다고 보고하는 어느 서버에나 시험 쿼리를 보낼 수 있다. ```shell kubectl run mysql-client --image=mysql:5.7 -i -t --rm --restart=Never -- mysql -h mysql-read -e "SELECT * FROM test.messages" ``` 그러면 다음과 같은 출력를 얻을 것이다. ``` Waiting for pod default/mysql-client to be running, status is Pending, pod ready: false +---------+ | message | +---------+ | hello   | +---------+ pod "mysql-client" deleted ``` `mysql-read` 서비스가 커넥션을 서버들에게 분배하고 있다는 사실을 확인하기 위해서, `SELECT @@server_id`를 루프로 돌릴 수 있다. ```shell kubectl run mysql-client-loop --image=mysql:5.7 -i -t --rm --restart=Never -- bash -ic "while sleep 1; do mysql -h mysql-read -e 'SELECT @@server_id,NOW()'; done" ``` 보고된 `@@server_id`가 무작위로 바뀌는 것을 알 수 있다. 왜냐하면 매 커넥션 시도마다 다른 엔드포인트가 선택될 수 있기 때문이다. ``` +-------------+---------------------+ | @@server_id | NOW()               | +-------------+---------------------+ |         100 | 2006-01-02 15:04:05 | +-------------+---------------------+ +-------------+---------------------+ | @@server_id | NOW()               | +-------------+---------------------+ |         102 | 2006-01-02 15:04:06 | +-------------+---------------------+ +-------------+---------------------+ | @@server_id | NOW()               | +-------------+---------------------+ |         101 | 2006-01-02 15:04:07 | +-------------+---------------------+ ``` 루프를 끝내고 싶다면 **Ctrl+C**를 입력하면 되지만, 다음 단계에서의 영향을 보기 위해서 다른 창에 계속 실행시켜 놓는 것이 좋다. ## 노드와 파드 실패 시뮬레이션하기 {#simulate-pod-and-node-downtime} 단일 서버 대비 레플리카들의 풀에 의한 읽기의 가용성 향상을 시연하기 위해, 파드를 Ready 상태로 강제하면서 `SELECT @@server_id` 루프를 돌리자. ### 준비성 프로브 고장내기 `mysql` 컨테이너의 [준비성 프로브](/ko/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#define-readiness-probes)는 쿼리를 실행할 수 있는지를 확인하기 위해 `mysql -h 127.0.0.1 -e 'SELECT 1'` 명령을 실행한다. 준비성 프로브를 강제로 실패시키는 방법은 해당 명령을 고장내는 것이다. ```shell kubectl exec mysql-2 -c mysql -- mv /usr/bin/mysql /usr/bin/mysql.off ``` 이것은 `mysql-2` 파드의 실제 컨테이너의 파일시스템에 접근해서 `mysql` 명령의 이름을 변경하여, 준비성 프로브가 찾을 수 없도록 한다. 몇 초 뒤에, 파드는 컨터이너 중 하나가 준비되지 않았다고 보고할 것이다. 다음 명령을 실행시켜서 확인할 수 있다. ```shell kubectl get pod mysql-2 ``` `READY` 항목의 `1/2`를 확인하자. ``` NAME      READY     STATUS    RESTARTS   AGE mysql-2   1/2       Running   0          3m ``` 이 시점에서, `102`를 보고하지 않지만, 계속해서 `SELECT @@server_id` 루프가 실행되는 것을 확인할 수 있을 것이다. `init-mysql` 스크립트에서 `server-id`를 `100 + $ordinal`로 정의했기 때문에, 서버 ID `102`는 `mysql-2` 파드에 대응된다는 사실을 상기하자. 이제 파드를 고치면 몇 초 뒤에 루프 출력에 나타날 것이다. ```shell kubectl exec mysql-2 -c mysql -- mv /usr/bin/mysql.off /usr/bin/mysql ``` ### 파드 삭제하기 레플리카셋이 스테이트리스 파드들에게 하는 것처럼, 스테이트풀셋 또한 파드들이 삭제되면 파드들을 다시 생성한다. ```shell kubectl delete pod mysql-2 ``` 스테이트풀셋 컨트롤러는 `mysql-2` 파드가 존재하지 않는 것을 인지하고, 같은 이름으로 새로운 파드를 생성하고 같은 퍼시스턴트볼륨클레임에 연결한다. 잠시동안 서버 ID `102`가 루프 출력에서 사라지고 다시 나타나는 것을 확인할 수 있을 것이다. ### 노드 드레인하기 만약 당신의 쿠버네티스 클러스터가 여러 노드들을 가지고 있으면, [드레인](/docs/reference/generated/kubectl/kubectl-commands/#drain)을 사용하여 노드 다운타임을 시뮬레이션할 수 있다. 먼저 MySQL 파드가 존재하고 있는 노드를 확인하자. ```shell kubectl get pod mysql-2 -o wide ``` 노드 이름은 마지막 열에서 나타날 것이다. ``` NAME      READY     STATUS    RESTARTS   AGE       IP            NODE mysql-2   2/2       Running   0          15m       10.244.5.27   kubernetes-node-9l2t ``` 그 후에, 다음 명령을 실행하여 노드를 드레인한다. 그러면 새로운 파드가 스케줄되지 않게 방지하고(cordon), 기존의 파드들을 추방(evict)한다. `<node-name>`를 이전 단계에서 찾았던 노드의 이름으로 바꾸자. {{< caution >}} 노드 드레인은 해당 노드에서 실행 중인 다른 워크로드와 애플리케이션들에게 영향을 줄 수 있다. 테스트 클러스터에만 다음 단계를 수행하자. {{< /caution >}} ```shell # 위에 명시된 다른 워크로드들이 받는 영향에 대한 주의사항을 확인한다. kubectl drain <node-name> --force --delete-emptydir-data --ignore-daemonsets ``` 이제 파드가 다른 노드에 리스케줄링되는 것을 관찰할 수 있다. ```shell kubectl get pod mysql-2 -o wide --watch ``` 출력은 다음과 비슷할 것이다. ``` NAME      READY   STATUS          RESTARTS   AGE       IP            NODE mysql-2   2/2     Terminating     0          15m       10.244.1.56   kubernetes-node-9l2t [...] mysql-2   0/2     Pending         0          0s        <none>        kubernetes-node-fjlm mysql-2   0/2     Init:0/2        0          0s        <none>        kubernetes-node-fjlm mysql-2   0/2     Init:1/2        0          20s       10.244.5.32   kubernetes-node-fjlm mysql-2   0/2     PodInitializing 0          21s       10.244.5.32   kubernetes-node-fjlm mysql-2   1/2     Running         0          22s       10.244.5.32   kubernetes-node-fjlm mysql-2   2/2     Running         0          30s       10.244.5.32   kubernetes-node-fjlm ``` 그리고, 서버 ID `102`가 `SELECT @@server_id` 루프 출력에서 잠시 사라진 후 다시 보이는 것을 확인할 수 있을 것이다. 이제 노드의 스케줄 방지를 다시 해제(uncordon)해서 정상으로 돌아가도록 조치한다. ```shell kubectl uncordon <node-name> ``` ## 레플리카 스케일링하기 MySQL 레플리케이션을 사용하면, 레플리카를 추가하는 것으로 읽기 쿼리 용량을 키울 수 있다. 스테이트풀셋을 사용하면, 단 한 줄의 명령으로 달성할 수 있다. ```shell kubectl scale statefulset mysql  --replicas=5 ``` 명령을 실행시켜서 새로운 파드들이 올라오는 것을 관찰하자. ```shell kubectl get pods -l app=mysql --watch ``` 파드들이 올라오면, `SELECT @@server_id` 루프 출력에 서버 ID `103` 과 `104`가 나타나기 시작할 것이다. 그리고 해당 파드들이 존재하기 전에 추가된 데이터들이 해당 새 서버들에게도 존재하는 것을 확인할 수 있다. ```shell kubectl run mysql-client --image=mysql:5.7 -i -t --rm --restart=Never -- mysql -h mysql-3.mysql -e "SELECT * FROM test.messages" ``` ``` Waiting for pod default/mysql-client to be running, status is Pending, pod ready: false +---------+ | message | +---------+ | hello   | +---------+ pod "mysql-client" deleted ``` 축소하는 것도 간단하게 할 수 있다. ```shell kubectl scale statefulset mysql --replicas=3 ``` {{< note >}} 확장은 퍼시스턴트볼륨클레임을 자동으로 생성하지만, 축소에서는 해당 PVC들이 자동으로 삭제되지 않는다. 이로써 확장을 빠르게 하기 위해 초기화된 PVC들을 보관해 두거나, 삭제하기 전에 데이터를 추출하는 선택을 할 수 있다. {{< /note >}} 다음 명령을 실행하여 확인할 수 있다. ```shell kubectl get pvc -l app=mysql ``` 스테이트풀셋을 3으로 축소했음에도 PVC 5개가 아직 남아있음을 보여준다. ``` NAME           STATUS    VOLUME                                     CAPACITY   ACCESSMODES   AGE data-mysql-0   Bound     pvc-8acbf5dc-b103-11e6-93fa-42010a800002   10Gi       RWO           20m data-mysql-1   Bound     pvc-8ad39820-b103-11e6-93fa-42010a800002   10Gi       RWO           20m data-mysql-2   Bound     pvc-8ad69a6d-b103-11e6-93fa-42010a800002   10Gi       RWO           20m data-mysql-3   Bound     pvc-50043c45-b1c5-11e6-93fa-42010a800002   10Gi       RWO           2m data-mysql-4   Bound     pvc-500a9957-b1c5-11e6-93fa-42010a800002   10Gi       RWO           2m ``` 만약 여분의 PVC들을 재사용하지 않을 것이라면, 이들을 삭제할 수 있다. ```shell kubectl delete pvc data-mysql-3 kubectl delete pvc data-mysql-4 ``` ## {{% heading "cleanup" %}} 1. `SELECT @@server_id` 루프를 끝내기 위해, 터미널에 **Ctrl+C**를 입력하거나, 해당 명령을 다른 터미널에서 실행시키자. ```shell kubectl delete pod mysql-client-loop --now ``` 1. 스테이트풀셋을 삭제한다. 이것은 파드들 또한 삭제할 것이다. ```shell kubectl delete statefulset mysql ``` 1. 파드들의 삭제를 확인한다. 삭제가 완료되기까지 시간이 걸릴 수 있다. ```shell kubectl get pods -l app=mysql ``` 위와 같은 메세지가 나타나면 파드들이 삭제되었다는 것을 알 수 있다. ``` No resources found. ``` 1. 컨피그맵, 서비스, 그리고 퍼시스턴트볼륨클레임들을 삭제한다. ```shell kubectl delete configmap,service,pvc -l app=mysql ``` 1. 만약 수동으로 퍼시스턴스볼륨들을 프로비저닝했다면, 수동으로 삭제하면서, 그 밑에 존재하는 리소스들을 또한 삭제해야 한다. 만약 동적 프로비저너를 사용했다면, 당신이 퍼시스턴트볼륨클레임으로 삭제하면 자동으로 퍼시스턴트볼륨을 삭제한다. 일부 (EBS나 PD와 같은) 동적 프로비저너들은 퍼시스턴트볼륨을 삭제 하면 그 뒤에 존재하는 리소스들도 삭제한다. ## {{% heading "whatsnext" %}} * [스테이트풀셋(StatefulSet) 확장하기](/ko/docs/tasks/run-application/scale-stateful-set/)에 대해 더 배워보기. * [스테이트풀셋 디버깅하기](/ko/docs/tasks/debug/debug-application/debug-statefulset/)에 대해 더 배워보기. * [스테이트풀셋(StatefulSet) 삭제하기](/ko/docs/tasks/run-application/delete-stateful-set/)에 대해 더 배워보기. * [스테이트풀셋(StatefulSet) 파드 강제 삭제하기](/ko/docs/tasks/run-application/force-delete-stateful-set-pod/)에 대해 더 배워보기. * [Helm Charts 저장소](https://artifacthub.io/)를 통해 다른 스테이트풀 애플리케이션 예제들을 확인해보기. </ins>

Related discussion:
text: This is a Feature Request Korean Localization for branch. What would you like to be Any localization contributions for Korean. Comments This issue is to notify the schedule of Korean localization to contributors. is the current work branch for Korean localization. Important dates A Korean localization work branch is merged to branch after we complete around 3~4 weeks job. PR Freeze: 01/16 (PR opened after freeze will be requested to rebase to next work branch) Branch Merge: 01/19 (merge to main branch)  2~3 , main . PR : 01/16 ( PR , PR ) : 01/19 (main , k8s.io ) /language ko /help
This request has been marked as needing help from a contributor. Please ensure that the issue body includes answers to the following questions: Why are we solving this issue? To address this issue, are there any code changes? If there are code changes, what needs to be done in the code and what places can the assignee treat as reference points? Does this issue have zero to low barrier of entry? How can the assignee reach out to you for help? For more details on the requirements of such an issue, please see and ensure that they are met. If this request no longer meets these requirements, the label can be removed by commenting with the command. <detailsIn response to : ## In English is the current work branch for Korean localization.A Korean localization work branch is merged to branch after we complete around 3~4 weeks job. PR Freeze: 01/16 (PR opened after freeze will be requested to rebase to next work branch) Branch Merge: 01/19 (merge to main branch) PR : 01/16 ( PR , PR ) : 01/19 (main , k8s.io ) /help </details
/milestone dev-1.26-ko.1
/triage accepted
Outdated Korean contents in the dev-1.26-ko.1