Инструмент устранения неполадок сети Kubernetes kubectl-debug

Kubernetes
Инструмент устранения неполадок сети Kubernetes kubectl-debug

задний фон

Лучшей практикой в ​​​​технологии контейнеров является создание образа контейнера наименьшего возможного размера. Но такая практика может вызвать проблемы при устранении неполадок: в уменьшенных контейнерах обычно отсутствуют общие инструменты устранения неполадок, а некоторые контейнеры даже не имеют оболочки (например,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 Подробный процесс

  1. Плагин запрашивает ApiServer: существует ли демо-модуль и на каком узле он находится?
  2. ApiServer возвращает узел, на котором находится демо-модуль.
  3. Запрос плагина создается на целевом узлеDebug Agent Pod
  4. Кубелет созданиеDebug Agent Pod
  5. открытие плагинаDebug AgentГотов, запрос на инициацию отладки (длинная ссылка)
  6. 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.

Шесть справочных ссылок