#kubernetes
#kubernetes
Вопрос:
У меня есть pod в состоянии CrashLoopBackOff
, журналы, которые я вижу из kubectl logs <pod-name> -p
, представляют собой лишь частичную картинку. Другие журналы находятся в других файлах (например, /var/log/something/something.log
).
Поскольку этот pod разбился, я не могу kubectl exec
войти в тамошнюю оболочку и посмотреть файлы.
Как я могу просмотреть файлы журналов, созданные контейнером, который больше не запущен?
Чтобы быть более конкретным, я ищу файлы журналов под $HOME/logs/es.log
(в контейнере, который потерпел неудачу)
Комментарии:
1. Журналы Docker хранятся на рабочих узлах под
/var/log/containers/
. Если у вас не включена ротация, они сохраняются, даже если pods не запущены.2. Я не ищу журналы docker. возможно, мне следовало быть более ясным. Журналы, которые я ищу, находятся по адресу $HOME/logs /es.log
3. Ах. В этом случае, если журналы не записываются на постоянный том, нет способа получить к ним доступ после удаления контейнера. Однако имейте в виду, что любой вывод stdout и stderr перехватывается docker и записывается в
/var/log/containers/
. Итак, если содержимое$HOME/logs/es.log
также было записано в stdout, вы должны иметь возможность получить к ним доступ с рабочего узла, на котором он изначально запускался.
Ответ №1:
Я был настолько разочарован отсутствием решения этой, казалось бы, распространенной проблемы, что создал образ docker, который отслеживает файлы журналов и отправляет их в stdout для использования в качестве контейнера sidecar.
Вот что я сделал:
- Я добавил том с
emptyDir{}
в pod - Я подключил этот том к своему основному контейнеру, причем
mountPath
является каталогом, в который он записывает журналы - Я добавил в pod другой контейнер, называемый «logger», с изображением, являющимся написанным мной средством отслеживания журналов (
lutraman/logger-sidecar:v2
), и подключил тот же том к/logs
(я запрограммировал скрипт для чтения журналов из этого каталога)
затем все журналы, записанные в этот каталог, могут быть доступны kubectl logs <pod-name> -c logger
Вот пример yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: dummy
labels:
app: dummy
spec:
selector:
matchLabels:
app: dummy
template:
metadata:
labels:
app: dummy
spec:
volumes:
- name: logs
emptyDir: {}
containers:
- name: dummy-app # the app that writes logs to files
image: lutraman/dummy:v2
ports:
- containerPort: 8080
name: http
protocol: TCP
env:
- name: MESSAGE
value: 'hello-test'
- name: LOG_FILE
value: '/var/log/app.log'
volumeMounts:
- name: logs
mountPath: /var/log
- name: logger # the sidecar container tracking logs and sending them to stdout
image: lutraman/logger-sidecar:v2
volumeMounts:
- name: logs
mountPath: /logs
Для всех, кому интересно, вот как я создал контейнер sidecar:
Dockerfile:
FROM alpine:3.9
RUN apk add bash --no-cache
COPY addTail /addTail
COPY logtrack.sh /logtrack.sh
CMD ["./logtrack.sh"]
addTail:
#!/bin/sh
(exec tail -F logs/$3 | sed "s/^/$3: /" ) amp;
echo $! >> /tmp/pids
logtrack.sh:
#!/bin/bash
trap cleanup INT
function cleanup() {
while read pid; do kill $pid; echo killed $pid; done < /tmp/pids
}
: > /tmp/pids
for log in $(ls logs); do
./addTail n logs $log
done
inotifyd ./addTail `pwd`/logs:n
Комментарии:
1. как насчет ‘logrotate’? это было рассмотрено?
2. Спасибо, что поделились! Это похоже на разделы «Использование контейнера sidecar с агентом ведения журнала» в официальной документации k8s. kubernetes.io/docs/concepts/cluster-administration/logging /…
3. Аналогично вопросу @Tun, вы периодически очищали файл журнала? Поскольку теперь файл журнала дублируется в stdout, это удвоит использование диска
4. @yusong вы правы, это удвоит размер на диске за время работы pod. В моем случае это было не очень актуально, поскольку исходные файлы сохранялись в fs контейнера, который является эфемерным и будет удаляться при каждом перезапуске (что в моем случае было достаточно частым, чтобы не беспокоиться). Остальные журналы сохраняются в elastic, для которых у меня есть ротация. Это обоснованная проблема, если у вас большие файлы журналов и между перезапусками проходит много времени
5. Или вы можете поместить стандартный вывод в logback.xml проблема решена
Ответ №2:
В принципе, здесь у вас есть несколько вариантов.
Если вы хотите продолжить, как есть, с вашей настройкой,
вы можете получить доступ к файлам завершенного контейнера с хоста, на котором запущен контейнер.
Узнайте, на каком рабочем компьютере находится контейнер:
$ kubectl get pod my-pod -o custom-columns=Node:{.spec.nodeName} --no-headers
my-worker-node
Затем, если у вас есть доступ к этому узлу (например, через shh), вы можете найти контейнер:
$ ID=$(docker ps -a | grep my-pod | grep -v POD | cut -d" " -f1)
$ docker cp $ID:/my.log .
$ cat my.log
log entry
Если у вас нет доступа ssh к узлу, вы можете использовать плагины, подобные этому:https://github.com/kvaps/kubectl-enter
Но, как правило, это не лучшая практика
Вы не должны записывать журналы в файлы, вместо этого ваше приложение должно записывать в stdout / stderr, тогда было бы намного проще отлаживать
Ответ №3:
Вы пробовали использовать --previous
флаг?
Это как
$ kubectl logs <pod-name> <container-name> --previous