如何嘗試用GitHub Actions項目編寫容器應用?

早前,GitHub 發佈GitHub Actions項目,開發者可通過 GitHub Actions 存儲和搜索代碼,部分代碼可直接運行。本文嘗試使用AWS Lambda和API Gateway作爲基本API,編寫應用程序原型並用名爲gourmet的容器運行函數,雖然這可能不會讓代碼易於管理,但至少不需要寫API或者Web應用程序。

正如Lambda函數在AWS中運行一樣,Github Actions是一種強大的管理方式,可直接擴展應用。使用AWS Lambda,可將代碼掛接到幾乎任何事件上,比如EC2創建、終止、DNS記錄更改等,不需要運行服務器,只需加載代碼就能正常工作。

本文作者針對此做了一些嘗試,但需要CI服務器。爲了擁有可測試的kubernetes集羣,作者自建私有存儲庫,目前因內部有些混亂暫不準備開源。

無論如何,以下是項目文件夾:

├── .github
│   ├── actions
│   │   ├── deploy
│   │   │   ├── deploy
│   │   │   └── Dockerfile
│   │   └── dryrun
│   │       ├── Dockerfile
│   │       └── dryrun
│   └── main.workflow
└── kubernetes
    ├── digitalocean.yaml
    ├── external-dns.yaml
    ├── micro.yaml
    ├── namespaces.yaml
    ├── nginx.yaml
    └── openvpn.yaml

kubernetes目錄包含集羣安裝的所有東西。對於此存儲庫的每次新推送,需要檢查是否可用命令kubectl apply -f./kubernetes --dryrun將其應用於kubernetes集羣,並且當合並PR時,應用更改。

因此,作者在.github/main.workflow中創辦了工作流:

## Workflow defines what we want to call a set of actions.
## For every new push check if the changes can be applied to kubernetes ## using the action called: kubectl dryrun
workflow "after a push check if they apply to kubernetes" {
  on = "push"
  resolves = ["kubectl dryrun"]
}
## When a PR is merged trigger the action: kubectl deploy. To apply the new code to master.
workflow "on merge to master deploy on kubernetes" {
  on = "pull_request"
  resolves = ["kubectl deploy"]
}
## This is the action that checks if the push can be applied to kubernetes
action "kubectl dryrun" {
  uses = "./.github/actions/dryrun"
  secrets = ["KUBECONFIG"]
}
## This is the action that applies the change to kubernetes
action "kubectl deploy" {
  uses = "./.github/actions/deploy"
  secrets = ["KUBECONFIG"]
}

secrets是一組環境變量,可從外部設置值。如果帳戶啓用GitHub Action,則每個存儲庫的Setting都會有一個名爲secrets的新標籤。

本例,作者將KUBECONFIG設置爲kubeconfig文件的base64,允許GitHub Action授權給Kubernetes集羣。

兩個操作類似,第一個操作位於 .github/actions/dryrun目錄:

├── .github
    ├── actions
        └── dryrun
            ├── Dockerfile
            └── dryrun

包含一個 Dockerfile

FROM alpine:latest

## The action name displayed by GitHub
LABEL "com.github.actions.name"="kubectl dryrun"
## The description for the action
LABEL "com.github.actions.description"="Check the kubernetes change to apply."
## https://developer.github.com/actions/creating-github-actions/creating-a-docker-container/#supported-feather-icons
LABEL "com.github.actions.icon"="check"
## The color of the action icon
LABEL "com.github.actions.color"="blue"

RUN     apk add --no-cache \
        bash \
        ca-certificates \
        curl \
        git \
        jq

RUN curl -L -o /usr/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/v1.13.0/bin/linux/amd64/kubectl && \
  chmod +x /usr/bin/kubectl && \
  kubectl version --client

COPY dryrun /usr/bin/dryrun
CMD ["dryrun"]

如上所示,只需要一個 Dockerfile,工作原理和 docker類似。Cmd dryrun 在這裏是複製的 bash 腳本:

#!/bin/bash

main(){
    echo ">>>> Action started"
    # Decode the secret passed by the action and paste the config in a file.
    echo $KUBECONFIG | base64 -d > ./kubeconfig.yaml
    echo ">>>> kubeconfig created"
    # Check if the kubernetes directory has change
    diff=$(git diff --exit-code HEAD~1 HEAD ./kubernetes)
    if [ $? -eq 1 ]; then
        echo ">>>> Detected a change inside the kubernetes directory"
        # Apply the changes with --dryrun just to validate them
        kubectl apply --kubeconfig ./kubeconfig.yaml --dry-run -f ./kubernetes
    else
        echo ">>>> No changed detected inside the ./kubernetes folder. Nothing to do."
    fi
}

main "$@"

第二個操作和此幾乎一樣,Dockerfile是相同的,但CMD看起來是這樣的:

#!/bin/bash

main(){
    # Decode the secret passed by the action and paste the config in a file.
    echo $KUBECONFIG | base64 -d > ./kubeconfig.yaml
     # Check if it is an event generated by the PR is a merge
    merged=$(jq --raw-output .pull_request.merged "$GITHUB_EVENT_PATH")
    # Retrieve the base branch for the PR because I would like to apply only PR merged to master
    baseRef=$(jq --raw-output .pull_request.base.ref "$GITHUB_EVENT_PATH")

    if [[ "$merged" == "true" ]] && [[ "$baseRef" == "master" ]]; then
        echo ">>>> PR merged into master. Shipping to k8s!"
        kubectl apply --kubeconfig ./kubeconfig.yaml -f ./kubernetes
    else
        echo ">>>> Nothing to do here!"
    fi
}

main "$@"

除此之外,工作流文件還有一個生成器,似乎效果不錯。secrets允許開箱即用,並與第三方服務集成,也可用bash做任何想做的事情!

參考鏈接:https://gianarb.it/blog/kubernetes-github-action

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章