k3s 一键脚本集群部署,懒人福音,国内友好

背景

起因

我是一名正在搞serverless相关内容的研究生,大类是云计算、分布式。这类论文大概可以分成两类,一类是使用仿真脚本模拟集群,实现优化算法;另一类是基于真实平台部署。我的第一个工作是实现了一个serverless仿真平台 https://github.com/340Lab/serverless_sim,并基于它做扩缩容和调度策略的研究,但在投论文时遭遇了针对仿真的可靠性的质疑。相比之下,真实平台有更多的dirty work和对不同影响因素的tradeoff,工作量更大,含金量也更高。因此想试一试做更实在的工作,进行真实框架的优化研究。 由于当前大部分开源serverless框架都需要k8s,因此需要在实验室里搭起一片小集群,装上k8s。小集群是用实验室角落里积灰的pc机组的。大概是下面这个粗糙的样子:

k3s 一键脚本集群部署,懒人福音,国内友好_第1张图片

添加图片注释,不超过 140 字(可选)

k8s

k8s就不多赘述了,前身是borg,也是现在云原生核心基建。在此之前我只尝试过单机k8s kind以及使用GitHub - KubeOperator/KubeOperator: KubeOperator 是一个开源的轻量级 Kubernetes 发行版,专注于帮助企业规划、部署和运营生产级别的 K8s 集群。部署k8s。kind这种单机只能做做完整性测试,性能测试是没法用的。kubeoperator是用的ansible,相较于手动部署成功率高一些,但是还是偶尔会出问题,同时部署端无法成为集群一员。因此这次将实现看向了k3s,之前也有所耳闻,具体去了解后发现他确实很轻量。每个节点只要有一个基本agent就行,agent管控每一个节点的基本配置,安装也是一键脚本。再也不用装这装那,配这配那了。

k3s集群部署

最后的完整方案脚本:paTools/k3s at main · ActivePeter/paTools · GitHub,修改config.yml配置好集群ip,按顺序执行脚本即可。

可选方案

  • autok3s
  • k3sup
  • 手动

首先我试了autok3s图形界面设置,发现不行。然后我试了k3sup,发现对部署节点具有访问外网的要求,一时没找到代理方法。最后直接去看k3s文档了,发现k3s有一个离线部署方案,也就是只要把bin,镜像下载好,传到每一个节点上,执行下安装,就完事了。离线安装 | Rancher文档 让我们来把这个过程自动化一点吧

1.准备bin和镜像

跟着教程来就行,对应到我的脚本的 1.prepare_local.py 准备k3s安装相关资源,此处如果网不好可以先export一下代理HTTP_PROXYHTTPS_PROXY。最终我们准备好k8sk3s-airgap-images-amd64.tar.gz 和 install.sh

2.编写本地安装脚本

为了实现把必要文件上传到对应节点执行就能达到安装的效果,我对安装脚本进行了封装。首先我们将必要的安装文件传输到了/tmp/k3s中,安装脚本负责做的事情是1将其复制到真正需要的位置,2配置好安装环境变量,3执行安装脚本。install_server.py 中心节点安装,k3s叫server

# prepare env
os_system_sure("cp /tmp/k3s/k3s /usr/local/bin/k3s")
os_system_sure("chmod +x /usr/local/bin/k3s")
os_system_sure("mkdir -p /var/lib/rancher/k3s/agent/images/")
os_system_sure("cp /tmp/k3s/k3s-airgap-images-amd64.tar.gz /var/lib/rancher/k3s/agent/images/")

# install
os.chdir("/tmp/k3s")
os.environ['INSTALL_K3S_SKIP_DOWNLOAD']="true"
os_system_sure("bash ./install.sh")

install_worker.py k3s叫agent,更复杂一点,因为传入k3s_token和server_ip 这两个都是动态的,根据具体的配置有差异,因此我先准备了一个install_woker_tmp.py,对应变量留空,后续替换实际内容

K3S_TOKEN=
SERVER_IP=

# prepare env
os_system_sure("cp /tmp/k3s/k3s /usr/local/bin/k3s")
os_system_sure("chmod +x /usr/local/bin/k3s")
os_system_sure("mkdir -p /var/lib/rancher/k3s/agent/images/")
os_system_sure("cp /tmp/k3s/k3s-airgap-images-amd64.tar.gz /var/lib/rancher/k3s/agent/images/")

# install
os.chdir("/tmp/k3s")
os.environ['INSTALL_K3S_SKIP_DOWNLOAD']="true"
# K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken
os.environ['K3S_URL']=f"https://{SERVER_IP}:6443"
os.environ['K3S_TOKEN']=f"{K3S_TOKEN}"

os_system_sure("bash ./install.sh")

3.上传节点并远程安装

首先我定义了一个config.yml,表示集群成员,is_master 标注是中心节点

lab1:
  ip: 192.168.31.162
  is_master:
lab2:
  ip: 192.168.31.87
lab7:
  ip: 192.168.31.89

....

后续远程指令以及上传文件要让节点间能够不使用密码互信才方便,对应0.ssh_direct.py,就是ssh-keygen生成密钥,ssh-copy-id拷贝到远程,只需要输入一次密码即可。

然后首先安装server,对应2.up_master.py,把必要的文件传到tmp,然后执行安装脚本即可

# prepare remote
os_system_sure(f"ssh root@{master_ip} 'mkdir -p /tmp/k3s'")
os_system_sure(f"scp k3s root@{master_ip}:/tmp/k3s/k3s")
os_system_sure(f"scp k3s-airgap-images-amd64.tar.gz root@{master_ip}:/tmp/k3s/k3s-airgap-images-amd64.tar.gz")
os_system_sure(f"scp install.sh root@{master_ip}:/tmp/k3s/install.sh")
os_system_sure(f"scp install_server.py root@{master_ip}:/tmp/k3s/install_server.py")
os_system_sure(f"ssh root@{master_ip} 'ls /tmp/k3s/'")

# remote run
os_system_sure(f"ssh root@{master_ip} 'python3 /tmp/k3s/install_server.py'")

然后安装每一个agent,对应3.up_worker.py,这里首先要获取一下k3s token,替换一下tmp中对应的环境变量, 然后和master一样,上传必要的文件,执行安装脚本

for node, conf in config_data.items():
    if 'is_master' in conf:
        continue

    ip=conf['ip']
    # prepare remote
    os_system_sure(f"ssh root@{ip} 'mkdir -p /tmp/k3s'")
    os_system_sure(f"scp k3s root@{ip}:/tmp/k3s/k3s")
    os_system_sure(f"scp k3s-airgap-images-amd64.tar.gz root@{ip}:/tmp/k3s/k3s-airgap-images-amd64.tar.gz")
    os_system_sure(f"scp install.sh root@{ip}:/tmp/k3s/install.sh")
    os_system_sure(f"scp install_worker.py root@{ip}:/tmp/k3s/install_worker.py")
    os_system_sure(f"ssh root@{ip} 'ls /tmp/k3s/'")

    # remote run
    os_system_sure(f"ssh root@{ip} 'python3 /tmp/k3s/install_worker.py'")

4. 在部署节点操作kubectl

对应5.kubectl_local.py,需要把server的配置拿过来,把ip换成server节点的局域网ip

# copy /etc/rancher/k3s/k3s.yaml to ~/.kube/config
os_system_sure(f"scp root@{master_ip}:/etc/rancher/k3s/k3s.yaml k3s.yaml")
with open("k3s.yaml", 'r') as stream:
    k3s_config = stream.read()
    stream.close()
    if k3s_config.find("server: https://127.0.0.1")==-1:
        print("unsupported k3s config, please check")
        exit(1)
    k3s_config=k3s_config.replace("server: https://127.0.0.1", f"server: https://{master_ip}")
    stream = open("k3s.yaml", 'w')
    stream.write(k3s_config)
    stream.close()

# set to ~/.kube/config
os_system_sure("mkdir -p ~/.kube")
os_system_sure("cp k3s.yaml ~/.kube/config")

5.代理问题

在起openwhisk时候遇到了代理问题,k3s文档里提到配一下服务环境变量即可,server和agent服务名不一样,对应6.setup_proxy.py。https://docs.k3s.io/zh/advanced#%E9%85%8D%E7%BD%AE-http-%E4%BB%A3%E7%90%86

for node, conf in config_data.items():
    ip=conf['ip']

    PROXY="http://192.168.31.53:7890"
    export=f"""
HTTP_PROXY={PROXY}
HTTPS_PROXY={PROXY}
NO_PROXY=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
"""
    # prepare remote
    if 'is_master' in conf:
        os_system_sure(f"ssh root@{ip} 'echo \"{export}\" >> /etc/systemd/system/k3s.service.env'")
        os_system_sure(f"ssh root@{ip} 'systemctl daemon-reload'")
        os_system_sure(f"ssh root@{ip} 'systemctl restart k3s'")
    else:
        os_system_sure(f"ssh root@{ip} 'echo \"{export}\" >> /etc/systemd/system/k3s-agent.service.env'")
        os_system_sure(f"ssh root@{ip} 'systemctl daemon-reload'")
        os_system_sure(f"ssh root@{ip} 'systemctl restart k3s-agent'")

但是还是遇到了pod内没有走代理的问题,提issue问了后发现,对containerd的代理并不会传递到真实pod实例的环境变量,因此最后的办法只有给路由器上。https://github.com/k3s-io/k3s/issues/10110

你可能感兴趣的:(分布式,云原生)