最近一年对于Kubernetes的开发学习比较少, 主要集中在使用. 涉及到大量集群从mesos到Kubernetes集群的迁移, 迁移结束之后我应该会写一篇博客来进行简单记录. 这篇博客就先来介绍下我是怎么在工作中进行多集群管理的, 以及我开发的gmux是做什么的.

这是软件的实现效果以及仓库

https://github.com/corvofeng/gmux

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
mkdir ~/.tmuxinator

echo '
name: gmux
root: "~/"
windows:
- p1:
- ls
- pwd
- p2:
- pwd
- echo "hello world"
- p3: htop
' > ~/.tmuxinator/gmux.yml

cd /tmp
rm -rfv gmux_linux_amd64.tar.gz
wget https://github.com/corvofeng/gmux/releases/latest/download/gmux_linux_amd64.tar.gz
tar -zxvf gmux_linux_amd64.tar.gz
sudo install -v gmux /usr/local/bin

gmux -p gmux

Kuberentes 多集群管理方案

这是官网介绍的一种方案, 它的基本原理是使用KUBECONFIG中的context进行切换

https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: v1
kind: Config
preferences: {}

clusters:
- cluster:
name: development
- cluster:
name: test

users:
- name: developer
- name: experimenter

contexts:
- context:
name: dev-frontend
- context:
name: dev-storage
- context:
name: exp-test

并且许多工具类似kubecm也是基于此来实现的, 这样会带来几个问题:

  1. 每次增删集群需要维护一个很大的KUBECONFIG文件
  2. 由于使用同一个KUBECONFIG文件, 会被所有终端共享 意味着同一时刻只能操作一个集群

在真正的线上多集群环境管理时, 非常不方便且容易出错. 我接下来介绍一种使用tmux 配置文件分割的方案.

tmux 多会话

tmux 是一款非常强大的终端复用器,它允许您在同一个终端窗口中创建和管理多个会话。这对于管理多个服务器或集群非常有用,因为您可以轻松地在不同的会话之间切换,而无需打开多个终端窗口。

要使用 tmux,您需要先安装它。在大多数 Linux 发行版中,您可以使用以下命令安装 tmux:

1
sudo apt install tmux

安装完成后,您可以使用以下命令启动 tmux:

1
tmux

这将在您的终端窗口中创建一个新的 tmux 会话。您可以使用以下命令在不同的会话之间切换:

1
tmux attach-session -t <session-name>

您还可以使用以下命令创建新的会话:

1
tmux new-session -s <session-name>

tmux -L

简单来说, -L socket-name 参数允许指定 tmux 的 socket 位置, 不同 socket 对应的会话完全隔离.

我们可以在不同的会话中使用不同的环境变量, 以此来达到分离环境的效果

例如, 通过以下两条命令, 你可以创建出完全独立的两个终端, 并且它们的环境变量

1
2
KUBECONFIG=~/.kube/config-aa tmux -L aa
KUBECONFIG=~/.kube/config-bb tmux -L bb

这里的脚本其实已经可以实现多集群管理了, 为什么我们要引入tmuxinator以及我新写的gmux呢?

  1. 线上环境对应的配置需要经过跳板机器, 如何在本地使用 KUBECONFIG(我附在结尾)
  2. 我希望启动的tmux能够直接拥有多个window, 并分别有自己的功能

tmuxinator 使用与局限

https://github.com/tmuxinator/tmuxinator

它是使用ruby写的一款工具, 可以用yaml形式定义tmux终端, 同时也支持模板化, 例如下面的一个模板化的yaml文件

1
2
3
4
5
6
7
8
9
10
name: project
root: ~/<%= @settings["workspace"] %>
# tmuxinator start project workspace=~/workspace/todo

windows:
- small_project:
root: ~/projects/company/small_project
panes:
- start this
- start that

在负责集群环境迁移的几个月中, 我用到最多的一些命令就是:

1
2
3
tmuxinator tpl project=ingame-pre-na
tmuxinator tpl project=ingame-pre-sg
tmuxinator tpl project=ingame-pre-fra

它能帮助我完美的区分不同环境, 并且由于我使用了fzf, 我甚至可以模糊搜索到自己想要打开的环境

image

局限: 由于使用ruby编写, 它需要机器上安装比较新版本的ruby. AWS需要登陆到一个跳板机中进行操作, 但是我们用到机器很旧, 我也不想编译重装一个ruby. 简单读过代码之后, 发现它本身没有用到什么更高级的特性, 使用golang完全重写也非常容易.

gmux实现

这个项目我大量借助了ChatGPT, 主要是一些逻辑编写以及单元测试的编写. 本来我感觉要2-3天的工时, 开发周期缩短到了1天. 最后实现的效果也非常好. 重写之后机会没有任何依赖, 安装很轻量.

项目开源在了这里, 与tmuxinator的配置应该是兼容的, 发现有缺失的功能也欢迎开issue.

https://github.com/corvofeng/gmux

总结

命令行管理几十的集群也是完全行得通的, 而且效果也还不错. 希望也能够提升大家的效率吧.

附: 我的模板配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
name: <%= @settings["project"] %>
root: ~/GitRepo

socket_name: <%= @settings["project"] %>
on_project_start:
# 由于需要跳板机才能连接API, 我这里使用ssh 在本机开了一个socks5的代理, 以下方式为获取一个本地可用的端口, 以及对应的跳板机
- export KUBECONFIG=~/.kube/config-<%= @settings["project"] %>
- export TMUX_SSH_PORT="$(python3 -c 'import socket; s=socket.socket(); s.bind(("", 0)); print(s.getsockname()[1])')"
- export TMUX_SSH_HOST="<%= @settings["host"] %>"
startup_window: kubectl

windows:
- proxy:
layout: main-vertical
panes:
- startup:
- ls -alh
# 修改KUBECONFIG中的context名称, 并增加socks5代理
- yq -i e '.current-context |= "tpl-<%= @settings["project"] %>"' $KUBECONFIG
- yq -i e '.contexts[0].name |= "tpl-<%= @settings["project"] %>"' $KUBECONFIG
- yq -i e ".clusters[0].cluster.proxy-url |=\"socks5://127.0.0.1:$TMUX_SSH_PORT\"" $KUBECONFIG
- ssh -D $TMUX_SSH_PORT $TMUX_SSH_HOST
- kubectl: ls # kubectl get pods

配合修改context的功能, 还能在终端PS1中增加提示, 类似这样

https://github.com/jonmosco/kube-ps1

image