# Архітектура логування

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

---

<!-- overview -->

Логи застосунків можуть допомогти вам зрозуміти, що відбувається у ньому всередині. Логи особливо корисні для виправлення проблем та моніторингу активності кластера. Більшість сучасних застосунків мають деякий механізм логування. Так само, рушії виконання контейнерів розроблені з підтримкою логування. Найпростіший і найбільш прийнятий метод логування для контейнеризованих застосунків — це запис у стандартні потоки виводу та помилок.

Однак, природна функціональність, яку надає рушій виконання контейнерів або середовище виконання, зазвичай недостатня для повного вирішення завдань логування.

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

У кластері логи повинні мати окреме сховище та життєвий цикл незалежно від вузлів, Podʼів або контейнерів. Ця концепція називається [логування на рівні кластера](#cluster-level-logging-architectures).

Архітектури логування на рівні кластера вимагають окремого бекенду для зберігання, аналізу, та отримання логів. Kubernetes не надає власного рішення для зберігання даних логів. Натомість існує багато рішень для логування, які інтегруються з Kubernetes. Наступні розділи описують, як обробляти та зберігати логи на вузлах.

<!-- body -->

## Логи Podʼів та контейнерів {#basic-logging-in-kubernetes}

Kubernetes збирає логи з кожного контейнера в запущеному Podʼі.

Цей приклад використовує маніфест для `Pod`ʼу з контейнером, який записує текст у стандартний потік виводу, раз на секунду.


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/uk/examples/debug/counter-pod.yaml" download="debug/counter-pod.yaml"><code>debug/counter-pod.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('debug-counter-pod-yaml')" title="Копіювати debug/counter-pod.yaml до буферу обміну"></img></div>
    <div class="includecode" id="debug-counter-pod-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">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">Pod</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">counter</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">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">count</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">busybox:1.28</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">args</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">/bin/sh, -c,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s1">&#39;i=0; while true; do echo &#34;$i: $(date)&#34;; i=$((i+1)); sleep 1; done&#39;</span><span class="p">]</span><span class="w">
</span></span></span></code></pre></div></div>
</div>

Для запуску цього Podʼа використовуйте наступну команду:

```shell
kubectl apply -f https://k8s.io/examples/debug/counter-pod.yaml
```

Вивід буде таким:

```console
pod/counter created
```

Для отримання логів використовуйте команду `kubectl logs`, як показано нижче:

```shell
kubectl logs counter
```

Вивід буде схожим на:

```console
0: Fri Apr  1 11:42:23 UTC 2022
1: Fri Apr  1 11:42:24 UTC 2022
2: Fri Apr  1 11:42:25 UTC 2022
```

Ви можете використовувати `kubectl logs --previous` для отримання логів з попереднього запуску контейнера. Якщо ваш Pod має кілька контейнерів, вкажіть, логи якого контейнера ви хочете переглянути, додавши назву контейнера до команди з прапорцем `-c`, ось так:

```shell
kubectl logs counter -c count
```

### Потоки логів контейнерів {#container-log-streams}








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


Як альфа-функція, kubelet може розділяти логи з двох стандартних потоків, що створюються контейнером: [стандартний вивід](https://en.wikipedia.org/wiki/Standard_streams#Standard_output_(stdout)) та [стандартна помилка](https://en.wikipedia.org/wiki/Standard_streams#Standard_error_(stderr)). Щоб скористатися такою поведінкою, вам слід увімкнути [функціональну можливість](/docs/reference/command-line-tools-reference/feature-gates/) `PodLogsQuerySplitStreams`. З її увімкненням Kubernetes 1.36 надає доступ до цих потоків логів безпосередньо за допомогою Pod API. Ви можете отримати конкретний потік, вказавши назву потоку (або `Stdout`, або `Stderr`) за допомогою рядка запиту `stream`. Ви повинні мати доступ до читання підресурсу `log` цього Pod.

Щоб продемонструвати цю можливість, ви можете створити Pod, який періодично записуватиме текст як до стандартного потоку виводу, так і до потоку помилок.


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/uk/examples/debug/counter-pod-err.yaml" download="debug/counter-pod-err.yaml"><code>debug/counter-pod-err.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('debug-counter-pod-err-yaml')" title="Копіювати debug/counter-pod-err.yaml до буферу обміну"></img></div>
    <div class="includecode" id="debug-counter-pod-err-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">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">Pod</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">counter-err</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">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">count</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">busybox:1.28</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">args</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">/bin/sh, -c,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">            </span><span class="s1">&#39;i=0; while true; do echo &#34;$i: $(date)&#34;; echo &#34;$i: err&#34; &gt;&amp;2 ; i=$((i+1)); sleep 1; done&#39;</span><span class="p">]</span><span class="w">
</span></span></span></code></pre></div></div>
</div>

Для запуску цього podʼа скористайтесь наступною командою:

```shell
kubectl apply -f https://k8s.io/examples/debug/counter-pod-err.yaml
```

Щоб отримати лише потік логу stderr, ви можете виконати команду:

```shell
kubectl get --raw "/api/v1/namespaces/default/pods/counter-err/log?stream=Stderr"
```

Дивіться [документацію `kubectl logs`](/docs/reference/generated/kubectl/kubectl-commands#logs) для отримання додаткових деталей.

### Як вузли обробляють логи контейнерів {#how-nodes-handle-container-logs}

![Логування на рівні вузла](/images/docs/user-guide/logging/logging-node-level.png)

Система управління контейнерами обробляє та перенаправляє будь-який вивід, створений потоками `stdout` та `stderr` контейнеризованого застосунку. Різні системи управління контейнерами реалізують це по-різному; однак, інтеграція з kubelet стандартизована як _формат логування CRI_.

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

Kubelet надає доступ до логів клієнтам через спеціальну функцію Kubernetes API. Зазвичай доступ до неї здійснюється за допомогою команди `kubectl logs`.

### Ротація логів {#log-rotation}








  <div class="feature-state-notice feature-stable">
      <span class="feature-state-name">СТАН ФУНКЦІОНАЛУ:</span>
      <code>Kubernetes v1.21 [stable]</code>
    </div>
  



Kubelet відповідає за ротацію логів контейнерів та управління структурою тек логів. Kubelet передає цю інформацію до системи управління контейнерами (використовуючи CRI), а середовище виконання записує логи контейнерів у вказане місце.

Ви можете налаштувати два параметри конфігурації kubelet [`containerLogMaxSize`](/docs/reference/config-api/kubelet-config.v1beta1/) (типово 10Mi) та `containerLogMaxFiles` (типово 5), використовуючи [файл конфігурації kubelet](/docs/tasks/administer-cluster/kubelet-config-file/). Ці параметри дозволяють вам налаштувати максимальний розмір для кожного файлу лога та максимальну кількість файлів, дозволених для кожного контейнера відповідно.

Для ефективної ротації логів у кластерах, де обсяг логів, згенерованих робочим навантаженням, великий, kubelet також надає механізм налаштування ротації логів з погляду кількості одночасних ротацій логів та інтервалу, з яким логи відстежуються та ротуються за потребою. Ви можете налаштувати два параметри [конфігурації](/docs/reference/config-api/kubelet-config.v1beta1/) kubelet, `containerLogMaxWorkers` та `containerLogMonitorInterval` за допомогою [файлу конфігурації kubelet](/docs/tasks/administer-cluster/kubelet-config-file/).

Коли ви виконуєте [`kubectl logs`](/docs/reference/generated/kubectl/kubectl-commands#logs) як у прикладі базового логування, kubelet на вузлі обробляє запит і безпосередньо читає з файлу лога. Kubelet повертає вміст файлу лога.


<div class="alert alert-info" role="note"><h4 class="alert-heading">Примітка:</h4><p>Через <code>kubectl logs</code> доступний лише вміст останнього файлу лога.</p>
<p>Наприклад, якщо Pod пише 40 MiB логів і kubelet ротує логи після 10 MiB, виконання <code>kubectl logs</code> поверне максимум 10MiB даних.</p>
</div>


## Логи системних компонентів {#system-component-logs}

Існують два типи системних компонентів: ті, які зазвичай працюють у контейнерах, та ті компоненти, які безпосередньо відповідають за запуск контейнерів. Наприклад:

* Kubelet та система управління контейнерами не працюють у контейнерах. Kubelet виконує ваші контейнери (згруповані разом у <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>).
* Планувальник Kubernetes, менеджер контролерів та сервер API працюють у Podʼах (зазвичай <a class='glossary-tooltip' title='Pod, яким управляє безпосередньо демон kubelet на певному вузлі.' data-bs-toggle='tooltip' data-bs-placement='top' href='/uk/docs/tasks/configure-pod-container/static-pod/' target='_blank' aria-label='статичних Podʼах'>статичних Podʼах</a>). Компонент etcd працює у панелі управління, і зазвичай також як статичний Pod. Якщо ваш кластер використовує kube-proxy, зазвичай ви запускаєте його як `DaemonSet`.

### Знаходження логів {#log-location-node}

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

<ul class="nav nav-tabs" id="tabs-log-location-node-tabs" role="tablist"><li class="nav-item"><a data-bs-toggle="tab" class="nav-link active" href="#tabs-log-location-node-tabs-0" role="tab" aria-controls="tabs-log-location-node-tabs-0" aria-selected="true">Linux</a></li>
	  
		<li class="nav-item"><a data-bs-toggle="tab" class="nav-link" href="#tabs-log-location-node-tabs-1" role="tab" aria-controls="tabs-log-location-node-tabs-1">Windows</a></li></ul>

<div class="tab-content" id="tabs-log-location-node-tabs-content"><div class="tab-body tab-pane fadeshow active"
        id="tabs-log-location-node-tabs-0" role="tabpanel" aria-labelledby="tabs-log-location-node-tabs-0-tab" tabindex="log-location-node-tabs"><p>На вузлах Linux, які використовують systemd, типово kubelet та система управління контейнерами записують логи у журнал systemd. Ви можете використовувати <code>journalctl</code> для читання журналу systemd; наприклад: <code>journalctl -u kubelet</code>.</p>
<p>Якщо systemd відсутній, kubelet та система управління контейнерами записують логи у файли <code>.log</code> в директорії <code>/var/log</code>. Якщо ви хочете, щоб логи були записані в інше місце, ви можете опосередковано запустити kubelet через допоміжний інструмент, <code>kube-log-runner</code>, та використовувати цей інструмент для перенаправлення логів kubelet у вибрану вами теку.</p>
<p>Типово, kubelet спрямовує систему управління контейнерами на запис логів у теці всередині <code>/var/log/pods</code>.</p>
<p>Для отримання додаткової інформації про <code>kube-log-runner</code>, читайте <a href="/uk/docs/concepts/cluster-administration/system-logs/#klog">Системні логи</a>.</p>
</div><div class="tab-body tab-pane fade"
        id="tabs-log-location-node-tabs-1" role="tabpanel" aria-labelledby="tabs-log-location-node-tabs-1-tab" tabindex="log-location-node-tabs"><p>Типово kubelet записує логи у файли всередині теки <code>C:\var\logs</code> (⚠️ зверніть увагу, що це не <code>C:\var\log</code>).</p>
<p>Хоча <code>C:\var\log</code> є типовим місцем для цих логів Kubernetes, деякі інструменти розгортання кластера налаштовують вузли Windows так, щоб логи записувались у <code>C:\var\log\kubelet</code>.</p>
<p>Якщо ви хочете, щоб логи були записані в інше місце, ви можете опосередковано запустити kubelet через допоміжний інструмент, <code>kube-log-runner</code>, та використовувати цей інструмент для перенаправлення логів kubelet у вибрану вами директорію.</p>
<p>Проте, типово kubelet скеровує систему управління контейнерами на запис логів у теці всередині <code>C:\var\log\pods</code>.</p>
<p>Для отримання додаткової інформації про <code>kube-log-runner</code>, читайте <a href="/uk/docs/concepts/cluster-administration/system-logs/#klog">Системні логи</a>.</p>
</div></div>


<br /><!-- work around rendering nit -->

Для компонентів кластера Kubernetes, які працюють у Podʼах, логи записуються у файли всередині директорії `/var/log`, оминаючи типовий механізм логування (компоненти не записуються у журнал systemd). Ви можете використовувати механізми зберігання Kubernetes для відображення постійного зберігання у контейнері, який виконує компонент.

Kubelet дозволяє змінювати теку логів Podʼів зі стандартної `/var/log/pods` на власну. Це можна зробити за допомогою параметра `podLogsDir` у конфігураційному файлі kubelet.

<div class="alert alert-caution" role="note"><h4 class="alert-heading">Увага:</h4><p>Важливо зазначити, що стандартне розташування <code>/var/log/pods</code> використовувалося протягом тривалого часу, і певні процеси можуть неявно використовувати цей шлях. Тому до зміни цього параметра слід підходити з обережністю і на власний ризик.</p>
<p>Ще одним застереженням є те, що kubelet підтримує розташування на тому ж диску, що і <code>/var</code>. В іншому випадку, якщо логи знаходяться в окремій від <code>/var</code> файловій системі, то kubelet не буде відстежувати використання цієї файлової системи, що може призвести до проблем, якщо вона заповниться.</p>
</div>


Для отримання детальної інформації про etcd та його логи, перегляньте [документацію etcd](https://etcd.io/docs/). Знову ж таки, ви можете використовувати механізми зберігання Kubernetes для відображення постійного зберігання у контейнері, який виконує компонент.


<div class="alert alert-info" role="note"><h4 class="alert-heading">Примітка:</h4><p>Якщо ви розгортаєте компоненти кластера Kubernetes (наприклад, планувальник) для запису у спільний том від батьківського вузла, вам потрібно враховувати та забезпечувати, що ці логи ротуються. <strong>Kubernetes не керує цією ротацією логів</strong>.</p>
<p>Ваша операційна система може автоматично здійснювати деяку ротацію логів — наприклад, якщо ви ділитеся текою <code>/var/log</code> у статичному Podʼі для компонента, обробка ротації логів на рівні вузла обробляє файл у цій теці так само як записаний будь-яким компонентом поза Kubernetes.</p>
<p>Деякі інструменти розгортання враховують цю ротацію логів та автоматизують її; інші залишають це на вашу відповідальність.</p>
</div>


## Архітектури логування на рівні кластера {#cluster-level-logging-architectures}

Хоча Kubernetes не надає власного рішення для логування на рівні кластера, існують кілька загальних підходів, які ви можете розглянути. Ось деякі варіанти:

* Використання агента логування на рівні вузла, який працює на кожному вузлі.
* Додавання в Pod застосунку спеціального sidecar-контейнера для логування.
* Пряме надсилання логів безпосередньо до бекенду з застосунка.

### Використання агента логування на рівні вузла {#using-node-level-logging-agent}

![Використання агента логування на рівні вузла](/images/docs/user-guide/logging/logging-with-node-agent.png)

Ви можете реалізувати логування на рівні кластера, включивши _агента логування на рівні вузла_ на кожному вузлі. Агент логування — це спеціальний інструмент, який надає логи або надсилає їх до бекенду. Зазвичай агент логування є контейнером, який має доступ до теки з файлами логів з усіх контейнерів застосунків на цьому вузлі.

Оскільки агент логування повинен працювати на кожному вузлі, рекомендується запускати агента
як `DaemonSet`.

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

Контейнери пишуть у stdout та stderr, але без узгодженого формату. Агент на рівні вузла збирає
ці логи та пересилає їх для агрегації.

### Використання sidecar контейнера з агентом логування {#sidecar-container-with-logging-agent}

Ви можете використовувати sidecar контейнер у такий спосіб:

* sidecar контейнер транслює логи застосунку у свій власний `stdout`.
* sidecar контейнер запускає агента логування, який налаштований на збір логів з контейнера застосунку.

#### Sidecar контейнер для трансляції {#streaming-sidecar-container}

![Sidecar контейнер з контейнером для трансляції](/images/docs/user-guide/logging/logging-with-streaming-sidecar.png)

Маючи свої sidecar контейнери які пишуть у власні `stdout` та `stderr`, ви можете скористатися kubelet та агентом логування, які вже працюють на кожному вузлі. Sidecar контейнери читають логи з файлу, сокета або журналу. Кожен sidecar контейнер виводить лог у свій власний потік `stdout` або `stderr`.

Цей підхід дозволяє вам розділити кілька потоків логів з різних частин вашого застосунку деякі з яких можуть не підтримувати запис у `stdout` або `stderr`. Логіка перенаправлення логів мінімальна, тому це не становить значного навантаження. Крім того, оскільки `stdout` та `stderr` обробляються kubelet, ви можете використовувати вбудовані інструменти, такі як `kubectl logs`.

Наприклад, Pod запускає один контейнер, і контейнер записує до двох різних файлів логів з використанням двох різних форматів. Ось маніфест для Podʼа:


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/uk/examples/admin/logging/two-files-counter-pod.yaml" download="admin/logging/two-files-counter-pod.yaml"><code>admin/logging/two-files-counter-pod.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('admin-logging-two-files-counter-pod-yaml')" title="Копіювати admin/logging/two-files-counter-pod.yaml до буферу обміну"></img></div>
    <div class="includecode" id="admin-logging-two-files-counter-pod-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">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">Pod</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">counter</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">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">count</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">busybox:1.28</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">args</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">/bin/sh</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- -<span class="l">c</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="p">&gt;</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">      i=0;
</span></span></span><span class="line"><span class="cl"><span class="sd">      while true;
</span></span></span><span class="line"><span class="cl"><span class="sd">      do
</span></span></span><span class="line"><span class="cl"><span class="sd">        echo &#34;$i: $(date)&#34; &gt;&gt; /var/log/1.log;
</span></span></span><span class="line"><span class="cl"><span class="sd">        echo &#34;$(date) INFO $i&#34; &gt;&gt; /var/log/2.log;
</span></span></span><span class="line"><span class="cl"><span class="sd">        i=$((i+1));
</span></span></span><span class="line"><span class="cl"><span class="sd">        sleep 1;
</span></span></span><span class="line"><span class="cl"><span class="sd">      done</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">varlog</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">/var/log</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">varlog</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>

Не рекомендується записувати записи логів з різними форматами у той самий потік логу, навіть якщо вам вдалося перенаправити обидва компоненти до потоку `stdout` контейнера. Замість цього ви можете створити два додаткових sidecar контейнери. Кожен додатковий sidecar контейнер може перехоплювати певний файл логів зі спільного тома та перенаправляти логи до власного потоку `stdout`.

Ось маніфест для Podʼа, в якому є два sidecar контейнери:


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/uk/examples/admin/logging/two-files-counter-pod-streaming-sidecar.yaml" download="admin/logging/two-files-counter-pod-streaming-sidecar.yaml"><code>admin/logging/two-files-counter-pod-streaming-sidecar.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('admin-logging-two-files-counter-pod-streaming-sidecar-yaml')" title="Копіювати admin/logging/two-files-counter-pod-streaming-sidecar.yaml до буферу обміну"></img></div>
    <div class="includecode" id="admin-logging-two-files-counter-pod-streaming-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">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">Pod</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">counter</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">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">count</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">busybox:1.28</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">args</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">/bin/sh</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- -<span class="l">c</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="p">&gt;</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">      i=0;
</span></span></span><span class="line"><span class="cl"><span class="sd">      while true;
</span></span></span><span class="line"><span class="cl"><span class="sd">      do
</span></span></span><span class="line"><span class="cl"><span class="sd">        echo &#34;$i: $(date)&#34; &gt;&gt; /var/log/1.log;
</span></span></span><span class="line"><span class="cl"><span class="sd">        echo &#34;$(date) INFO $i&#34; &gt;&gt; /var/log/2.log;
</span></span></span><span class="line"><span class="cl"><span class="sd">        i=$((i+1));
</span></span></span><span class="line"><span class="cl"><span class="sd">        sleep 1;
</span></span></span><span class="line"><span class="cl"><span class="sd">      done</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">varlog</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">/var/log</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">count-log-1</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">busybox:1.28</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">args</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">/bin/sh, -c, &#39;tail -n+1 -F /var/log/1.log&#39;]</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">varlog</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">/var/log</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">count-log-2</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">busybox:1.28</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">args</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="l">/bin/sh, -c, &#39;tail -n+1 -F /var/log/2.log&#39;]</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">varlog</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">/var/log</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">varlog</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>

Тепер, коли ви запускаєте цей Pod, ви можете отримати доступ до кожного потоку логів окремо, запустивши такі команди:

```shell
kubectl logs counter count-log-1
```

Результат буде подібним до:

```console
0: Fri Apr  1 11:42:26 UTC 2022
1: Fri Apr  1 11:42:27 UTC 2022
2: Fri Apr  1 11:42:28 UTC 2022
...
```

```shell
kubectl logs counter count-log-2
```

Результат буде подібним до:

```console
Fri Apr  1 11:42:29 UTC 2022 INFO 0
Fri Apr  1 11:42:30 UTC 2022 INFO 0
Fri Apr  1 11:42:31 UTC 2022 INFO 0
...
```

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

Навіть для Podʼів, які використовують низьке використання CPU та памʼяті (наприклад, декілька мілікорів (millicore) для CPU та кілька мегабайтів для памʼяті), запис логів до файлу та їх трансляція до `stdout` можуть подвоїти обсяг памʼяті, необхідний на вузлі. Якщо у вас є застосунок, який записує у єдиний файл, рекомендується встановити `/dev/stdout` як призначення, а не впроваджувати підхід з sidecar контейнером для трансляції.

Sidecar контейнери також можуть використовуватися для ротації файлів логів, ротація яких не може бути зроблена самим застосунком. Прикладом такого підходу є малий контейнер, який періодично запускає `logrotate`. Однак набагато простіше використовувати `stdout` та `stderr` безпосередньо і
залишити ротації та політику зберігання kubelet.

#### Sidecar контейнер з агентом логування {#sidecar-container-with-a-logging-agent}

![Sidecar контейнер з агентом логування](/images/docs/user-guide/logging/logging-with-sidecar-agent.png)

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


<div class="alert alert-info" role="note"><h4 class="alert-heading">Примітка:</h4>Використання агента логування у sidecar контейнері може призвести до значного використання ресурсів. Щобільше, ви не зможете отримати доступ до цих логів за допомогою <code>kubectl logs</code>, оскільки вони не керуються kubelet.</div>


Ось два приклади маніфестів, які ви можете використати для впровадження sidecar контейнера з агентом логування. Перший маніфест містить [`ConfigMap`](/docs/tasks/configure-pod-container/configure-pod-configmap/), щоб налаштувати fluentd.


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/uk/examples/admin/logging/fluentd-sidecar-config.yaml" download="admin/logging/fluentd-sidecar-config.yaml"><code>admin/logging/fluentd-sidecar-config.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('admin-logging-fluentd-sidecar-config-yaml')" title="Копіювати admin/logging/fluentd-sidecar-config.yaml до буферу обміну"></img></div>
    <div class="includecode" id="admin-logging-fluentd-sidecar-config-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">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">ConfigMap</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">fluentd-config</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">data</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">fluentd.conf</span><span class="p">:</span><span class="w"> </span><span class="p">|</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">    &lt;source&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">      type tail
</span></span></span><span class="line"><span class="cl"><span class="sd">      format none
</span></span></span><span class="line"><span class="cl"><span class="sd">      path /var/log/1.log
</span></span></span><span class="line"><span class="cl"><span class="sd">      pos_file /var/log/1.log.pos
</span></span></span><span class="line"><span class="cl"><span class="sd">      tag count.format1
</span></span></span><span class="line"><span class="cl"><span class="sd">    &lt;/source&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">    &lt;source&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">      type tail
</span></span></span><span class="line"><span class="cl"><span class="sd">      format none
</span></span></span><span class="line"><span class="cl"><span class="sd">      path /var/log/2.log
</span></span></span><span class="line"><span class="cl"><span class="sd">      pos_file /var/log/2.log.pos
</span></span></span><span class="line"><span class="cl"><span class="sd">      tag count.format2
</span></span></span><span class="line"><span class="cl"><span class="sd">    &lt;/source&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">    &lt;match **&gt;
</span></span></span><span class="line"><span class="cl"><span class="sd">      type google_cloud
</span></span></span><span class="line"><span class="cl"><span class="sd">    &lt;/match&gt;</span><span class="w">
</span></span></span></code></pre></div></div>
</div>


<div class="alert alert-info" role="note"><h4 class="alert-heading">Примітка:</h4>У конфігураціях з прикладів ви можете замінити fluentd на будь-який агент логування, який читає з будь-якого джерела всередині контейнера застосунку.</div>


Другий маніфест описує Pod, в якому є sidecar контейнер, що запускає fluentd. Pod монтує том, де fluentd може отримати свої дані конфігурації.


















<div class="highlight code-sample">
    <div class="copy-code-icon">
    <a href="https://raw.githubusercontent.com/kubernetes/website/main/content/uk/examples/admin/logging/two-files-counter-pod-agent-sidecar.yaml" download="admin/logging/two-files-counter-pod-agent-sidecar.yaml"><code>admin/logging/two-files-counter-pod-agent-sidecar.yaml</code>
    </a><img src="/images/copycode.svg" class="icon-copycode" onclick="copyCode('admin-logging-two-files-counter-pod-agent-sidecar-yaml')" title="Копіювати admin/logging/two-files-counter-pod-agent-sidecar.yaml до буферу обміну"></img></div>
    <div class="includecode" id="admin-logging-two-files-counter-pod-agent-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">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">Pod</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">counter</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">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">count</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">busybox:1.28</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">args</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="l">/bin/sh</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- -<span class="l">c</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span>- <span class="p">&gt;</span><span class="sd">
</span></span></span><span class="line"><span class="cl"><span class="sd">      i=0;
</span></span></span><span class="line"><span class="cl"><span class="sd">      while true;
</span></span></span><span class="line"><span class="cl"><span class="sd">      do
</span></span></span><span class="line"><span class="cl"><span class="sd">        echo &#34;$i: $(date)&#34; &gt;&gt; /var/log/1.log;
</span></span></span><span class="line"><span class="cl"><span class="sd">        echo &#34;$(date) INFO $i&#34; &gt;&gt; /var/log/2.log;
</span></span></span><span class="line"><span class="cl"><span class="sd">        i=$((i+1));
</span></span></span><span class="line"><span class="cl"><span class="sd">        sleep 1;
</span></span></span><span class="line"><span class="cl"><span class="sd">      done</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">varlog</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">/var/log</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">count-agent</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">registry.k8s.io/fluentd-gcp:1.30</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">env</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">FLUENTD_ARGS</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">      </span><span class="nt">value</span><span class="p">:</span><span class="w"> </span>-<span class="l">c /etc/fluentd-config/fluentd.conf</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">varlog</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">/var/log</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">config-volume</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">/etc/fluentd-config</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">varlog</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><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">config-volume</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">configMap</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">fluentd-config</span><span class="w">
</span></span></span></code></pre></div></div>
</div>

### Викладення логів безпосередньо з застосунку {#exposing-logs-directly-from-application}

![Викладення логів безпосередньо з застосунку](/images/docs/user-guide/logging/logging-from-application.png)

Кластерне логування, яке викладає або надсилає логи безпосередньо з кожного застосунку, виходить за межі цілей Kubernetes.

## Що далі

* Дізнайтеся про [системні журнали Kubernetes](/docs/concepts/cluster-administration/system-logs/)
* Дізнайтеся про [Trace для компонентів системи Kubernetes](/docs/concepts/cluster-administration/system-traces/)
* Дізнайтеся, як [налаштувати повідомлення про припинення роботи](/docs/tasks/debug/debug-application/determine-reason-pod-failure/#customizing-the-termination-message) яке Kubernetes записує, коли Pod зазнає збою.
