Поиск по сайту:

Как проверить сеть Kubernetes


Введение

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

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

Если вы хотите узнать больше о Kubernetes в целом, ознакомьтесь с нашим руководством Kubernetes Networking Under the Hood.

Начиная

В этом руководстве предполагается, что у вас есть кластер 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 службы

Мы также можем найти IP-адрес службы, используя kubectl. В этом случае мы перечислим все службы во всех пространствах имен:

  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.

Поиск и ввод пространств имен Pod Network

Каждому поду 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-интерфейса пода

Сетевое пространство имен каждого модуля взаимодействует с корневым 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 использовал iptables NAT и модуль ядра conntrack для отслеживания подключений. Чтобы вывести список всех отслеживаемых соединений, используйте команду conntrack:

  1. conntrack -L

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

  1. conntrack -E

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

  1. conntrack -L -d 10.32.0.1

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

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:

. . .
net.ipv4.netfilter.ip_conntrack_max = 198000

Проверка правил Iptables

До версии 1.11 Kubernetes использовал iptables NAT для реализации преобразования виртуальных 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-адрес кластера. 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.