k8s本地开发工具telepresence及部署
背景
k8s内部的pod ip 、svc ip 无法被集群外用户访问,目前内部信息化集群需要通过svc ip访问到应用的swagger页面,解决方案主要有三种,分别为ingress转发、NodePort暴露集群外端口,以及通过本地开发工具telepresence通过apiserver对集群内资源进行访问。前面两种方式需要配置大量规则不利于集群维护,故对本地开发工具telepresence进行调研
telepresence介绍
这种一种更契合远程调试部署在k8s中的业务的方式,它能够在不修改程序代码的情况下,让本地应用程序无感的接入到 Kubernetes
集群中,这样你就可以直接在本地开发调试微服务了
这是一个 Telepresence
工作原理图,它将集群中的数据卷、环境变量、网络都代理到了本地(除了数据卷外,其他两个对应用程序来说都是透明的):
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传
有了这些代理之后:
- 本地的服务就可以完整的访问到远程集群中的其他服务。
- 本地的服务直接访问到 Kubernetes 里的各种资源,包括环境变量、Secrets、Config map 等。
- 甚至集群中的服务还能直接访问到本地暴露出来的接口。
HELM部署Traffic Manager
Traffic Manager用于将集群内流量转发至开启流量拦截功能的客户端
#Start by adding this repo to your Helm client with the following command:
helm repo add datawire https://app.getambassador.io
helm repo update
#If you are installing the Telepresence Traffic Manager for the first time on your cluster, create the telepresence namespace in your cluster
kubectl create namespace ambassador
#Install the Telepresence Traffic Manager with the following command
helm install traffic-manager --namespace ambassador datawire/telepresence
查看Traffic Manager资源部署情况
root@testctyunfzoa-cn-fz1b-k8s-1294192-0001:~/k8sit_kubeconfig/rbac# kubectl -n ambassador get all
NAME READY STATUS RESTARTS AGE
pod/traffic-manager-56489c7cb7-8vtt9 1/1 Running 0 3h58mNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/agent-injector ClusterIP 10.100.236.116 <none> 443/TCP 3h58m
service/traffic-manager ClusterIP None <none> 8081/TCP 3h58mNAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/traffic-manager 1/1 1 1 3h58mNAME DESIRED CURRENT READY AGE
replicaset.apps/traffic-manager-56489c7cb7 1 1 1 3h58m
创建最小权限RBAC
为了允许用户跨所有命名空间进行拦截,但kubectl
权限更有限,以下ServiceAccount
、ClusterRole
和ClusterRoleBinding
将允许完整telepresence intercept
功能
集群范围的telepresence用户访问
---
apiVersion: v1
kind: ServiceAccount
metadata:name: tp-user # Update value for appropriate valuenamespace: ambassador # Traffic-Manager is deployed to Ambassador namespace
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:name: telepresence-role
rules:
# For gather-logs command
- apiGroups: [""]resources: ["pods/log"]verbs: ["get"]
- apiGroups: [""]resources: ["pods"]verbs: ["list"]
# Needed in order to maintain a list of workloads
- apiGroups: ["apps"]resources: ["deployments", "replicasets", "statefulsets"]verbs: ["get", "list", "watch"]
- apiGroups: [""]resources: ["namespaces", "services"]verbs: ["get", "list", "watch"]
- apiGroups: [""]resources: ["pods/portforward"]verbs: ["create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:name: telepresence-rolebinding
subjects:
- name: tp-userkind: ServiceAccountnamespace: ambassador
roleRef:apiGroup: rbac.authorization.k8s.ioname: telepresence-rolekind: ClusterRole
生成用户kubeconfig文件
查看tp-user的token
root@testctyunfzoa-cn-fz1b-k8s-1294192-0001:~/k8sit_kubeconfig/rbac# kubectl -n ambassador describe secrets tp-user-token-72hkg
Name: tp-user-token-72hkg
Namespace: ambassador
Labels: <none>
Annotations: kubernetes.io/service-account.name: tp-userkubernetes.io/service-account.uid: 43bd38a6-c16c-4a98-af71-10c0e4623e2bType: kubernetes.io/service-account-tokenData
====
ca.crt: 1350 bytes
namespace: 10 bytes
token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImprcThENHhZdmZNRkdwUzZFQjMyMUNuQy1hMk5TbFJBem5wZ2JrSzh2SXMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJhbWJhc3NhZG9yIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InRwLXVzZXItdG9rZW4tNzJoa2ciLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoidHAtdXNlciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjQzYmQzOGE2LWMxNmMtNGE5OC1hZjcxLTEwYzBlNDYyM2UyYiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDphbWJhc3NhZG9yOnRwLXVzZXIifQ.JwKYU-MR-173Ks6Fypn_boLsLwvoqajN6ylkGWCG4NEZ-3uhfXIJ849RRC7FFAz442rypLWLFfymBUGPyy6smCouk4cXU471xEew8tba3NtYMAZ2XT-oOw41bUoBBZmVpz38iVDbc58y8yzTgRGXPzHIsmWF-yoXMiYGuAdjBCbtrmoQ36-Nb92Dc0YXIZpsgC1XvzdYL0jQKVvLfi821wYPVVPouDYRDCij8Y5Qcdw6cGBBkheaIuC0O_F5TRLfes_v_eRyoPm5WQAzVsNd5A0YFmqadSgt0L-xWm-f_6npRAKdOWzhM6L2YElI-2B3-6H0q2B160zaP2fAaKAqMw
将token写入kubeconfig文件如下
apiVersion: v1
clusters:
- cluster:certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUR1RENDQXFDZ0F3SUJBZ0lVSVRESUJad1VpQmNyajFyTnNHb3RCQ01ZU05Vd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1lURUxNQWtHQTFVRUJoTUNRMDR4RVRBUEJnTlZCQWdUQ0VoaGJtZGFhRzkxTVFzd0NRWURWUVFIRXdKWQpVekVNTUFvR0ExVUVDaE1EYXpoek1ROHdEUVlEVlFRTEV3WlRlWE4wWlcweEV6QVJCZ05WQkFNVENtdDFZbVZ5CmJtVjBaWE13SUJjTk1qSXdOVEU0TURreU1EQXdXaGdQTWpFeU1qQTBNalF3T1RJd01EQmFNR0V4Q3pBSkJnTlYKQkFZVEFrTk9NUkV3RHdZRFZRUUlFd2hJWVc1bldtaHZkVEVMTUFrR0ExVUVCeE1DV0ZNeEREQUtCZ05WQkFvVApBMnM0Y3pFUE1BMEdBMVVFQ3hNR1UzbHpkR1Z0TVJNd0VRWURWUVFERXdwcmRXSmxjbTVsZEdWek1JSUJJakFOCkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQXdtZFB3dTljMXdjbUJLVzVpWlJUN29XLzlxRm0KL2IyTTVqYzVlOFRPb2hJN1dWWkdnVXFSQkNZcjUxWHVlbXczRDJyVmdNRHY0c2pYTXJjTGRJYmg1LzNNYWM5TQowQU0wbkhRaHg5RVROV2drajZlODMvNTN2NkNYNGNQZjNoWi9zUzgzUnpTOEFyelM0MWI1V2JHME5ybjVpTnNyCk9yOWVZTDR2eDFKbWcyZldFZWVQYTNPVXBML3BBa0JqVXpGZ05zZzZVVDJZRXMzdDgxdHk0RENxS0RWbnVWSzkKekVqUEViS2F5czNIREEvTktybVd0WjdmaVZ4bDJiWCtqYkU2aG1DS0RtQnY1bnRadmNGeFJoUkxsc2U4dE4xSQp2NXcrZnA3SjByNWdXRE5UTnlrNXIrLy91K1U5a280bnE1eHNxVWtvNHJ5b0V0eUZ1NmVJM002QVZRSURBUUFCCm8yWXdaREFPQmdOVkhROEJBZjhFQkFNQ0FRWXdFZ1lEVlIwVEFRSC9CQWd3QmdFQi93SUJBakFkQmdOVkhRNEUKRmdRVVRWQTZqanJaS3BtUmw2ckV1WGZhaEFqQ1RDd3dId1lEVlIwakJCZ3dGb0FVVFZBNmpqclpLcG1SbDZyRQp1WGZhaEFqQ1RDd3dEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBQjR1NldZNENTOFBHeWEzYmlMUkw3THE5OXpxClBXdTFqWGk1QmZLOU8yN0QwZWFFYjBqTDRyWFMxU3g3eHozT1hXZWJrWlVESWdoYXRjOXgrQittM1kyVDFhODgKcDkxalgycE04eG9EcjE1bTgxVlU1MDdYVDNUNnpwUDlJWFJibHhoaUpBeW9TTFcvWVVNc0NYS3F0Vk9iejF5OAo3a3g5T2Ztb2dmTVI3Nlg0RmVZUllRN1pkYmRkOXgvcXVaV0huVElvc0lzaUxZdWNqS1RuQVgvZ2x3Y3NCeFovCmNRajIyM0hLTlFMQnp5TjNqaTR6YkNod1ppdGdKdjFiWXlISFBBN3g2LzF1Ny9aRlJRU3NQYkhHcU93eElzWEUKZ2NSdDFJV3ppWThEaFEvYkFJQ041emdpQ0FlbmRwV2lFblFSa21WSFZSQ2VuRjd3aVBab29aYkwrZ2M9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0Kserver: https://10.230.0.115:6443name: kubernetes
contexts:
- context:cluster: kubernetesuser: tp-username: tp-user
current-context: tp-user
kind: Config
preferences: {}
users:
- name: tp-useruser:token: eyJhbGciOiJSUzI1NiIsImtpZCI6ImprcThENHhZdmZNRkdwUzZFQjMyMUNuQy1hMk5TbFJBem5wZ2JrSzh2SXMifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJhbWJhc3NhZG9yIiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9zZWNyZXQubmFtZSI6InRwLXVzZXItdG9rZW4tNzJoa2ciLCJrdWJlcm5ldGVzLmlvL3NlcnZpY2VhY2NvdW50L3NlcnZpY2UtYWNjb3VudC5uYW1lIjoidHAtdXNlciIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjQzYmQzOGE2LWMxNmMtNGE5OC1hZjcxLTEwYzBlNDYyM2UyYiIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDphbWJhc3NhZG9yOnRwLXVzZXIifQ.JwKYU-MR-173Ks6Fypn_boLsLwvoqajN6ylkGWCG4NEZ-3uhfXIJ849RRC7FFAz442rypLWLFfymBUGPyy6smCouk4cXU471xEew8tba3NtYMAZ2XT-oOw41bUoBBZmVpz38iVDbc58y8yzTgRGXPzHIsmWF-yoXMiYGuAdjBCbtrmoQ36-Nb92Dc0YXIZpsgC1XvzdYL0jQKVvLfi821wYPVVPouDYRDCij8Y5Qcdw6cGBBkheaIuC0O_F5TRLfes_v_eRyoPm5WQAzVsNd5A0YFmqadSgt0L-xWm-f_6npRAKdOWzhM6L2YElI-2B3-6H0q2B160zaP2fAaKAqMw
客户端安装Telepresence
# 安装kubectl
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl"
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/darwin/arm64/kubectl.sha256"
echo "$(cat kubectl.sha256) kubectl" | shasum -a 256 --check
#验证通过时,输出如下:
#kubectl: OK
chmod +x ./kubectl
sudo mv ./kubectl /usr/local/bin/kubectl
sudo chown root: /usr/local/bin/kubectl# 手动安装telepresence:
sudo curl -fL https://app.getambassador.io/download/tel2/darwin/arm64/latest/telepresence -o /usr/local/bin/telepresencesudo chmod a+x /usr/local/bin/telepresence
启动Telepresence代理
使用 Telepresence,您可以创建全局拦截,拦截流向集群中服务的所有流量,并将其路由到本地环境
telepresence connect
访问集群内应用测试
(base) ➜ ~ curl -ik https://kubernetes.default
HTTP/2 401
cache-control: no-cache, private
content-type: application/json
content-length: 165
date: Thu, 14 Jul 2022 09:50:55 GMT{"kind": "Status","apiVersion": "v1","metadata": {},"status": "Failure","message": "Unauthorized","reason": "Unauthorized","code": 401
}%
现在可以使用任何本地工具连接到集群中的任何服务
使用场景
假设我们有两个服务 A 和 B,服务 A 是依赖于服务 B 的。下面分两个场景来看看如何用 Telepresence 来调试 A 和 B。
调试服务 A
服务 A 在本地运行,服务 B 运行在远端集群中。借助 Telepresence
搭建的代理,A 就能直接访问到 B。比方说我们的服务 B 是这样一个程序,它监听在 8000 端口上。每当有人访问时它就返回 Hello, world!
$ kubectl run service-b --image=datawire/hello-world --port=8000 --expose
$ kubectl get service service-b
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service-b 10.0.0.12 <none> 8000/TCP 1m
现在在本地用默认参数启动 Telepresence
,等它连接好集群:
$ telepresence
T: Starting proxy with method 'vpn-tcp', which has the following limitations: All processes are affected, only one telepresence can run per machine, and you
T: can't use other VPNs. You may need to add cloud hosts and headless services with --also-proxy. For a full list of method limitations see
T: https://telepresence.io/reference/methods.html
T: Volumes are rooted at $TELEPRESENCE_ROOT. See https://telepresence.io/howto/volumes.html for details.
T: Starting network proxy to cluster using new Deployment telepresence-1566230249-7112632-14485T: No traffic is being forwarded from the remote Deployment to your local machine. You can use the --expose option to specify which ports you want to
T: forward.T: Setup complete. Launching your command.
@test_cluster|bash-4.2#
这时候就可以开始调试服务 A 了,因为服务 B 暴露出来的接口本地已经可以直接访问到:
$ curl http://service-b:8000/
Hello, world!
这里要说明一下这背后发生的事情:
- 当运行
Telepresence
命令的时候,它创建了一个Deployment
,这个Deployment
又创建了一个用来做代理的Pod
,我们可以这样查看到它kubectl get pod -l telepresence
- 同时它还在本地创建了一个全局的
VPN
,使得本地的所有程序都可以访问到集群中的服务。Telepresence
其实还支持其他的网络代理模式(使用--method
切换),vpn-tcp
是默认的方式,其他的好像用处不大,inject-tcp
甚至要在后续的版本中取消掉。 - 当本地的
curl
访问http://service-b:8000/
时,对应的DNS
查询和HTTP
请求都被VPN
路由到集群中刚刚创建的Pod
去处理。
除此之外 Telepresence
还将远端的文件系统通过 sshfs
挂载到本地 $TELEPRESENCE_ROOT
下面(你也可以用参数 --mount <MOUNT_PATH>
指定挂载的路径)。这样,我们的应用程序就可以在本地访问到远程的文件系统:
$ ls $TELEPRESENCE_ROOT/var/run/secrets/kubernetes.io/serviceaccount
ca.crt namespace token
如果我们退出 Telepresence
对应的 Shell,它也会做一些清理工作,比如取消本地 VPN
、删除刚刚创建的Deployment
等
调试服务 B
服务 B 与刚才的不同之处在于,它是被别人访问的,要调试它,首先得要有真实的访问流量。我们如何才能做到将别人对它的访问路由到本地来,从而实现在本地捕捉到集群中的流量呢?
Telepresence 提供这样一个参数,--swap-deployment <DEPLOYMENT_NAME[:CONTAINER]>
,用来将集群中的一个 Deployment
替换为本地的服务。对于上面的 service-b
,我们可以这样替换:
$ telepresence --swap-deployment service-b --expose 8000:8000
这个时候集群中的服务 A 再想访问服务 B 的 8000 端口时,Telepresence
就会将这个请求转发到本地的 8000 端口。它的工作原理就是将集群中的 service-b
替换为 Telepresence
创建的 Proxy ,然后这个 Proxy 再将请求转发到本地客户端。
即,将原始的网络:
替换为这个结构:
这样我们就有机会在本地查看具体的请求数据,调试逻辑,以及生成新的回复。
参考资料
官网:https://www.telepresence.io/docs/latest/install/
kubectl安装:https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-macos/
k8s本地开发工具telepresence及部署相关推荐
- k8s本地联调工具kt-connect
1.Kt Connect简介 KT Connect ( Kubernetes Developer Tool ) 是轻量级的面向 Kubernetes 用户的开发测试环境治理辅助工具.其核心是通过建立本 ...
- SpringBoot官方开发工具,热部署和远程调试真带劲
平时使用SpringBoot开发应用时,修改代码后需要重新启动才能生效.如果你的应用足够大的话,启动可能需要好几分钟.有没有什么办法可以加速启动过程,让我们开发应用代码更高效呢?今天给大家推荐一款Sp ...
- Mac下的Docker及Kubernetes(k8s)本地环境搭建与应用部署、管理界面kubernetes-dashboard
Mac下的Docker及Kubernetes环境搭建与应用部署 Mac安装docker: brew cask install docker 当然也可以直接去官网下载docker的pkg文件安装 Mac ...
- 开发工具|H5微应用本地开发新姿势
你在本地开发H5微应用时也遇到了这些问题?: 1. 不知道如何调试 2. 不知道如何将本地的页面在钉钉客户端内打开来调试JSAPI 3. 不知道该使用什么ui组件 4. 调用JSAPI前要鉴权,很麻烦 ...
- 【链块技术36期】智能合约基础语言(一)——Solidity概述和开发工具的使用
原文链接:区块链技术语言:Solidity(一):概述和开发工具的使用 一.目录 ☛Solidity的概述 ☛Solidity开发工具remix的使用 ☛Solidity本地开发工具remix安装 二 ...
- 新时代程序员主流开发工具一览
分享一些优秀的写代码工具和使用感受 大家好,我是鱼皮. 俗话说的好:工欲善其事,必先利其器.一款好的开发工具对程序员来说是至关重要的,可以降低开发成本.提高开发的效率和代码质量. 所以今天分享一些主流 ...
- 编程开发工具一览:新手到大神,程序员都用什么写代码?
俗话说的好:工欲善其事,必先利其器.一款好的开发工具对程序员来说是至关重要的,可以降低开发成本.提高开发的效率和代码质量. 所以今天分享一些主流的编程开发工具,基本都是我曾经或正在使用的,附带一些使用 ...
- PHP环境搭建(phpStudy)与集成开发工具(phpStorm)的安装
写作时间:2018.04.09 凌晨 介绍:PHP(外文名:PHP: Hypertext Preprocessor,中文名:"超文本预处理器")是一种通用开源脚本语言.语法吸收 ...
- Draft-微软出品的云原生下的本地开发辅助工具
一.介绍 Draft是微软Deis团队开源的一个用Go语言编写的容器应用开发辅助工具,用于帮助开发人员简化容器应用程序构建和部署的开发流程.Draft的设计思路在于,允许开发人员在不了Docker和K ...
最新文章
- 月薪8k和月薪38K的程序员差距在哪里?
- 差动机器人毕业设计_双轮差动机器人曲线算法设计与实现
- c/c++ 结构体前加不加typedef有什么区别?
- HDU - 4821 String(字符串哈希+优化)
- python spark进行大数据分析_第2天Python实战Spark大数据分析及调度-RDD编程
- 证明Ax=0的最小二乘解是ATA的最小特征值对应的特征向量(||x||=1)
- 自由动力论坛一枝花,全靠汇道童鞋来当家
- [leetcode]326. Power of Three(c语言)
- 卡车紧急刹车加强系统(发明畅想)
- Android Thread/Runnable/Handler用法
- 边看边练之Django(二)---- Django的URL设置
- 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第2节 线程实现方式_14_匿名内部类方式实现线程的创建...
- sql未保存文档找回
- html5取消backspace后退功能,JS禁止后退键(Backspace)详解
- 奇舞团- 招高级iOS开发工程师
- 信号完整性(SI)概述
- 计算机专业高数学科难度,大学里极其有难度的4个专业,挂科率很高,不是学霸学不明白...
- lenb和len的区别
- HTML和CSS实现京东首页(附GitHub地址)
- Vulnhub-Moneybox
热门文章
- 七、ES对象(二) -- 正则表达式
- h5 canvas html 合成,图片合成以及canvas的应用
- 如何使用Domino实用程序(Updall, Compact, Fixup) 进行维护
- 高校校园跑腿系统的设计app-计算机毕业设计
- TypeError: only size-1 arrays can be converted to Python scalars
- 齿轮与减速器输出端连接方式
- 稀疏索引、密集索引、聚簇索引、非聚簇索引
- java Char与char_JAVAc++中char和char[]的区别
- mysql查询本用户的表的列名等信息_mysql常用命令查询手册
- MAPJOIN来解决实际的问题