Telepresence - 在本地端與 Kubernetes 的其他服務溝通及快速開發

Telepresence 透過 sshuttle 使用 SSH connection 產生 VPN-like tunnel,建立一個雙向的 network proxy。(more details),甚至可以在 service 前面加一層 ingress, cert-manager 進而產生一個 Local HTTPS 的開發環境。

此外,CNCF 基金會 目前已經將 Telepresence 加入計畫,可以對這個工具多一點的信心。

解決問題

  • 如果 cluster 的 micro service 很多,不可能在本地端用 minikube 測試。
  • 不需要等待 CI/CD 將程式碼推到 Cluster 才能看到結果
  • 不需要額外設定 VPN(OpenVPN, Wireguard),存取 Cluster 其他 Service
  • 可以在程式內直接使用 Kubernetes Cluster 的 Service
    • ex. requests.get(‘client.elasticsearch:9200’)

先看結果

Step by Step

Code: https://github.com/RammusXu/toolkit/tree/master/k8s/telepresence

Install

brew cask install osxfuse
brew install datawire/blackbird/telepresence

先準備一個 telepresence 的 proxy pod(deployment+service)

kind: Service
apiVersion: v1
metadata:
name: telepresence-rammus
spec:
selector:
owner: rammus
type: LoadBalancer
ports:
- name: http
port: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: telepresence-rammus
spec:
replicas: 1
selector:
matchLabels:
owner: rammus
template:
metadata:
labels:
owner: rammus
spec:
containers:
- name: telepresence
image: datawire/telepresence-k8s-priv:0.99
ports:
- name: http
containerPort: 80

以及一個簡單的 Flask

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
return 'Hello, Rammus Xu!'

Run

kubectl apply -f telepresence.yaml
sudo telepresence --deployment telepresence-rammus --expose 5000:80 --namespace dev --run sh -c "FLASK_DEBUG=1 flask run"

--deployment [deployment-name] 將會置換掉 deployment
--expose 5000:80 將 localhost:5000 expose 到 kubernetes-pod:80
--namespace [your-namespace] 可以選擇要替換哪個 namespace 的 deployment。預設是 default
--run 啟用 server 的方式。ex. npm start, flask run, rails server。這邊帶入 FLASK_DEBUG=1 自動監控 app.py 程式碼變更時重啟 server,如果是別的語言,請自行替換,或是加入環境變數。

Advanced

其他選擇

Reference

Troubleshooting

sshd: no hostkeys available – exiting.

https://github.com/telepresenceio/telepresence/issues/1013#issuecomment-495949902
However, running telepresence –expose 80 fixes things for me by forcing usage of the datawire/telepresence-k8s-priv image as opposed to the datawire/telepresence-k8s image as mentioned above.