Представьте типичную ситуацию: вы хотите, чтобы порт на локальном компьютере волшебным образом перенаправлял трафик в pod/контейнер (или наоборот).
Возможные сценарии использования
- Проверить, что возвращает HTTP endpoint
/healthz
pod’а в production-кластере. - Подключить TCP-отладчик к pod’у на локальной машине.
- Получить доступ к production-базе из локальных инструментов для работы с БД без необходимости возиться с аутентификацией (обычно у localhost’а есть права root’а).
- Запустить одноразовый скрипт миграции для данных в staging-кластере без необходимости создавать для него контейнер.
- Подключить сессию VNC к pod’у с запущенным виртуальным рабочим столом (см. XVFB).
Несколько слов о необходимых инструментах
Tcpserver — Open Source-утилита, доступная в большинстве репозиториев пакетов Linux. Она позволяет открыть локальный порт и перенаправить на него трафик, получаемый через stdin/stdout от любой указанной команды:
colin@colin-work:~$ tcpserver 127.0.0.1 8080 echo -e 'HTTP/1.0 200 OK\r\nContent-Length: 19\r\n\r\n<body>hello!</body>'& [1] 17377 colin@colin-work:~$ curl localhost:8080 <body>hello!</body>colin@colin-work:~$
Netcat делает обратное. Она позволяет подключиться к открытому порту и передать полученный от него ввод/вывод на stdin/stdout:
colin@colin-work:~$ nc -C httpstat.us 80 GET /200 HTTP/1.0 Host: httpstat.us HTTP/1.1 200 OK Cache-Control: private Server: Microsoft-IIS/10.0 X-AspNetMvc-Version: 5.1 Access-Control-Allow-Origin: * X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Set-Cookie: ARRAffinity=93fdbab9d364704de8ef77182b4d13811344b7dd1ec45d3a9682bbd6fa154ead;Path=/;HttpOnly;Domain=httpstat.us Date: Fri, 01 Nov 2019 17:53:04 GMT Connection: close Content-Length: 0 ^C colin@colin-work:~$
В приведенном выше примере netcat запрашивает страницу по HTTP. Флаг -C
заставляет его добавлять CRLF в конец строки.
Связка с kubectl: слушайте на хосте и подключайтесь к pod’у
Если объединить представленные выше инструменты с kubectl, мы получим команду вроде этой:
tcpserver 127.0.0.1 8000 kubectl exec -i web-pod nc 127.0.0.1 8080
По аналогии, для доступа к порту 80 внутри pod’а достаточно будет сделать curl "127.0.0.1:80"
:
colin@colin-work:~$ sanic kubectl exec -it web-54dfb667b6-28n85 bash root@web-54dfb667b6-28n85:/web# apt-get -y install netcat-openbsd Reading package lists... Done Building dependency tree Reading state information... Done netcat-openbsd is already the newest version (1.195-2). 0 upgraded, 0 newly installed, 0 to remove and 10 not upgraded. root@web-54dfb667b6-28n85:/web# exit colin@colin-work:~$ tcpserver 127.0.0.1 8000 sanic kubectl exec -i web-54dfb667b6-28n85 nc 127.0.0.1 8080& [1] 3232 colin@colin-work:~$ curl localhost:8000/healthz {"status":"ok"}colin@colin-work:~$ exit
Схема взаимодействия утилит
В обратную сторону: слушайте в pod’е и подключайтесь к хосту
nc 127.0.0.1 8000 | kubectl exec -i web-pod tcpserver 127.0.0.1 8080 cat
Эта команда позволяет pod’у получить доступ к порту 8000 на локальной машине.
Скрипт для Bash
Я написал специальный скрипт для Bash, позволяющий управлять production-кластером Kubernetes LayerCI, используя описанный выше метод:
kubetunnel() { POD="$1" DESTPORT="$2" if [ -z "$POD" -o -z "$DESTPORT" ]; then echo "Usage: kubetunnel [pod name] [destination port]" return 1 fi pkill -f 'tcpserver 127.0.0.1 6666' tcpserver 127.0.0.1 6666 kubectl exec -i "$POD" nc 127.0.0.1 "$DESTPORT"& echo "Connect to 127.0.0.1:6666 to access $POD:$DESTPORT" }
Если добавить эту функцию в ~/.bashrc
, можно легко открывать туннель в pod командой kubetunnel web-pod 8080
и делать curl localhost:6666
.
- Для туннеля в Docker можно заменить основную строку на:
tcpserver 127.0.0.1 6666 docker exec -i "$CONTAINER" nc 127.0.0.1 "$DESTPORT"
- для туннеля в K3s — поменяйте её на:
tcpserver 127.0.0.1 6666 k3s kubectl exec …
- и т.д.
Другие идеи
- Перенаправить UDP-трафик можно командами
netcat -l -u -c
вместоtcpserver
иnetcat -u
вместоnetcat
соответственно. - Посмотреть ввод/вывод через pipe viewer:
nc 127.0.0.1 8000 | pv --progress | kubectl exec -i web-pod tcpserver 127.0.0.1 8080 cat
. - Можно сжимать и распаковывать трафик на обоих концах с помощью
gzip
. - Подключиться по SSH к другому компьютеру с соответствующим файлом
kubeconfig
:cpserver ssh workcomputer "kubectl exec -i my-pod nc 127.0.0.1 80"
. - Можно соединить два pod’а в разных кластерах с помощью
mkfifo
и запустить две отдельные командыkubectl
.
Возможности безграничны!
P.S. от переводчика
Читайте также в нашем блоге:
ссылка на оригинал статьи https://habr.com/ru/company/flant/blog/479910/
Добавить комментарий