задний фон
Лучшей практикой в технологии контейнеров является создание образа контейнера наименьшего возможного размера. Но такая практика может вызвать проблемы при устранении неполадок: в уменьшенных контейнерах обычно отсутствуют общие инструменты устранения неполадок, а некоторые контейнеры даже не имеют оболочки (например,FROM scratch
).在这种状况下,我们只能通过日志或者到宿主机上通过 docker-cli 或 nsenter 来排查问题,效率很低。需要一款k8s排障工具帮助诊断目标容器,kubectl-debug就是一款(GitHub.com/aaaaaa/cry bec…): ** Хороший инструмент для диагностики целевого контейнера путем запуска контейнера с установленными различными инструментами устранения неполадок.
Два обзора
2.1 Принцип работы
Контейнер — это, по сути, группа процессов с ограничениями ресурсов cgroup и изоляцией пространства имен. Следовательно, пока мы запускаем процесс и добавляем этот процесс в различные пространства имен целевого контейнера, процесс может «войти внутрь контейнера» (обратите внимание на кавычки) и «увидеть» ту же корневую файловую систему, что и процесс в контейнер. , виртуальная сетевая карта, пространство процесса - это именно то, чтоdocker exec
иkubectl exec
И т.д. Как работает команда.
Текущая ситуация такова, что мы не только хотим «зайти внутрь контейнера», но также хотим ввести набор инструментов для устранения неполадок. Затем, если вы хотите эффективно управлять набором инструментов и иметь возможность кроссплатформенности, лучший способ — упаковать сами инструменты в образ контейнера. Далее нам нужно только запустить контейнер через этот «образ инструмента», а затем указать, что контейнер добавляется в различные пространства имен целевого контейнера, и естественно «перенести набор инструментов в контейнер». На самом деле это можно сделать с помощью docker-cli:
export TARGET_ID=666666666
# 加入目标容器的 network, pid 以及 ipc namespace
docker run -it --network=container:$TARGET_ID --pid=container:$TARGET_ID --ipc=container:$TARGET_ID busybox
2.2 Подробная блок-схема
2.2.1 Блок-схема
Здесь на помощь приходит kubectl-debug:Использование контейнеров инструментов для диагностики бизнес-контейнеров. Идея дизайна, лежащая в основе этого, согласуется с такими шаблонами, как коляска: каждый контейнер выполняет только одну функцию.
Конкретно для реализации,kubectl debug <target-pod>
За командой:
2.2.2 Подробный процесс
- Плагин запрашивает ApiServer: существует ли демо-модуль и на каком узле он находится?
- ApiServer возвращает узел, на котором находится демо-модуль.
- Запрос плагина создается на целевом узле
Debug Agent
Pod - Кубелет создание
Debug Agent
Pod - открытие плагина
Debug Agent
Готов, запрос на инициацию отладки (длинная ссылка) -
Debug Agent
После получения запроса на отладку создайте контейнер отладки и добавьте его в каждое пространство имен целевого контейнера.После завершения создания установите соединение с tty контейнера отладки.
Далее клиент может начать операции отладки через два соединения 5 и 6. После операции агент отладки очищает контейнер отладки, подключаемый модуль очищает агент отладки, и отладка завершается один раз. Эффект следующий:
Три установки и развертывания
3.1 установка kubectl-debug
3.1.1 установка на Mac
# brew安装
brew install aylei/tap/kubectl-debug
# 二进制安装
export PLUGIN_VERSION=0.1.1
curl -Lo kubectl-debug.tar.gz https://github.com/aylei/kubectl-debug/releases/download/v${PLUGIN_VERSION}/kubectl-debug_${PLUGIN_VERSION}_darwin_amd64.tar.gz
tar -zxvf kubectl-debug.tar.gz kubectl-debug
sudo mv kubectl-debug /usr/local/bin/
3.1.2 Установка Linux
export PLUGIN_VERSION=0.1.1
# linux x86_64
curl -Lo kubectl-debug.tar.gz https://github.com/aylei/kubectl-debug/releases/download/v${PLUGIN_VERSION}/kubectl-debug_${PLUGIN_VERSION}_linux_amd64.tar.gz
tar -zxvf kubectl-debug.tar.gz kubectl-debug
sudo mv kubectl-debug /usr/local/bin/
3.2 установка DaemonSet отладочного агента
kubectl-debug
Содержит две части: одна — подключаемый модуль kubectl на стороне пользователя, а другая — агент, развернутый на всех узлах k8s (используется для запуска «новых контейнеров», а также действует как ретранслятор для соединений SPDY).agentless
середина,kubectl-debug
Под отладочного агента будет создан при запуске отладки и будет автоматически очищен после ее завершения (режим без агента включен по умолчанию).
agentless
Хоть это и удобно, но значительно замедлит скорость запуска отладки.Вы можете использовать режим агента, предварительно установив DaemonSet отладки-агента и указав параметр --agentless=false для ускорения скорости запуска:
# 如果你的kubernetes版本为v1.16或更高
kubectl apply -f https://raw.githubusercontent.com/aylei/kubectl-debug/master/scripts/agent_daemonset.yml
# 如果你使用的是旧版本的kubernetes(<v1.16), 你需要先将apiVersion修改为extensions/v1beta1, 可以如下操作
wget https://raw.githubusercontent.com/aylei/kubectl-debug/master/scripts/agent_daemonset.yml
sed -i '' '1s/apps\/v1/extensions\/v1beta1/g' agent_daemonset.yml
kubectl apply -f agent_daemonset.yml
# 或者使用helm安装
helm install kubectl-debug -n=debug-agent ./contrib/helm/kubectl-debug
# 使用daemonset agent模式(关闭agentless模式)
kubectl debug --agentless=false POD_NAME
четыре использования
kubectl debug -h
老版本的 kubectl 无法自动发现插件, 需要直接调用 binary
kubect-debug POD_NAME
假如安装了 debug-agent 的 daemonset, 可以略去 --agentless 来加快启动速度
之后的命令里会略去 --agentless
kubectl debug POD_NAME --agentless
假如 Pod 处于 CrashLookBackoff 状态无法连接, 可以复制一个完全相同的 Pod 来进行诊断
kubectl debug POD_NAME --fork
假如 Node 没有公网 IP 或无法直接访问(防火墙等原因), 请使用 port-forward 模式
kubectl debug POD_NAME --port-forward --daemonset-ns=kube-system --daemonset-name=debug-agent
4.1 Использование безагентного режима
Использование режима без агенирования нет необходимости устанавливать POD в узле узла, но вам нужно каждый раз тянуть зеркало, недоразумение медленное, но это более чисто, а не в кластерной установке отладки.
[root@master01 kubectl-debug]# kubectl debug --agentless=true centos-778d877549-7r5h8 -n anchnet-devops-dev
Agent Pod info: [Name:debug-agent-pod-44e763d0-edad-11ea-bbaf-5254f5694cb5, Namespace:default, Image:aylei/debug-agent:latest, HostPort:10027, ContainerPort:10027]
Waiting for pod debug-agent-pod-44e763d0-edad-11ea-bbaf-5254f5694cb5 to run...
pulling image nicolaka/netshoot:latest...
latest: Pulling from nicolaka/netshoot
Digest: sha256:04786602e5a9463f40da65aea06fe5a825425c7df53b307daa21f828cfe40bf8
Status: Image is up to date for nicolaka/netshoot:latest
starting debug container...
container created, open tty...
bash-5.0# netstat -lntup
4.2 Используйте другие методы устранения неполадок
Когда приложение, работающее в k8s, сталкивается с проблемой, помимо использования kubectl-debug для входа в контейнер, вы также можете использовать nsenter для входа в пространство имен сети контейнера и использовать tcpdump для анализа перехвата пакетов.
- Определите, на каком хост-узле работает модуль для просмотра, а затем войдите на хост-узел, чтобы устранить проблемы с сетью.
- Найдите контейнер через pod, найдите pid, работающий на хосте, через контейнер, а затем используйте
nsenter -n —target $pid
После входа в сетевое пространство имен контейнера вы можете использовать инструменты хоста для просмотра сетевых условий в модуле.
Вы можете использовать следующий сценарий, чтобы зарегистрировать функцию на узле, на котором запущен модуль, а затем проверить сеть модуля.
function netcheck() {
set -eu
ns=${2-"default"}
pod=`kubectl -n $ns describe pod $1 | grep -A10 "^Containers:" | grep -Eo 'docker://.*$' | head -n 1 | sed 's/docker:\/\/\(.*\)$/\1/'`
pid=`docker inspect -f {{.State.Pid}} $pod`
echo "entering pod netns for $ns/$1"
cmd="nsenter -n --target $pid"
echo $cmd
$cmd
}
Тест со скриптом
[root@node01 ~]# kubectl get po
NAME READY STATUS RESTARTS AGE
nginx-98f85fbb8-ql2gv 1/1 Running 2 29d
# 注册函数
[root@node01 ~]# function netcheck() {
> set -eu
> ns=${2-"default"}
> pod=`kubectl -n $ns describe pod $1 | grep -A10 "^Containers:" | grep -Eo 'docker://.*$' | head -n 1 | sed 's/docker:\/\/\(.*\)$/\1/'`
> pid=`docker inspect -f {{.State.Pid}} $pod`
> echo "entering pod netns for $ns/$1"
> cmd="nsenter -n --target $pid"
> echo $cmd
> $cmd
> }
# 进入容器网络名称空间
[root@node01 ~]# netcheck nginx-98f85fbb8-ql2gv
entering pod netns for default/nginx-98f85fbb8-ql2gv
nsenter -n --target 4536
# 通过工具查看网络情况。
[root@node01 ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
3: eth0@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP
link/ether ba:0e:65:c4:bb:1c brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 10.233.82.89/32 scope global eth0
valid_lft forever preferred_lft forever
4: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1
link/ipip 0.0.0.0 brd 0.0.0.0
[root@node01 ~]# ss -tnl
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:80 *:*
LISTEN 0 128 :::80 :::*
Пять вопросов, требующих внимания
-
Если вы используете безагентный режим, вам необходимо изменить конфигурацию при установке отладочного агента.
-
Запустить kubectl-debug Если модуль не найден, необходимо указать пространство имен целевого модуля -n.