使用Github Action搭建k8s测试环境

前言

好久没有写博客了,因为测试的还没弄好,所以没啥好写的,不过现在第一版测试已经做好了,
所以这里简单分享一下使用Github Action做发布测试的经验

项目简介

项目托管在Github上,已经做了构建镜像的操作,也就是使用Github Action workflow做了构建镜像的操作,
但是测试还没做。而我最近刚转到这个项目组,所以就开始做简单的测试工作啦。项目的主要语言是Go,主要是开发一个云原生工具,
协助开发者更快的进行代码反馈,举个栗子,比如你的项目部署在远端kubernetes cluster中,阿里云或者腾讯云的k8s中,此时一般的开发步骤:

  • 本地编码 --> 本地docker build,push到docker仓库 --> 到k8s删除pod,重建个新的
  • 本地编码 --> 跑CI/CD直接更新到k8s环境中

但是这样都会有个问题,那就是慢,路径长,想知道开发的功能是否有问题的方式就是打日志,通过日志定位问题所在,而使用我们开发的工具

  • 本地编码 --> 本地调试(会自动同步本地文件夹到远程pod的container中,需要手动到container中启动服务)

项目原理

原理就是将container的镜像,替换为一个空镜像(tail -f /dev/null),拿掉readinessProbe和livenessProbe,防止将ip从endpoint controller拿掉,从而构建一个微型linux,同时使用文件同步,将本地文件同步到container中。

需求

每次提交PullRequest(也就是Merge Request,MR),调用测试用例,判断本地提交是否有问题。
每次合并到dev分支,调用测试用例,判断当前dev分支是否有问题。
每次合并到main分支,调用测试用例,判断当前main分支是否有问题。

分析

这设计到一个问题就是需要使用kubernetes跑应用,之前有了解到的是kubernetes可以使用kubectl,但是需要自己提供kubeconfig,也就是说需要自己提供集群,
然后将kubeconfig配置到github的secret中,使用{{ secret.KUBE_CONFIG }}这样的方式使用。但是这样有个缺点,就是集群只有一个,那么跑任务的时候,如果需要依赖依赖
pod资源配置的话,那么得是串行的,一个一个跑,跑完之后清理环境,供第二个任务跑。耗时很高

再到后边有了解到github action是可以跑docker的,那么理应也可以跑k8s的,因次,搜索了一下,有两个选择,第一个是使用k3s, 特点是轻量,初始化一个k3s的环境可能只需要20
秒左右,缺点是不是标准的k8s需要使用k3s kubectl get pods -A这样的方式才能访问到集群数据。第二种选择是kind,kubernetes in docker的缩写,链接
,缺点是启动慢,按照说明至多5min就可以初始化好,测试发现大约需要2分钟左右就可以了,优点是标准的k8s。后边通过取舍,还是使用了标准的k8s作为测试环境,
2分钟的初始化时间是可以接受的,同时标准的k8s有利于避免环境不统一导致的问题。

k8s配置

name: k8s # 此workflow的名称,可自定义

on: # 触发条件
  push: # 标示向master分支合并代码就会触发此workflow
    branches: [ master ]
  pull_request: # 标示向master分支提交了merge request就会触发,pull request === merge request
    branches: [ master ]
  workflow_dispatch: # 会出现一个按钮,可以手动调起workflow
  workflow_run:
    workflows: [ "k3s" ] # 这里可以由另一个workflow触发,触发条件是名称为k3s的workflow结束
    types: [ completed ] # 触发条件是结束状态,可以填写started,意为workflow k3s一开始就调用这个k8s的workflow

jobs:
  on-success: # job名称,可以自定义
    runs-on: ubuntu-latest # 跑在什么平台上的,支持linux,macos和windows,这里提供的是虚拟机资源
    steps: 
      - uses: actions/[email protected] # 使用这个插件checkout代码
        timeout-minutes: 10 # 这个step的超时时间
      - name: git tag
        timeout-minutes: 60
        if: ${{ github.event.workflow_run.conclusion == 'success' }} # 如果是由workflow_run触发的,并且上个workflow结果状态是成功的才执行此step,如果是手动或者其他触发的,则会skip这个step
        run: |
          git fetch --prune --unshallow --tags
          TAG=$(git tag | tail -2)
          echo $TAG
          TAG=$(echo $(git tag | tail -2))
          echo $TAG
          echo "可以手动设置环境变量,如下"
          echo "RELEASE_VERSION=${TAG}" >> $GITHUB_ENV
      - uses: actions/checkout@master
        timeout-minutes: 10
      - uses: engineerd/setup-[email protected] # 这里就是使用了kind,初始化一个k8s
        timeout-minutes: 10
      - name: Waiting for images to be ready
        timeout-minutes: 60
        run: |
          echo ${{ env.RELEASE_VERSION }}
      - name: Kubernetes info # 这个step会打印出k8s的信息
        timeout-minutes: 5
        run: |
          kubectl cluster-info
          kubectl get pods -n kube-system
          cat ~/.kube/config
          ls -lah ~/.kube/config
          cd ~/.kube/
          pwd

k3s配置

# This is a basic workflow to help you get started with Actions

name: k3s

# Controls when the action will run. 
on:
  push:
    tags:
    - "v*"
  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: debianmaster/actions-k3s@master # 使用k3s提供的k8s环境
      id: k3s
      with:
        version: 'v1.18.2-k3s1'
    - run: |
        kubectl get nodes
        kubectl config view --raw

注意的点

workflow_run的顺序问题

workflow_run可以填写多个workflow的名字,表示可以由其它workflow调用,不过这些调用是无感知的,并不是都完成了才调用当前workflow,而是有其中一个满足条件就会调用
比如:需要等待两个workflow构建镜像完成之后,再进行测试,那么这里使用workflow_run是无法做到的,每次两个构建镜像任务中的任何一个任务结束,都会调用当前workflow。当然了,如果可以容忍速度问题的话,可以将这两个构建镜像的workflow也使用workflow_run串起来
不过这样就会比较慢。

${GITHUB_SHA}的值和commitid不是对应的

${GITHUB_SHA}是每次都会重新生成一个的,而不是和merge request的commitid对应,但是内容是一致的,都是提交上来的这部分代码的内容

jobs默认是串行的

jobs默认是串行的,可以使用needs串起来,step默认是串行的(没找到什么选项可以并行)

workflow需要放在default分支

workflow需要放在default分支才可以显示,(貌似不是很准,不过有些选项是放在默认分支才生效的)

kind目前只支持linux

kind目前只支持linux,不支持macos和windows

kind稳定性问题

kind貌似不是很稳定,有的时候k8s会很慢,可以通过取消重新跑的方式尝试规避

if语句很强大

if用法很灵活,有兴趣的可以参见官网例子

使用github action + kind/k3s搭建k8s网络问题

由于我们的任务需要使用到kubeconfig来进行在pod中和外部k8s进行通信,但是pod内部和node的网络是不互通的,k8s的网络方式貌似都不支持pod和node主机使用同一个网络进行通信,不过这里可以使用docker来解决这个问题

docker run --network host

的方式启动container,这样就可以使用node主机上的网络了。

你可能感兴趣的:(github,action,github,action,kind,kubernetes)