Կ 如何打开一个隧道到 Kubernetes pod 或容器通过 tcpserver 和 netcat

Համար. թարգմանություն.: Այս գործնական заметка LayerCI-ի հիմնադրից գերազանցում է Kubernetes-ի (և ոչ միայն) համար նախատեսված տիպի և հնարքների հասկացությունն։ Այստեղ առաջարկված լուծումը միայն մեկերից մեկն է և, հավանաբար, ոչ ամենաբարդը (որոշ դեպքերում արդեն նշված «օգտագործելու» մոտեցումը K8s-ի համար կարող է համապատասխանել) kubectl port-forward). Սակայն, այն թույլ է տալիս գոնե տեսնել խնդիրը դասական գործիքների կիրառման տեսանկյունից և դրանց հետագա համադրումը՝ միաժամանակ պարզ, ճկուն և հզոր (տեսեք «այլ գաղափարներ» վերջում՝ ներշնչման համար):

Կ 如何打开一个隧道到 Kubernetes pod 或容器通过 tcpserver 和 netcat

Imagine a typical situation: you want a port on your local computer to magically redirect traffic to a pod/container (or vice versa).

Possible usage scenarios

  1. Check what the HTTP endpoint returns /healthz pod-in production cluster.
  2. Connect a TCP debugger to the pod on your local machine.
  3. Access the production database from local database tools without the need to deal with authentication (usually localhost has root privileges).
  4. Run a one-time migration script for data in the staging cluster without the need to create a container for it.
  5. Connect a VNC session to the pod with a virtual desktop running (see XVFB).

A few words about the necessary tools

Tcpserver — Open Source utility available in most Linux package repositories. It allows you to open a local port and redirect traffic received through stdin/stdout from any specified command:

colin@colin-work:~$ tcpserver 127.0.0.1 8080 echo -e 'HTTP/1.0 200 OK
Content-Length: 19<body>բարև!</body>'&amp;
[1] 17377
colin@colin-work:~$ curl localhost:8080
<body>բարև!</body>colin@colin-work:~$

(asciinema.org)

Netcat does the opposite. It allows you to connect to an open port and pass the input/output received from it to 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:~$

(asciinema.org)

In the example above, netcat requests a page via HTTP. The flag -C causes it to add CRLF at the end of the line.

Combining with kubectl: listen on the host and connect to the pod

If you combine the tools presented above with kubectl, we get a command like this:

tcpserver 127.0.0.1 8000 kubectl exec -i web-pod nc 127.0.0.1 8080

Similarly, to access port 80 inside the pod, it will be enough to do 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

(asciinema.org)

Կ 如何打开一个隧道到 Kubernetes pod 或容器通过 tcpserver 和 netcat
Interaction scheme of utilities

In the opposite direction: listen in the pod and connect to the host

nc 127.0.0.1 8000 | kubectl exec -i web-pod tcpserver 127.0.0.1 8080 cat

Այս հրամանը պոդին թույլ է տալիս մուտք գործել 8000 պորտին տեղական մեքենայում:

Bash-ի համար սցենար

Ես գրել եմ հատուկ Bash սցենար, որը թույլ է տալիս կառավարել Kubernetes պրոդակցիոն կլաստերը: LayerCI, օգտագործելով վերոհիշյալ մեթոդը:

kubetunnel() {
    POD="$1"
    DESTPORT="$2"
    if [ -z "$POD" -o -z "$DESTPORT" ]; then
        echo "Օգտագործումը: kubetunnel [պոդի անուն] [պար destination]"
        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, հեշտությամբ կարող ենք բացել տունելը պոդի հրամանի միջոցով 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 ֆայլի միջոցով kubeconfig:

    tcpserver ssh workcomputer "kubectl exec -i my-pod nc 127.0.0.1 80"

  • Երկու պոդաձևերի միացման համար կարելի է օգտագործել mkfifo և գործարկել երկու առանձին հրամաններ kubectl.

Հնարավորությունները անսահման են!

P.S. թարգմանչից

Նաեւ կարդացեք մեր բլոգում:

Ընտանիք: habr.com

Գնել հուսալի հյուրընկալում DDoS պաշտպանությամբ, VPS VDS սերվերներով 🔥 Գնել հուսալի հյուրընկալում DDoS պաշտպանությամբ, VPS VDS սերվերներով | ProHoster