Прим. прев.: Това практическо бележка от създателя на LayerCI — отлична илюстрация на така наречените съвети и трикове за Kubernetes (и не само). Предложеното тук решение е само едно от малкото, и вероятно не е най-очевидното (за някои случаи може да подхожда вече споменатият в коментарите „роден“ за K8s. ). Все пак, то позволява поне да погледнем на проблема от позицията на прилагането на класически инструменти и тяхната последваща комбинация — едновременно просто, гъвкаво и мощно (вижте „други идеи“ в края за вдъхновение).

Представете си типична ситуация: искате портът на локалния компютър магически да пренасочи трафика към pod/контейнер (или обратно).
Възможни сценарии на употреба
- Проверете какво връща HTTP endpoint
/healthzpod-а в продукционен кластер. - Свържете TCP отладчик към pod-а на локалната машина.
- Достъп до продукционната база от локалните инструменти за работа с БД без необходимост от мъчи с аутентификация (обикновено локалният хост има права на root).
- Стартирайте еднократен скрипт за миграция на данни в staging клъстер без необходимост от създаване на контейнер за него.
- Свържете VNC сесия към pod-а с активен виртуален работен плот (вижте XVFB).
Няколко думи за необходимите инструменти
— Open Source инструмент, достъпен в повечето репозитории на Linux. Позволява да отворите локален порт и да пренасочите трафика, получен чрез stdin/stdout от всяка посочена команда:
colin@colin-work:~$ tcpserver 127.0.0.1 8080 echo -e 'HTTP/1.0 200 OKrnContent-Length: 19rnrn<body>здравей!</body>'&
[1] 17377
colin@colin-work:~$ curl localhost:8080
<body>здравей!</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 , используя описанный выше метод:
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:tcpserver ssh workcomputer "kubectl exec -i my-pod nc 127.0.0.1 80" - Можно соединить два pod'а в разных кластерах с помощью
mkfifoи запустить две отдельные командыkubectl.
Возможности безграничны!
P.S. от преводача
Прочетете също в нашия блог:
- «»;
- «»;
- «»;
- «».
Източник: habr.com
