1. Tunnel-Agent简介
tunnel-agent是通过daemonset部署在每个worker节点,通过grpc协议与云端的tunnel-server建立连接。以下分析tunnel-agent的源码逻辑。
常用的启动参数:
1 | - args: |
2. NewYurttunnelAgentCommand
NewYurttunnelAgentCommand还是常用命令代码三板斧,此处不做展开,直接分析Run函数。
1 | // NewYurttunnelAgentCommand creates a new yurttunnel-agent command |
3. Run
Run函数即启动一个agent服务,主要包含以下几个步骤:
-
先获取配置项tunnelserver-addr中的地址,如果地址不存在,则获取x-tunnel-server-svc的service 地址。(说明:一般情况下,tunnel-server跟agent不在同一个网络域,因此网络会不通,所以一般需要配置独立且可连通的地址,可以通过Nginx转发)
-
agent通过host的网络模式运行在宿主机上,启动证书manager。并等待证书生成。
-
生成连接tunnel-server的证书。
-
启动 yurttunnel-agent。
-
启动meta server。
1 | // Run starts the yurttunel-agent |
4. TunnelAgent
TunnelAgent与tunnel-server建立tunnel,接收server的请求,并转发给kubelet。
1 | // TunnelAgent sets up tunnel to TunnelServer, receive requests |
5. anpTunnelAgent.Run
anpTunnelAgent使用apiserver-network-proxy包来实现tunnel逻辑。项目具体参考:https://github.com/kubernetes-sigs/apiserver-network-proxy)
1 | // RunAgent runs the yurttunnel-agent which will try to connect yurttunnel-server |
以下是apiserver-network-proxy的源码分析。
6. apiserver-network-proxy.Client分析
具体代码参考:
通过NewAgentClientSet
创建一个client结构体。
1 | func (cc *ClientSetConfig) NewAgentClientSet(stopCh <-chan struct{}) *ClientSet { |
6.1. client.Serve
client.Serve运行一个sync的goroutine的常驻进程,再调用syncOnce函数。
1 | // 运行一个sync的goroutine |
syncOnce
运行了真正执行grpc通信的client。
1 | func (cs *ClientSet) syncOnce() error { |
7. Grpc client
代码参考:
7.1. newAgentClient
newAgentClient
初始化一个grpc client,并启动连接。
1 | func newAgentClient(address, agentID, agentIdentifiers string, cs *ClientSet, opts ...grpc.DialOption) (*Client, int, error) { |
7.2. connect
Connect使grpc连接代理服务器。它返回服务器ID
1 | // Connect makes the grpc dial to the proxy server. It returns the serverID |
7.3. Serve()
Serve
主要启动grpc双向传输通道的goroutine, 主要包括 send(发)和recv(收)2个操作。
1 | func (a *Client) Serve() { |
8. remoteToProxy和proxyToRemote
remoteToProxy
1 | func (a *Client) remoteToProxy(connID int64, ctx *connContext) { |
proxyToRemote
1 | func (a *Client) proxyToRemote(connID int64, ctx *connContext) { |
9. Recv() 和Send()
1 | func (a *Client) Send(pkt *client.Packet) error { |
10. 总结
Tunnel-agent本质是封装了apiserver-network-proxy
库,最终运行一个grpc的双向收发数据包的通道,所以**本质上tunnel是通过grpc反向建立连接,并实现双向通信的能力。**因此该反向隧道能力的也可以通过其他双向通信的协议来实现,例如websocket(类似kubeedge通过websocket来实现反向隧道)。
参考:
赞赏一下