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

Вступление

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

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

Если вы хотите узнать больше о Kubernetes в целом, наше руководствоAn Introduction to Kubernetes охватывает основы. Для обзора Kubernetes, специфичного для сетей, прочтитеKubernetes Networking Under the Hood.

Начиная

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

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

echo 'this is a node command'

Команды, которые должны выполняться на вашем локальном компьютере, будут иметь следующий вид:

echo 'this is a local command'

[.note] #Note: Большинство команд в этом руководстве нужно будет запускать от имени пользователяroot. Если вместо этого вы используете пользователя с поддержкой sudo на своих узлах Kubernetes, добавьтеsudo для запуска команд при необходимости.
#

Поиск IP-адреса кластера модуля

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

kubectl get pod -o wide
OutputNAME                           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. В этом случае мы перечислим все сервисы во всех пространствах имен:

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

IP-адрес службы можно найти в столбцеCLUSTER-IP.

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

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

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

docker ps
OutputCONTAINER 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
. . .

Найдитеcontainer ID илиname любого контейнера в интересующем вас модуле. В приведенном выше выводе мы показываем два контейнера:

  • Первый контейнер - это приложениеhello-world, работающее в модулеhello-world.

  • Второй - контейнерpause, работающий в модулеhello-world. Этот контейнер существует исключительно для хранения в пространстве имен сети модуля

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

docker inspect --format '{{ .State.Pid }}' container-id-or-name
Output14552

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

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

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

[.note] #Note: Одно из преимуществ использованияnsenter для запуска команд в пространстве имён модуля - по сравнению с использованием чего-то вродеdocker exec - заключается в том, что у вас есть доступ ко всем командам, доступным на node вместо обычно ограниченного набора команд, установленных в контейнерах.
#

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

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

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

Сначала запуститеip addr в пространстве имен сети модуля, используяnsenter. Обратитесь к предыдущему разделуFinding and Entering Pod Network Namespaces
для получения подробной информации о том, как это сделать:

nsenter -t your-container-pid -n ip addr
Output1: lo:  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:  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 в пространстве имен узла по умолчанию, чтобы вывести его интерфейсы:

ip addr
Output1: lo:  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:  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:  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:  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:

conntrack -L

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

conntrack -E

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

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

sysctl net.netfilter.nf_conntrack_max
Outputnet.netfilter.nf_conntrack_max = 131072

Чтобы установить новое значение, используйте флаг-w:

sysctl -w net.netfilter.nf_conntrack_max=198000

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

/etc/sysctl.conf

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

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

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

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

iptables-save

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

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

iptables -t nat -L KUBE-SERVICES
OutputChain 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. Это описано вthe official Kubernetes documentation.

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

apt install dnsutils

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

kubectl get service -n kube-system kube-dns
OutputNAME       TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)         AGE
kube-dns   ClusterIP   10.32.0.10           53/UDP,53/TCP   15d

IP-адрес кластера выделен выше. Затем мы будем использоватьnsenter для запускаdig в пространстве имен контейнера. Посмотрите разделFinding and Entering Pod Network Namespaces для получения дополнительной информации об этом:

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:

ipvsadm -Ln
OutputIP 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-адрес:

ipvsadm -Ln -t 100.64.0.10:53
OutputProt 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 см. Вour Kubernetes tutorials tag иthe official Kubernetes documentation.

Related