# 사이드카 컨테이너 도입

LLMS index: [llms.txt](/llms.txt)

---

<!-- overview -->

이 섹션은 워크로드에 새로운
빌트인 [사이드카 컨테이너](/docs/concepts/workloads/pods/sidecar-containers/) 기능을 도입하려는 사용자를 대상으로 한다.

사이드카 컨테이너는
[블로그 포스트](/blog/2015/06/the-distributed-system-toolkit-patterns/)에서 소개된 것처럼 새로운 개념이 아니다. 
쿠버네티스는 이 개념을 구현하기 위해 하나의 파드에서 여러 컨테이너를 실행할 수 있도록 지원한다.
그러나 사이드카 컨테이너를 일반 컨테이너로 실행하는 것에는 많은 제한 사항이 있으며, 
이러한 문제들은 새로운 빌트인 사이드카 컨테이너 지원을 통해 해결되고 있다.








  <div class="feature-state-notice feature-stable" title="Feature Gate: SidecarContainers">
              <span class="feature-state-name">기능 상태:</span> 
              <code>Kubernetes v1.33 [stable]</code>(enabled by default)</div>


## 목적

- 사이드카 컨테이너가 필요한 이유를 이해하기
- 사이드카 컨테이너에 관련된 문제 해결 능력 갖추기
- 모든 워크로드에서 사이드카를 보편적으로 "주입"하는 설정 이해하기

## 시작하기 전에

<p>쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와
통신할 수 있도록 설정되어 있어야 한다. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 적어도 2개 포함된 클러스터에서 실행하는 것을 추천한다. 만약, 아직 클러스터를 가지고
있지 않다면,
<a href="/ko/docs/tasks/tools/#minikube">minikube</a>를 사용해서 생성하거나
다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.</p>
<ul>
<li><a href="https://labs.iximiuz.com/playgrounds?category=kubernetes&filter=all">iximiuz Labs</a></li>
<li><a href="https://killercoda.com/playgrounds/scenario/kubernetes">Killercoda</a></li>
<li><a href="https://kodekloud.com/public-playgrounds">KodeKloud</a></li>
</ul>
 
 
 쿠버네티스 서버의 버전은 다음과 같거나 더 높아야 함. 버전: 1.29.
  <p>버전 확인을 위해서, 다음 커맨드를 실행  <code>kubectl version</code>.</p>


<!-- lessoncontent -->

## 사이드카 컨테이너 개요

사이드카 컨테이너는 같은 <a class='glossary-tooltip' title='파드는 클러스터에서 실행 중인 컨테이너의 집합을 나타낸다.' data-bs-toggle='tooltip' data-bs-placement='top' href='/ko/docs/concepts/workloads/pods/' target='_blank' aria-label='파드'>파드</a> 내에서 메인
애플리케이션 컨테이너와 함께 실행되는 보조 컨테이너이다.
이 컨테이너들은 로깅, 모니터링, 보안, 데이터 동기화와 같은 추가 기능을 제공하여 주 _애플리케이션 컨테이너_ 의 기능을 
향상시키거나 확장하는데 사용되며, 
주 애플리케이션 코드를 직접 수정하지 않는다.
[사이드카 컨테이너](/docs/concepts/workloads/pods/sidecar-containers/)에서 더 자세한 내용을 
확인할 수 있다.

사이드카 컨테이너의 개념은 새로운 것이 아니며 이 개념에 대한 여러 구현이 존재한다.
파드를 정의하는 사용자가 실행하려는 사이드카 컨테이너뿐만 아니라, 
일부 <a class='glossary-tooltip' title='쿠버네티스의 기능을 확장하는 리소스.' data-bs-toggle='tooltip' data-bs-placement='top' href='/ko/docs/concepts/cluster-administration/addons/' target='_blank' aria-label='애드온'>애드온</a>은 파드가 실행되기 전에 
파드를 수정하여 추가적인 사이드카 컨테이너를 삽입하는 경우도 있다. 
이러한 추가 사이드카를 _주입_ 하는 메커니즘은 주로 [변형(mutating) 웹훅](/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook)이다.
예를 들어, 서비스 메시 애드온은 파드 간의 상호 TLS 및 전송 중 암호화를 
구성하는 사이드카를 주입할 수 있다.

사이드카 컨테이너의 개념은 새로운 것이 아니지만, 
쿠버네티스에서 이 기능의 네이티브 구현은 새로운 것이다. 그리고 모든 새로운 기능과 마찬가지로, 
이 기능을 도입하면 몇 가지 어려움이 있을 수 있다.

이 튜토리얼은 최종 사용자와 사이드카 컨테이너 작성자 모두가 
경험할 수 있는 어려움과 해결 방안을 탐색한다.

## 빌트인 사이드카 컨테이너의 장점

쿠버네티스의 사이드카 컨테이너에 대한 네이티브 지원을 사용하면 여러 장점이 있다.

1. 네이티브 사이드카 컨테이너를
   <a class='glossary-tooltip' title='앱 컨테이너가 동작하기 전에 완료되기 위해 실행되는 하나 이상의 초기화 컨테이너.' data-bs-toggle='tooltip' data-bs-placement='top' href='/ko/docs/reference/glossary/?all=true#term-init-container' target='_blank' aria-label='초기화 컨테이너'>초기화 컨테이너</a>보다 먼저 시작하도록 설정할 수 있다.
1. 빌트인 사이드카는 항상 가장 마지막에 종료되도록 보장할 수 있다.
   사이드카 컨테이너는 모든 일반 컨테이너가 완료되어 
   종료된 후 `SIGTERM` 신호와 함께 종료된다.
   사이드카 컨테이너가 정상적으로 종료되지 않으면 `SIGKILL` 신호를 사용해 종료된다.
1. 잡의 경우, 파드의 `restartPolicy: OnFailure` 또는 `restartPolicy: Never`일 때 
   네이티브 사이드카 컨테이너는 파드 완료를 차단하지 않는다. 
   레거시 사이드카 컨테이너의 경우 이 상황을 처리하기 위해 특별한 주의가 필요하다. 
1. 또한 잡에서 파드의 `restartPolicy: Never`일 때 일반 컨테이너는 재시작되지 않는 반면에
   빌트인 사이드카 컨테이너는 완료된 후에도 계속 재시작된다.

자세한 내용은 [초기화 컨테이너와의 차이점](/docs/concepts/workloads/pods/sidecar-containers/#differences-from-application-containers)
에서 확인할 수 있다.

## 빌트인 사이드카 컨테이너 도입

`SidecarContainers` [기능 게이트](/docs/reference/command-line-tools-reference/feature-gates/)는
쿠버네티스 1.29부터 베타 상태이며 기본적으로 활성화되어 있다.
일부 클러스터에서는 비활성화되어 있거나, 해당 기능과 호환되지 않는 소프트웨어가 설치되어 있을 수 있다.

이런 경우가 발생하면 파드가 거부되거나 사이드카 컨테이너가 파드 시작을 차단하여 파드를 사용할 수 없게 만들 수 있다.
이 상태는 파드가 초기화 단계에서 멈춰 있는 것으로 쉽게 감지할 수 있다. 
하지만 문제의 원인이 불분명한 경우도 있다.

워크로드에 사이드카 컨테이너를 도입할 때 고려할 사항과 문제 해결 단계는 다음과 같다.

### 기능 게이트의 활성화 확인

가장 먼저 API 서버와 노드가 모두 쿠버네티스 버전 v1.29 이상인지 확인해야 한다. 
이전 버전의 노드가 실행 중인 클러스터에서는 기능이 작동하지 않는다.

<div class="alert alert-info" role="alert"><div class="h4 alert-heading" role="heading">참고</div>



이 기능은 버전 1.28 노드에서 활성화할 수 있다. 
버전 1.28에서 빌트인 사이드카 컨테이너의 종료 동작이 다르며, 사이드카의 동작을 해당 동작으로 조정하는 것은 권장되지 않는다. 
그러나 단순히 시작 순서만 중요하다면 위의 내용을 
기능 게이트가 활성화된 버전 1.28을 실행하는 노드로 변경할 수 있다.

</div>


컨트롤 플레인 내의 API 서버**와** 모든 노드에 대해 
기능 게이트가 활성화되어 있는지 확인해야 한다. 

기능 게이트 활성화를 확인하는 방법 중 하나는 다음과 같은 명령을 실행하는 것이다.

- API 서버 확인

  ```shell
  kubectl get --raw /metrics | grep kubernetes_feature_enabled | grep SidecarContainers
  ```

- 개별 노드 확인

  ```shell
  kubectl get --raw /api/v1/nodes/<node-name>/proxy/metrics | grep kubernetes_feature_enabled | grep SidecarContainers
  ```

다음과 같은 출력이 보이면

```
kubernetes_feature_enabled{name="SidecarContainers",stage="BETA"} 1
```

기능이 활성화된 것이다.

### 서드파티 도구 및 변형 웹훅 확인

기능을 검증하는 과정에서 문제가 발생한다면 이는 서드파티 도구 또는 
변형 웹훅 중 하나가 정상적으로 동작하지 않는 것일 수 있다. 

`SidecarContainers` 기능 게이트가 활성화되면 파드는 API에 새로운 필드를 갖게 된다. 
일부 도구 또는 변형 웹훅은 이전 버전의 쿠버네티스 API로 작성되었을 수 있다. 

도구가 다양한 패칭(patching) 전략을 사용하여 파드 객체를 변경하면서 알 수 없는 필드를 그대로 전달한다면,
문제가 되지 않는다. 그러나 알 수 없는 필드를 제거하는 도구도 존재하며,
이러한 도구가 있는 경우 v1.28 버전 이상의 쿠버네티스 API 클라이언트 코드로 다시 컴파일해야 한다.

이를 확인하는 방법은 변형 승인(mutating admission)을 통과한 파드에 대해 `kubectl describe pod` 명령을 사용하는 것이다. 
만약 어떤 도구가 새로운 필드(`restartPolicy:Always`)를 제거한 경우 
해당 필드는 명령 출력에서 보이지 않을 것이다. 

이러한 문제가 발생하면 도구 또는 
웹훅 작성자에게 전체 객체 업데이트 대신 패칭 전략 중 하나를 사용하여 객체를 수정하도록 권장한다.

<div class="alert alert-info" role="alert"><div class="h4 alert-heading" role="heading">참고</div>



변형 웹훅은 일부 조건에 따라 파드를 업데이트할 수 있다. 
따라서 사이드카 컨테이너는 일부 파드에서는 작동하고 다른 파드에서는 실패할 수 있다. 

</div>


### 사이드카의 자동 주입

사이드카를 자동으로 주입하는 소프트웨어를 사용하는 경우, 
네이티브 사이드카 컨테이너를 사용할 수 있도록 
따를 수 있는 몇 가지 전략이 있다. 
모든 전략은 일반적으로 사이드카가 주입될 파드가 
해당 기능을 지원하는 노드에 배치될지 여부를 결정하는 설정이다. 

예를 들어, [Istio 커뮤니티의 관련 논의](https://github.com/istio/istio/issues/48794)를 참고할 수 있다. 
해당 논의는 아래와 같은 방식들을 제시한다.

1. 사이드카를 지원하는 노드에 배치된 파드를 표시한다. 노드 레이블과 노드 어피니티를 사용하여 
   사이드카 컨테이너를 지원하는 노드와 해당 노드에 배치된 파드를 표시할 수 있다. 
1. 사이드카 주입시 노드 호환성을 확인한다. 
   사이드카 주입 중에 다음 전략을 사용하여 노드 호환성을 확인할 수 있다.
   - 노드 버전을 질의하고 버전 1.29+에서 기능 게이트가 활성화되었다고 가정한다.
   - 노드 프로메테우스 메트릭을 질의하고 기능 활성화 상태를 확인한다.
   - 노드가 API 서버와 [지원되는 버전 차이](/releases/version-skew-policy/#supported-version-skew)로 실행 중이라고 가정한다.
   - 노드 호환성을 감지하는 다른 사용자 정의 방법이 있을 수 있다.
1. 범용 사이드카 주입기를 개발한다. 범용 사이드카 주입기의 아이디어는 
   사이드카 컨테이너를 일반 컨테이너와 네이티브 사이드카 
   컨테이너로 모두 주입하는 것이다. 
   그리고 런타임 로직을 사용하여 어떤 것이 작동할지 결정한다. 
   범용 사이드카 주입기는 요청을 두 번 계산하므로 낭비지만, 
   특수한 경우에 사용할 수 있는 해결책이 될 수 있다.
   - 한 가지 방법은 네이티브 사이드카 컨테이너 시작시 
     노드 버전을 감지하고 버전이 사이드카 기능을 지원하지 않으면 즉시 종료하는 것이다. 
   - 런타임 기능 감지 설계를 고려한다.
     - 컨테이너가 서로 통신할 수 있도록 빈 디렉터리를 정의한다
     - `restartPolicy=Always`를 사용하여 `NativeSidecar`라는 초기화 컨테이너를 주입한다.
     - `NativeSidecar`는 첫 번째 실행을 나타내는 파일을 빈 디렉터리에 쓰고
       즉시 종료 코드 `0`으로 종료해야 한다.
     - `NativeSidecar`는 재시작시 (네이티브 사이드카가 지원될 때) 
       파일이 이미 빈 디렉터리에 있는지 확인하고 변경한다 - 이는 
       빌트인 사이드카 컨테이너를 지원하며 실행 중임을 나타낸다.
     - `OldWaySidecar`라는 일반 컨테이너를 주입한다.
     - `OldWaySidecar`는 시작시 빈 디렉터리에 파일의 존재를 확인한다.
     - 파일이 `NativeSidecar`가 실행 되지 않음을 나타내면, 
       사이드카 기능이 지원되지 않는다고 가정하고 사이드카처럼 작동한다. 
     - 파일이 `NativeSidecar`가 실행 중임을 나타내면, 
       아무 것도 하지 않고 영원히 절전 모드로 들어간다 (파드의 `restartPolicy=Always`인 경우) 또는 즉시 종료 코드 `0`으로 종료한다 
       (파드의 `restartPolicy!=Always`인 경우).

## 다음 내용

- [사이드카 컨테이너](/docs/concepts/workloads/pods/sidecar-containers/)에 대하여 더 알아보기.
