Eisen's Blog

© 2024. All rights reserved.

在 Github Actions 中获取最最最新的 commit

2021 December-09

有 helm charts 管理经验的人都晓得 helm charts 发布后需要打包一个 tar 放到目录里面。helm 会要求一个特定的目录结构获取不同版本的 tar 包。在 openbayes 就有这么一个 helm charts 项目里面存放了一系列的 tar 包。目前来看这些 tar 包都很小(只有几百 K)为了方便部署,就直接把这些文件和 nginx 打包到镜像里了,部署起来就能直接提供服务了,没有其他对象存储之类的外部依赖。

我们也希望把打包部署的流程通过 github workflow 实现自动化。按照上面的描述,可以分成两个步骤:

  1. release: 提交一个新 tag 触发 release 流程,将特定目录的文件达成 tar 包并以特定的名字保存到 packages 目录下,然后提交这个 tar 包
  2. build-and-push: 创建一个新的镜像包含刚才打的 tar 包,并提交到镜像仓库

同时,为了适用 reusable workflow ,可调用的 workflow 必须是一个独立的 job 出现在调用方的 workflow 里。我们需要把上述两个工作分成 github workflow 中两个独立的 job:

name: release a new helm version

on:
  ...

jobs:
  
  release:
    ...

  build-and-push:
    needs: release
    ...

但遇到一个很奇怪的问题,在 release 中明明提交了新的内容,在 build-and-push 中却拿不到。我的第一感觉就怀疑是 github 的 actions/checkout@v2 action 的行为有点问题。简单搜索了下,发现 actions/checkout@v2 默认会获取触发这次 github workflow 的 commit。也就是说,虽然我在 release 有新的提交,但是我在下一步 build-and-push 的 job 里还是 checkout 了上一个 commit 而已。

查看 actions/checkout@v2 的 README 发现,如果想要修改上述的行为,需要修改其 ref 参数。修改成想要获取最新 commit 的 branch 名称即可。而具体在 github action 里则可以使用 github.ref_name(在 https://docs.github.com/en/actions/learn-github-actions/contexts#github-context 可以看到相关文档)这个变量获取当前的 branch。这里我提供一个例子:

name: test commit

on:
  push:
    branches:
      - master

jobs:

  make-commit:
    runs-on: ubuntu-latest 
    
    steps:
      - uses: actions/checkout@v2
      - run: |
          FILENAME=`date  +"%y%m%d%H%M%S"`.txt
          echo 123 > $FILENAME
          echo "::set-output name=$FILENAME"
        id: write
      
      - uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: "add ${{ steps.write.outputs.name }}"
  
  checkout-commit:
    needs: make-commit
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
        with:
          ref: ${{ github.ref_name }}   # <-------- 如果不修改这里就拿不到上面提交的文件
      - run: |
          ls -lh

我在 github-checkout-test 这个仓库里做了上述的 workflow 的测试。增加 ref 参数为 ${{ github.ref_name }} 就可以获取最新的提交文件了。


让 Intellij 一直显示参数提示

2021 December-08

最近更换了新的 macbook pro 一方面由于架构发生了变化,原来电脑里的一些东西应该不能运行了;另一方面,原来的电脑有太多乱七八糟的东西了,我想要从新做一个干净的环境。所以决定一点点安装东西,后续会有一系列内容介绍这个过程中的查漏补缺。

众所周知,java 的方法不支持 name parameter 的,也没有默认值之说。在参数比较长的时候,按照顺序传递参数很容易忘记下一个参数到底是什么。

一个包含很长参数列表的方法调用
一个包含很长参数列表的方法调用

语言不行 IDE 来凑,Intellij 就在这方面做了加强,会在传递的参数前面显示这个参数的名字(如上图所示)。不过很遗憾,这里默认的配置并没有展示完整的信息,只在一些 Intellij 觉得你容易迷失的地方增加了提示。不过很显然它高估了我的水平,事实上我希望可以提供健全的参数信息。

幸好 Intellij 可以很容易的做这个修改:

  1. 点开设置 Preference > Editor > Inlay Hint > Java > Parameter hints
  2. 把这里的统统勾选,点击 OK

intellij parameter hints config

再回到刚才的方法,就可以看到提供了健全的参数信息了:

java method with all parameter hint in intellij

同时我发现视频录制可以更加有表现力,相较于繁琐的文字介绍视频可能会更清晰的展示一些工作流程。这里我就把刚才的设置录制了个视频:


ucloud 下部署高可用 k3s

2021 November-07

之所以要尝试 k3s 是因为它相对于标准的 k8s 所用的内存资源要减半,非常适合比较小型的设备,尤其是自己买来的小机器(树莓派?)。而对于标准的虚拟机环境,我们大可不必这么折腾了,毕竟越来越多的云厂商已经可以点点点就创建一个 k8s 集群了。

其实相关的主题已经非常多了,不过这里还会希望记录一下在国内环境部署高可用 k3s 一些不太一样的地方,也尝试了 k3s 的 config file 参数。

前提知识

首先,这里安装的是内嵌 etcd 的高可用版本,不是使用外部数据库的版本。不过为了让 worker 节点高可用,需要在 worker 和 master 节点之间增加一层负载均衡。虽然刚刚在说折腾 k3s 是针对非云环境的,不过考虑 bare-metal 的负载均衡还是需要一些稍微复杂的技术,这里就先不考虑了,后续会准备一个完全体。

那么整个架构就像 rancher 官方 提供的那样:

2021 11 08 00 32 05

不过很显然,这里的 etcd 已经不是一个外部的东西了,而是内嵌在每一个 server(master)节点里了。

预备环境

这里的测试环境用的 ucloud 。这里主要测试 master 的高可用,我准备了三台 master 以及一个 worker 节点。然后准备了一个内网的 ulb。

2021 11 08 00 36 20

2021 11 08 00 36 51

这里另外一个值得一提的是 ucloud 的内网 ulb 是需要在每台 master 做额外的设置的,参见官方文档

  1. 需要在每台机器下增加文件 /etc/netplan/lo-cloud-init.yaml,其中 $VIP 为 ulb 的内网 IP
network:
    ethernets:
        lo:
            addresses:
            - $VIP/32
  1. 执行命令 sudo netplan apply

通过命令 ip a 可以看到 lo 的网卡已经增加了 $VIP

由于我目前安装的 k3s 没用其内置的 containerd 而是用了 docker 所以需要为每台机器首先安装:

sudo apt update && sudo install docker.io -y

安装过程

整个过程是这样的:

  1. 创建第一个种子 master 节点 master0
  2. 陆续将另外两个 masetr 加入到集群
  3. 创建 worker 节点,不过在加入的时候采用的就是内网的 ulb 的 ip 了

首先在 master0 执行如下命令:

curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | \
    INSTALL_K3S_MIRROR=cn sh -s - server -c /home/ubuntu/master0-config.yaml
  1. 这里采用了国内镜像,直接使用 k3s 的镜像在国内应该会各种下载失败的。
  2. 采用了 k3s server 下一个 -c 的参数,这个参数可以将命令参数以 yaml 的形式传进来,这个就是看喜好了,传一系列 --xxx 形式的参数也应该没什么问题。

其中 master0-config.yaml 内容如下:

write-kubeconfig-mode: "0644"
tls-san:
- 10.60.210.147     # ulb ip
- 10.60.172.234     # master0
- 10.60.227.248     # master1
- 10.60.82.205      # master 2
- 117.50.162.155    # master0 external ip
- 117.50.172.65     # master1 external ip
- 117.50.172.104    # master2 external ip
docker: true
cluster-init: true
token: VNVIyKGNPtSKTfhi
disable: servicelb
  1. 把所有 master 的内网和外网 ip 都放进了 tls-san 同时把内网负载均衡节点 ip 也放了进来。
  2. k3s 默认使用 containerd 作为容器运行环境,不过我还是用惯了 docker 所以添加了参数 docker: true
  3. 第一台 master 采用 cluster-init 的方式启动。
  4. token 就是一个随机字符串,后面添加 master 节点和 worker 节点只要保持一致就好。
  5. disable 参数关掉了 k3s 默认添加的 servicelb 如果想要同时关掉 traefik 就可以写成 disable: servicelb,traefik注意 像配置 tls-san 那样用 yaml 的数组的语法是不行的,这也是让我多花了点时间的地方。

等 master0 的命令执行成功后输入命令 k3s kubectl get nodes -w 等待第一个节点准备完毕后在第二台 master 执行如下命令:

curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | \
    INSTALL_K3S_MIRROR=cn sh -s - server -c /home/ubuntu/master-others.config.yaml

其中 master-others.config.yaml 内容如下:

write-kubeconfig-mode: "0644"
tls-san:
- 10.60.210.147     # ulb ip
- 10.60.172.234     # master0
- 10.60.227.248     # master1
- 10.60.82.205      # master 2
- 117.50.162.155    # master0 external ip
- 117.50.172.65     # master1 external ip
- 117.50.172.104    # master2 external ip
docker: true
server: https://10.60.172.234:6443 # master0 kubernetes api server address
token: VNVIyKGNPtSKTfhi
disable: servicelb

注意 两台 master 要陆续添加,必须等第一个结束了再去添加第二台。

三台 master 都加入集群后,集群的核心安装过程就结束了。

下面就尝试添加一台 worker:

curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | \
    INSTALL_K3S_MIRROR=cn K3S_TOKEN=VNVIyKGNPtSKTfhi  sh -s - agent --docker --server="https://10.60.210.147:6443"

等 worker 变为 Ready 后集群的构建就算是完成了。这时候去任意一台 master 将 /etc/rancher/k3s/k3s.yaml 拷贝到自己的电脑上并修改里面 server 的 ip 为任意一台 master 的外网 ip 就可以作为 kubeconfig 文件使用了。

其他补充

还有个安装工具 k3sup 可以帮助快速安装集群,不过看起来更新的频率不高了,以及国内环境显然也不能直接用。

rancher cn 的团队也做了个 autok3s 在官网上就有介绍,不过看起来更新频率也不太高,并且 k3s 本身的安装成本真的很低了,所以就没去了解了。

除了安装之外,其实集群后续的维护工作也是挺重要的,毕竟你不希望集群慢慢老去不得不兼容各种奇怪问题,后面希望记录如何升级,如何集群数据备份和恢复两部分内容。

k3s 本身有一些局限性,比如它的 CNI 插件默认是 flannel 如果想要其他的就要自己去安装了,这个我并没有做更多的尝试了。

参考资料

  1. rancher k3s cn 的文档
  2. rancher k3s 官方文档