Kubernetes — это система организации контейнеров, способная управлять контейнерными приложениями в кластере серверных узлов. Для обеспечения доступа к сети для всех контейнеров в кластере требуются сложные схемы сетевых подключений. В этой статье мы кратко расскажем о некоторых инструментах и методиках для проверки используемой схемы сетевых подключений.
Эти инструменты могут быть полезны для отладки проблем со связью, расследования проблем с пропускной способностью сети или изучения принципов работы Kubernetes.
Если вы хотите узнать больше о Kubernetes, вам поможет наше руководство «Введение в Kubernetes». Для обзора сетевых возможностей Kubernetes прочитайте статью «Сети в Kubernetes: под капотом».
В этом обучающем модуле предполагается, что у вас имеется кластер Kubernetes с установленным локальным компонентом kubectl
, настроенным для подключения к кластеру.
В следующих разделах содержатся различные команды, которые предполагается выполнять на узлах Kubernetes. Они выглядят примерно так:
- echo 'this is a node command'
Команды для выполнения на локальном компьютере будут выглядеть так:
- echo 'this is a local command'
Примечание. Большнство команд в этом обучающем модуле должно выполняться от имени пользователя root Если вы используете пользователя с привилегиями sudo на узлах Kubernetes, добавьте sudo
для запуска команд, когда это требуется.
Чтобы найти 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
.
С помощью команды kubectl
также можно определить IP-адрес службы. В данном случае мы выводим список всех служб во всех пространствах имен:
- kubectl get service --all-namespaces
OutputNAMESPACE 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 мы можем сделать это с помощью серии из двух команд. Вначала выведите список контейнеров, запущенных на узле:
- 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
. . .
Найдите идентификатор контейнера или имя любого контейнера в поде, который вас интересует. В показанных выше результатах отображается два контейнера:
hello-world
, запущенное в поде hello-world
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
командой, которую вы хотите запустить в сетевом пространстве имен пода.
Примечание. Использование nsenter
для запуска команд в пространстве имен пода дает преимущества по сравнению с такими программами как docker exec
. Это преимущество заключается в том, что у вас имеется доступ ко всем командам, поддерживаемым узлом, а не только к ограниченному набору команд, установленному в контейнерах.
Каждое пространство имен пода взаимодействует с пространством root netns через виртуальный конвейер ethernet. Со стороны узла этот конвейер выглядит как устройство, которое обычно начинается с veth
и заканчивается уникальным идентификатором, например veth77f2275
или veth01
. Внутри пода этот конвейер выглядит как eth0
.
Его можно использовать для корреляции устройств veth
, сопряженных с конкретными подами. Для этого мы выводим список всех сетевых устройств в узле, а затем выводим список устройств в сетевом пространстве имен пода. Для получения связи мы можем провести корреляцию номеров устройств в двух списках.
Запустите команду ip addr
в сетевом пространстве имен пода, используя nsenter
. Более подробную информацию об этом можно найти в предыдущем разделе «Поиск и ввод пространств имен подов»:
- nsenter -t your-container-pid -n ip addr
Output1: 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
в пространстве имен по умолчанию узла для перечисления его интерфейсов:
- ip addr
Output1: 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 к исследуемому нами поду.
До выпуска версии 1.11 в Kubernetes для отслеживания соединений использовались таблицы NAT iptables и модуль ядра conntrack. Для вывода списка всех отслеживаемых соединений используйте команду conntrack
:
- conntrack -L
Чтобы постоянно отслеживать новые соединения, используйте флаг -E
:
- conntrack -E
Чтобы вывести отслеживаемые conntrack соединения на определенный адрес назначения, используйте флаг -d
:
- conntrack -L -d 10.32.0.1
Если у ваших узлов возникают проблемы с установлением надежных соединений со службами, это может означать, что ваша таблица отслеживания подключений полная, и что новые соединения отбрасываются. В этом случае вы можете увидеть в системных журналах сообщения следующего вида:
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
:
. . .
net.ipv4.netfilter.ip_conntrack_max = 198000
До выпуска версии 1.11 в Kubernetes использовались таблицы NAT iptables для преобразования виртуальных 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 кластера заключается в развертывании контейнера отладки с помощью всех необходимых инструментов и использование kubectl
для выполнения команды nslookup
. Это описывается в официальной документации по Kubernetes.
Еще один способ запроса 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 <none> 53/UDP,53/TCP 15d
IP-адрес кластера подсвечен выше. Теперь мы используем nsenter
для запуска dig
в пространстве имен контейнера. Дополнительную информацию об этом можно найти в разделе «Поиск и ввод сетевых пространств имен подов»:
- 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
).
В версии 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 можно найти в наших обучающих модулях по Kubernetes и официальной документации по Kubernetes.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
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!