# Контейнери sidecar

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

---

<!-- overview -->








  <div class="feature-state-notice feature-stable" title="Функціональна можливість: SidecarContainers">
              <span class="feature-state-name">СТАН ФУНКЦІОНАЛУ:</span> 
              <code>Kubernetes v1.33 [stable]</code>(стандартно увімкнено)</div>


Контейнери sidecar — це додаткові контейнери, які працюють разом з основним контейнером застосунку всередині одного <a class='glossary-tooltip' title='Pod є групою контейнерів, що запущені у вашому кластері.' data-bs-toggle='tooltip' data-bs-placement='top' href='/uk/docs/concepts/workloads/pods/' target='_blank' aria-label='Podʼа'>Podʼа</a>. Ці контейнери використовуються для розширення чи покращення функціональності _основного контейнера_ застосунку, надаючи додаткові сервіси чи функціональність, такі як логування, моніторинг, безпеку або синхронізацію даних, не змінюючи безпосередньо код основного застосунку.

Зазвичай в одному Podʼі є лише один контейнер застосунку. Наприклад, якщо у вас є вебзастосунок, який потребує локального вебсервера, локальний вебсервер буде контейнером sidecar, а сам вебзастосунок — це контейнер застосунку.

<!-- body -->

## Контейнери sidecar в Kubernetes {#pod-sidecar-containers}

Kubernetes впроваджує контейнери sidecar як особливий випадок [контейнерів ініціалізації](/docs/concepts/workloads/pods/init-containers/); контейнери sidecar залишаються запущеними після запуску Podʼа. У цьому документі термін _звичайні контейнери ініціалізації_ використовується для чіткого посилання на контейнери, які працюють лише під час запуску Podʼа.

Припускаючи, що у вашому кластері увімкнено [функціональну можливість](/docs/reference/command-line-tools-reference/feature-gates/) `SidecarContainers`, (активна починаючи з Kubernetes v1.29), ви можете вказати `restartPolicy` для контейнерів, вказаних у полі `initContainers` Podʼа. Ці контейнери sidecar, які перезапускаються, є незалежними від інших контейнерів ініціалізації та від основних контейнерів застосунку у тому ж Podʼі, і можуть бути запущені, зупинені або перезапущені без впливу на основний контейнер застосунку та інші контейнери ініціалізації.

Ви також можете запустити Pod із декількома контейнерами, які не позначені як контейнери ініціалізації або sidecar. Це доцільно, якщо контейнери в межах Podʼа необхідні для його роботи в цілому, але вам не потрібно керувати тим, які контейнери спочатку запускаються або зупиняються. Ви також можете це зробити, якщо вам потрібно підтримувати старі версії Kubernetes, які не підтримують поле `restartPolicy` на рівні контейнера.

### Приклад застосунку {#sidecar-example}

Нижче наведено приклад Deployment з двома контейнерами, один з яких є sidecar:


<div class="alert alert-info" role="note"><h4 class="alert-heading">Примітка:</h4>У цьому прикладі контейнер-сайдкар навмисно визначений в <code>initContainers</code> з <code>restartPolicy: Always</code>. Kubernetes розглядає такі контейнери як sidecars, які продовжують працювати впродовж усього терміну існування Podʼа.</div>



















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/uk/examples/application/deployment-sidecar.yaml" download="application/deployment-sidecar.yaml"><code>application/deployment-sidecar.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('application-deployment-sidecar-yaml')" title="Копіювати application/deployment-sidecar.yaml до буферу обміну"></img></div>
    <div class="includecode" id="application-deployment-sidecar-yaml"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">apps/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Deployment</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">myapp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">app</span><span class="p">:</span><span class="w"> </span><span class="l">myapp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">replicas</span><span class="p">:</span><span class="w"> </span><span class="m">1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">selector</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">matchLabels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">app</span><span class="p">:</span><span class="w"> </span><span class="l">myapp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">template</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">labels</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span><span class="nt">app</span><span class="p">:</span><span class="w"> </span><span class="l">myapp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">containers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">myapp</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">alpine:latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">command</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s1">&#39;sh&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;-c&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;while true; do echo &#34;logging&#34; &gt;&gt; /opt/logs.txt; sleep 1; done&#39;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">volumeMounts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">mountPath</span><span class="p">:</span><span class="w"> </span><span class="l">/opt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">initContainers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">logshipper</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">alpine:latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="c"># Встановлення restartPolicy: Always робить цей контейнер контенером sidecar.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">restartPolicy</span><span class="p">:</span><span class="w"> </span><span class="l">Always</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">command</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s1">&#39;sh&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;-c&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;tail -F /opt/logs.txt&#39;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">volumeMounts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">mountPath</span><span class="p">:</span><span class="w"> </span><span class="l">/opt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">emptyDir</span><span class="p">:</span><span class="w"> </span>{}<span class="w">
</span></span></span></code></pre></div></div>
</div>

## Контейнери sidecar та життєвий цикл Podʼа {#sidecar-containers-and-pod-lifecycle}

Якщо контейнер ініціалізації створено з параметром `restartPolicy`, встановленим на `Always`, він розпочне роботу і залишиться запущеним протягом усього життя Podʼа. Це може бути корисно для запуску служб підтримки, відокремлених від основних контейнерів застосунку.

Якщо для цього контейнера ініціалізації вказано `readinessProbe`, результат буде використовуватися для визначення стану `ready` Podʼа.

Оскільки ці контейнери визначені як контейнери ініціалізації, вони користуються тими ж гарантіями порядку та послідовності, що й інші контейнери ініціалізації, що дозволяє їх змішувати з іншими контейнерами ініціалізації в складні потоки ініціалізації Podʼа.

В порівнянні зі звичайними контейнерами ініціалізації, контейнери, визначені в `initContainers`, продовжують роботу після їх запуску. Це важливо, коли в `.spec.initContainers` для Podʼа є більше одного запису. Після запуску контейнера ініціалізації типу sidecar (kubelet встановлює статус `started` для цього контейнера в `true`), kubelet запускає наступний контейнер ініціалізації з упорядкованого списку `.spec.initContainers`. Цей статус стає true через те, що в контейнері працює процес і немає визначеного `startupProbe`, або внаслідок успішного виконання `startupProbe`.

При завершенні роботи [Podʼа](/docs/concepts/workloads/pods/pod-lifecycle/#termination-with-sidecars), kubelet відкладає завершення контейнерів sidecar до повної зупинки основного контейнера застосунку. Після цього контейнери sidecar вимикаються у порядку, протилежному порядку їх появи у специфікації Podʼа. Такий підхід гарантує, що контейнери sidecar залишаються в робочому стані, підтримуючи інші контейнери в Podʼі, до тих пір, поки їх обслуговування більше не буде потрібне.

### Завдання з контейнерами sidecar {#job-with-sidecar-containers}

Якщо ви створюєте Job з контейнерами sidecar, що використовує їх за допомогою контейнерів ініціалізації, контейнери sidecar у кожному Podʼі не перешкоджатимуть завершенню Завдання після завершення роботи основного контейнера.

Ось приклад Job із двома контейнерами, один з яких — це контейнер sidecar:


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/uk/examples/application/job/job-sidecar.yaml" download="application/job/job-sidecar.yaml"><code>application/job/job-sidecar.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('application-job-job-sidecar-yaml')" title="Копіювати application/job/job-sidecar.yaml до буферу обміну"></img></div>
    <div class="includecode" id="application-job-job-sidecar-yaml"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">apiVersion</span><span class="p">:</span><span class="w"> </span><span class="l">batch/v1</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">kind</span><span class="p">:</span><span class="w"> </span><span class="l">Job</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">metadata</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">myjob</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">template</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">spec</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">containers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">myjob</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">alpine:latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">command</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s1">&#39;sh&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;-c&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;echo &#34;logging&#34; &gt; /opt/logs.txt&#39;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">volumeMounts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">mountPath</span><span class="p">:</span><span class="w"> </span><span class="l">/opt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">initContainers</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">logshipper</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">image</span><span class="p">:</span><span class="w"> </span><span class="l">alpine:latest</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="c"># Встановлення restartPolicy: Always робить цей контейнер контенером sidecar.</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">restartPolicy</span><span class="p">:</span><span class="w"> </span><span class="l">Always</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">command</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="s1">&#39;sh&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;-c&#39;</span><span class="p">,</span><span class="w"> </span><span class="s1">&#39;tail -F /opt/logs.txt&#39;</span><span class="p">]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">volumeMounts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">              </span><span class="nt">mountPath</span><span class="p">:</span><span class="w"> </span><span class="l">/opt</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">restartPolicy</span><span class="p">:</span><span class="w"> </span><span class="l">Never</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">volumes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">        </span>- <span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l">data</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">          </span><span class="nt">emptyDir</span><span class="p">:</span><span class="w"> </span>{}<span class="w">
</span></span></span></code></pre></div></div>
</div>

## Відмінності від контейнерів застосунків {#differences-from-application-containers}

Контейнери sidecar працюють поруч з _контейнерами застосунку_ в одному Podʼі. Однак вони не виконують основну логіку застосунку; замість цього вони надають додатковий функціонал основному застосунку.

Контейнери sidecar мають власні незалежні життєві цикли. Їх можна запускати, зупиняти та перезапускати незалежно від контейнерів застосунку. Це означає, що ви можете оновлювати, масштабувати чи обслуговувати контейнери sidecar, не впливаючи на основний застосунок.

Контейнери sidecar ділять той самий простір імен мережі та сховища з основним контейнером. Це спільне розташування дозволяє їм тісно взаємодіяти та спільно використовувати ресурси.

З погляду Kubernetes, відповідне завершення для sidecar є менш важливим. Якщо інші контейнери використали весь виділений час для відповідного завершення роботи, то контейнери з sidecar отримають сигнал `SIGTERM`, а потім `SIGKILL`, перш ніж вони встигнуть завершити свою роботу відповідним чином. Отже, коди виходу, відмінні від `0` (`0` означає успішний вихід), для контейнерів з sidecar є нормальним явищем при завершенні роботи Podʼа, і зазвичай їх слід ігнорувати зовнішньому інструментарію.

## Відмінності від контейнерів ініціалізації {#differences-from-init-containers}

Контейнери sidecar працюють поруч з основним контейнером, розширюючи його функціональність та надаючи додаткові служби.

Контейнери sidecar працюють паралельно з основним контейнером застосунку. Вони активні протягом усього життєвого циклу Podʼа та можуть бути запущені та зупинені незалежно від основного контейнера. На відміну від [контейнерів ініціалізації](/docs/concepts/workloads/pods/init-containers/), контейнери sidecar підтримують [проби](/docs/concepts/workloads/pods/pod-lifecycle/#types-of-probe), щоб контролювати їхній життєвий цикл.

Контейнери sidecar можуть взаємодіяти безпосередньо з основними контейнерами застосунків, оскільки вони, так само як і контейнери ініціалізації, спільно використовують той самий простір імен мережі, файлову систему та змінні оточення.

Контейнери ініціалізації зупиняються до того, як основний контейнер застосунку розпочне роботу, тож контейнер ініціалізації не може обмінюватись повідомленнями з контейнером застосунку в Podʼі. Будь-які дані передаються лише в один бік (наприклад, контейнер ініціалізації може залишити інформацію у томі `emptyDir`).

Зміна образу контейнера sidecar не призведе до перезапуску Podʼа, але спровокує перезапуск контейнера.

## Спільне використання ресурсів всередині контейнерів {#resource-sharing-within-containers}



З урахуванням порядку виконання контейнерів ініціалізації, обслуговування та застосунків застосовуються наступні правила
використання ресурсів:

- Найвищий запит чи обмеження будь-якого конкретного ресурсу, визначеного у всіх контейнерах ініціалізації, вважається _ефективним запитом/обмеженням ініціалізації_. Якщо для будь-якого ресурсу не вказано обмеження, це вважається найвищим обмеженням.
- _Ефективний запит/обмеження Podʼа_ для ресурсу — більше з:
  - сума всіх запитів/обмежень контейнерів застосунків для ресурсу
  - ефективний запит/обмеження для ініціалізації для ресурсу
- Планування виконується на основі ефективних запитів/обмежень, що означає, що контейнери ініціалізації можуть резервувати ресурси для ініціалізації, які не використовуються протягом життя Podʼа.
- Рівень якості обслуговування (QoS), *рівень QoS Podʼа* — є рівнем QoS як для контейнерів ініціалізації, так і для контейнерів застосунків.

Обмеження та ліміти застосовуються на основі ефективного запиту та ліміту Podʼа.

### Контейнери sidecar та cgroups Linux {#cgroups}

У Linux, розподіл ресурсів для контрольних груп рівня Podʼів (cgroups) ґрунтується на ефективному запиті та ліміті рівня Podʼа, так само як і для планувальника.

## Що далі

- Дізнайтеся, про те як [використовувати контейнери sidecar](/docs/tutorials/configuration/pod-sidecar-containers/)
- Прочитайте блог-пост про [нативні контейнери sidecar](/blog/2023/08/25/native-sidecar-containers/).
- Прочитайте про [створення Podʼа, який має контейнер ініціалізації](/docs/tasks/configure-pod-container/configure-pod-initialization/#create-a-pod-that-has-an-init-container).
- Дізнайтеся про [види проб](/docs/concepts/workloads/pods/pod-lifecycle/#types-of-probe): liveness, readiness, startup.
- Дізнайтеся про [накладні витрати роботи Podʼа](/docs/concepts/scheduling-eviction/pod-overhead/).
