Tutorial

Инспектирование сетевых компонентов Kubernetes

Published on January 24, 2020
Русский
Инспектирование сетевых компонентов Kubernetes

Введение

Kubernetes — это система организации контейнеров, способная управлять контейнерными приложениями в кластере серверных узлов. Для обеспечения доступа к сети для всех контейнеров в кластере требуются сложные схемы сетевых подключений. В этой статье мы кратко расскажем о некоторых инструментах и методиках для проверки используемой схемы сетевых подключений.

Эти инструменты могут быть полезны для отладки проблем со связью, расследования проблем с пропускной способностью сети или изучения принципов работы Kubernetes.

Если вы хотите узнать больше о Kubernetes, вам поможет наше руководство «Введение в Kubernetes». Для обзора сетевых возможностей Kubernetes прочитайте статью «Сети в Kubernetes: под капотом».

Начало работы

В этом обучающем модуле предполагается, что у вас имеется кластер Kubernetes с установленным локальным компонентом kubectl, настроенным для подключения к кластеру.

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

  1. echo 'this is a node command'

Команды для выполнения на локальном компьютере будут выглядеть так:

  1. echo 'this is a local command'

Примечание. Большнство команд в этом обучающем модуле должно выполняться от имени пользователя root Если вы используете пользователя с привилегиями sudo на узлах Kubernetes, добавьте sudo для запуска команд, когда это требуется.

Поиск IP-адреса кластера пода

Чтобы найти IP-адрес кластера пода Kubernetes, запустите на локальном компьютере команду kubectl get pod с опцией -o wide. Эта опция выводит больше информации, включая узел размещения пода и IP-адрес кластера пода.

  1. kubectl get pod -o wide
Output
NAME READY STATUS RESTARTS AGE IP NODE hello-world-5b446dd74b-7c7pk 1/1 Running 0 22m 10.244.18.4 node-one hello-world-5b446dd74b-pxtzt 1/1 Running 0 22m 10.244.3.4 node-two

В столбце IP будет указан внутренний IP-адрес кластера для каждого пода.

Если вы не видите под, который вам нужен, проверьте правильность выбора пространства имен. Вы можете вывести список всех подов во всех пространствах имен с помощью флага --all-namespaces.

Поиск IP-адреса службы

С помощью команды kubectl также можно определить IP-адрес службы. В данном случае мы выводим список всех служб во всех пространствах имен:

  1. kubectl get service --all-namespaces
Output
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE default kubernetes ClusterIP 10.32.0.1 <none> 443/TCP 6d kube-system csi-attacher-doplugin ClusterIP 10.32.159.128 <none> 12345/TCP 6d kube-system csi-provisioner-doplugin ClusterIP 10.32.61.61 <none> 12345/TCP 6d kube-system kube-dns ClusterIP 10.32.0.10 <none> 53/UDP,53/TCP 6d kube-system kubernetes-dashboard ClusterIP 10.32.226.209 <none> 443/TCP 6d

IP-адрес службы указывается в столбце CLUSTER-IP.

Поиск и ввод сетевых пространств имен подов

Каждому поду Kubernetes присваивается собственное сетевое пространство имен. Сетевые пространства имен (netns) — это примитив сетей Linux, обеспечивающий изоляцию сетевых устройств.

Запускать команды через netns пода может быть полезно для проверки разрешения DNS или общей работоспособности сети. Для этого нужно предварительно посмотреть идентификатор процесса одного из контейнеров в поде. Для Docker мы можем сделать это с помощью серии из двух команд. Вначала выведите список контейнеров, запущенных на узле:

  1. docker ps
Output
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 173ee46a3926 gcr.io/google-samples/node-hello "/bin/sh -c 'node se…" 9 days ago Up 9 days k8s_hello-world_hello-world-5b446dd74b-pxtzt_default_386a9073-7e35-11e8-8a3d-bae97d2c1afd_0 11ad51cb72df k8s.gcr.io/pause-amd64:3.1 "/pause" 9 days ago Up 9 days k8s_POD_hello-world-5b446dd74b-pxtzt_default_386a9073-7e35-11e8-8a3d-bae97d2c1afd_0 . . .

Найдите идентификатор контейнера или имя любого контейнера в поде, который вас интересует. В показанных выше результатах отображается два контейнера:

  • Первый контейнер — это приложение hello-world, запущенное в поде hello-world
  • Второй — это контейнер pause, запущенный в поде hello-world. Этот контейнер используется исключительно для захвата сетевого пространства имен пода

Чтобы получить идентификатор процесса любого из контейнеров, запишите идентификатор контейнера или имя и используйте его в следующей команде docker:

  1. docker inspect --format '{{ .State.Pid }}' container-id-or-name
Output
14552

Будет выведен идентификатор процесса (или PID). Теперь мы можем использовать программу nsenter для запуска команды в сетевом пространстве имен этого процесса:

  1. nsenter -t your-container-pid -n ip addr

Обязательно используйте собственный PID и замените ip addr командой, которую вы хотите запустить в сетевом пространстве имен пода.

Примечание. Использование nsenter для запуска команд в пространстве имен пода дает преимущества по сравнению с такими программами как docker exec. Это преимущество заключается в том, что у вас имеется доступ ко всем командам, поддерживаемым узлом, а не только к ограниченному набору команд, установленному в контейнерах.

Поиск интерфейса виртуальной сети Ethernet пода

Каждое пространство имен пода взаимодействует с пространством root netns через виртуальный конвейер ethernet. Со стороны узла этот конвейер выглядит как устройство, которое обычно начинается с veth и заканчивается уникальным идентификатором, например veth77f2275 или veth01. Внутри пода этот конвейер выглядит как eth0.

Его можно использовать для корреляции устройств veth, сопряженных с конкретными подами. Для этого мы выводим список всех сетевых устройств в узле, а затем выводим список устройств в сетевом пространстве имен пода. Для получения связи мы можем провести корреляцию номеров устройств в двух списках.

Запустите команду ip addr в сетевом пространстве имен пода, используя nsenter. Более подробную информацию об этом можно найти в предыдущем разделе «Поиск и ввод пространств имен подов»:

  1. nsenter -t your-container-pid -n ip addr
Output
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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 10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue state UP group default link/ether 02:42:0a:f4:03:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 10.244.3.4/24 brd 10.244.3.255 scope global eth0 valid_lft forever preferred_lft forever

Данная команда выводит список интерфейсов пода. Запишите номер if11 после eth0@ на экране результатов примера. Это означает, что конвейер eth0 этого пода связан с 11-м интерфейсом узла. Теперь запустите команду ip addr в пространстве имен по умолчанию узла для перечисления его интерфейсов:

  1. ip addr
Output
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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 inet6 ::1/128 scope host valid_lft forever preferred_lft forever . . . 7: veth77f2275@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master docker0 state UP group default link/ether 26:05:99:58:0d:b9 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::2405:99ff:fe58:db9/64 scope link valid_lft forever preferred_lft forever 9: vethd36cef3@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master docker0 state UP group default link/ether ae:05:21:a2:9a:2b brd ff:ff:ff:ff:ff:ff link-netnsid 1 inet6 fe80::ac05:21ff:fea2:9a2b/64 scope link valid_lft forever preferred_lft forever 11: veth4f7342d@if10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1450 qdisc noqueue master docker0 state UP group default link/ether e6:4d:7b:6f:56:4c brd ff:ff:ff:ff:ff:ff link-netnsid 2 inet6 fe80::e44d:7bff:fe6f:564c/64 scope link valid_lft forever preferred_lft forever

В этом примере 11-й интерфейс — это интерфейс veth4f7342d. Это конвейер виртуальной сети ethernet к исследуемому нами поду.

Проверка отслеживания соединения Conntrack

До выпуска версии 1.11 в Kubernetes для отслеживания соединений использовались таблицы NAT iptables и модуль ядра conntrack. Для вывода списка всех отслеживаемых соединений используйте команду conntrack:

  1. conntrack -L

Чтобы постоянно отслеживать новые соединения, используйте флаг -E:

  1. conntrack -E

Чтобы вывести отслеживаемые conntrack соединения на определенный адрес назначения, используйте флаг -d:

  1. conntrack -L -d 10.32.0.1

Если у ваших узлов возникают проблемы с установлением надежных соединений со службами, это может означать, что ваша таблица отслеживания подключений полная, и что новые соединения отбрасываются. В этом случае вы можете увидеть в системных журналах сообщения следующего вида:

/var/log/syslog
Jul 12 15:32:11 worker-528 kernel: nf_conntrack: table full, dropping packet.

Это настройка sysctl для отслеживания максимального количества соединений. Вы можете вывести список текущих значений с помощью следующей команды:

  1. sysctl net.netfilter.nf_conntrack_max
Output
net.netfilter.nf_conntrack_max = 131072

Используйте флаг -w для установки нового значения:

  1. sysctl -w net.netfilter.nf_conntrack_max=198000

Чтобы сделать этот параметр постоянным. добавьте его в файл sysctl.conf:

/etc/sysctl.conf
. . .
net.ipv4.netfilter.ip_conntrack_max = 198000

Проверка правил таблиц Iptables

До выпуска версии 1.11 в Kubernetes использовались таблицы NAT iptables для преобразования виртуальных IP-адресов и балансировки нагрузки служебных IP-адресов.

Чтобы сохранить все правила таблиц iptables на узле, используйте команду iptables-save:

  1. iptables-save

Поскольку результаты могут быть длинными, вы можете отправить результаты через конвейер в файл (iptables-save > output.txt) или на пейджер (iptables-save | less) для большего удобства просмотра.

Чтобы вывести только правила NATдля службы Kubernetes, используйте команду iptables и флаг -L для указания правильной цепочки:

  1. iptables -t nat -L KUBE-SERVICES
Output
Chain KUBE-SERVICES (2 references) target prot opt source destination KUBE-SVC-TCOU7JCQXEZGVUNU udp -- anywhere 10.32.0.10 /* kube-system/kube-dns:dns cluster IP */ udp dpt:domain KUBE-SVC-ERIFXISQEP7F7OF4 tcp -- anywhere 10.32.0.10 /* kube-system/kube-dns:dns-tcp cluster IP */ tcp dpt:domain KUBE-SVC-XGLOHA7QRQ3V22RZ tcp -- anywhere 10.32.226.209 /* kube-system/kubernetes-dashboard: cluster IP */ tcp dpt:https . . .

Запросы DNS кластера

Один из способов отладки разрешения DNS кластера заключается в развертывании контейнера отладки с помощью всех необходимых инструментов и использование kubectl для выполнения команды nslookup. Это описывается в официальной документации по Kubernetes.

Еще один способ запроса DNS кластера заключается в том, чтобы использовать dig и nsenter с узла. Если dig не установлен, его можно установить с помощью apt в дистрибутивах Linux на базе Debian:

  1. apt install dnsutils

Вначале найдите IP-адрес кластера службы kube-dns:

  1. kubectl get service -n kube-system kube-dns
Output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kube-dns ClusterIP 10.32.0.10 <none> 53/UDP,53/TCP 15d

IP-адрес кластера подсвечен выше. Теперь мы используем nsenter для запуска dig в пространстве имен контейнера. Дополнительную информацию об этом можно найти в разделе «Поиск и ввод сетевых пространств имен подов»:

  1. nsenter -t 14346 -n dig kubernetes.default.svc.cluster.local @10.32.0.10

Команда dig ищет полное доменное имя службы service-name.namespace.svc.cluster.local и указывает IP-адрес службы DNS кластера (@10.32.0.10).

Просмотр деталей IPVS

В версии Kubernetes 1.11 команда kube-proxy может настроить IPVS для обработки преобразования виртуальных IP-адресов служб в IP-адреса подов. Вы можете вывести таблицу преобразования IP-адресов с помощью команды ipvsadm:

  1. ipvsadm -Ln
Output
IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 100.64.0.1:443 rr -> 178.128.226.86:443 Masq 1 0 0 TCP 100.64.0.10:53 rr -> 100.96.1.3:53 Masq 1 0 0 -> 100.96.1.4:53 Masq 1 0 0 UDP 100.64.0.10:53 rr -> 100.96.1.3:53 Masq 1 0 0 -> 100.96.1.4:53 Masq 1 0 0

Чтобы вывести IP-адрес одной службы, используйте опцию -t и укажите желаемый IP-адрес:

  1. ipvsadm -Ln -t 100.64.0.10:53
Output
Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 100.64.0.10:53 rr -> 100.96.1.3:53 Masq 1 0 0 -> 100.96.1.4:53 Masq 1 0 0

Заключение

В этой статье мы рассмотрели некоторые команды и методики изучения и проверки сетевых подключений вашего кластера Kubernetes. Более подробную информацию по Kubernetes можно найти в наших обучающих модулях по Kubernetes и официальной документации по Kubernetes.

Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.

Learn more about our products

About the authors

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
Leave a comment


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Featured on Community

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more