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

Представете си типична ситуация: искате порт на локалния компютър магически да пренасочва трафик към pod/контейнер (или обратно).
Възможни сценарии на употреба
- Проверете какво връща HTTP endpoinт.
/healthzpod'а в production-кластера. - Свържете TCP-дебъгер към pod'а на локалната машина.
- Получете достъп до production-базата от локални инструменти за работа с БД без необходимост да се занимавате с аутентификация (обикновено localhost има 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, който управлява производствения клъстер Kubernetes , използвайки описания по-горе метод:
kubetunnel() {
POD="$1"
DESTPORT="$2"
if [ -z "$POD" -o -z "$DESTPORT" ]; then
echo "Използване: kubetunnel [име на pod] [порта на дестинацията]"
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 "Свържете се с 127.0.0.1:6666 за достъп до $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
