Github Action - 製作高重複利用的 CI Script(Image) for beta

本文已經不合時宜,請參考 Github Action - 更換成 beta v2 新的格式 (yaml)

本文使用 HCL syntax in GitHub Actions 將會在 2019-09-30 被棄用。(for info)

大家在開發 CI 的時候,一定會遇到需要寫 script,無論是 Shell Script, Python, Makefile,多少都會用到。那麼當你在第二個、第三個專案也需要一樣的流程,那我們就會從舊的專案複製一樣的 script 到新專案。

這個時候,如果發現 script 寫錯了,或是要擴充時。那麼你有數十個專案,都要一一進去每個專案改動這個 CI script,是不是想到就頭痛?

那麼你可以開始嘗試 Github Action,Github Action 非常符合 DRY(Don’t Repeat Yourself) 的原則,只要是 public repo 的 Dockerfile,那麼你就可以使用它,這等於是可以將 CI script 模組化,並重複利用。

你甚至可以在 local 使用,當作是 Jenkins, Ansible 的替代品

Talk Is Cheap. Show Me The Code

Sample code: https://github.com/swaglive/action-demo/tree/master/.github

workflow "Show env" {
on = "push"
resolves = ["debug","hello"]
}

action "debug" {
uses = "docker://alpine:3.10"
args = ["env"]
}

action "hello" {
needs = "debug"
uses = "docker://alpine:3.10"
args = ["echo", "hello"]

env = {
DOCKER_REGISTRY_URL = "docker.pkg.github.com"
IMAGE = "echo-box:latest"
}
secrets = ["DOCKER_USERNAME", "DOCKER_PASSWORD"]
}

Read More

GitOps - Store Secrets

因為 GitOps 需要將所有的 config(yaml) 包含 secret 都存在 Git 上,Kubernetes Secret 基本上也算是明文,為了更完善 GitOps,我們必須加密 secrets,再推上 Git Repo。

在本地端加密 secrets.yaml,透過 sealed-secrets 解密,還原 kubernetes secrets。

release=$(curl --silent "https://api.github.com/repos/bitnami-labs/sealed-secrets/releases/latest" | sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p')

# Install client-side tool into /usr/local/bin/
GOOS=$(go env GOOS)
GOARCH=$(go env GOARCH)
wget https://github.com/bitnami-labs/sealed-secrets/releases/download/$release/kubeseal-$GOOS-$GOARCH
sudo install -m 755 kubeseal-$GOOS-$GOARCH /usr/local/bin/kubeseal

# Note: If installing on a GKE cluster, a ClusterRoleBinding may be needed to successfully deploy the controller in the final command. Replace <your-email> with a valid email, and then deploy the cluster role binding:
USER_EMAIL=rammus.xu@swag.live
kubectl create clusterrolebinding $USER-cluster-admin-binding --clusterrole=cluster-admin --user=$USER_EMAIL

# Install SealedSecret CRD, server-side controller into kube-system namespace (by default)
# Note the second sealedsecret-crd.yaml file is not necessary for releases >= 0.8.0
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/$release/controller.yaml
kubectl apply -f https://github.com/bitnami-labs/sealed-secrets/releases/download/$release/sealedsecret-crd.yaml

Create secret.yaml:

apiVersion: v1
kind: Secret
metadata:
name: mysecret
namespace: argocd
type: Opaque
data:
mykey: bXlrZXk=

Encrypt secret.yaml:

kubeseal <secret.yaml >encrypted.yaml --format yaml

產生 SealedSecret CRD encrypted.yaml:

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
creationTimestamp: null
name: mysecret
namespace: argocd
spec:
encryptedData:
mykey: AgBiEzc5KIX5FqpR8ommE2avZf7qmfIO3WcMbllnfERcs7rYPThhhAARtFm4KFtjnqGDhe5VkrDR1GrEGkBGwrqTjhLaaEDZVwMdeKCXF1H8893ksX+pxy670LIMbNbRCNFhPAOihkncXp7S6AjyILpdpZJEk/6/GwRtaDDImbe/R6REgATVXAzNNiCw3Zq2vHzKSdeAwYYGrH9fcMXy0RIeiUzUo8ylVL7IYmiitBtXIyH5fz+2zq/D+v4vGt425wQXCk9s1z/6sAtL1+voV7t0sLlTnGOkAk8Cnz8hhQzXdiucFyIeIzrqzJwB2L+MoAy0RxawiyZNpKbRsb8tZH2rGTgjF+M6+nUbGlH0n5BBKOocSbVpoa5aBGP7q1dGP+hI+fDbUzg/t0PJNIEag9Kq4VkbdZPzqG35Fe8ysrGaALEeuK9VmkujFugoGXj9MyNL1z+RjBXUTUaxnzRmsJRwL5+AMC1hMMpeyH1y2NNXBOUYB2GKxHBHTKfZVKQThi82lEwCcuRypUFtaHh7aNH2j6Vk3bWMItO4I9nP++yRmuiK9F4ISSbcoPTG62Bg5gG9+awde5Ma1urS2fOJfPTft5FAHCwM0fKTvIkj6T5LVfnF/7WArVMwCm+zX3iDwJ5QnIGZ7cYBveJtSQqCzewu/ki0E3LMid4rJKJQiyfMnY2j80Sjija9wJHxo3YIXNO1WPV9Ow==

Apply encrypted.yaml:

kubectl apply -f encrypted.yaml
kubectl get secrets mysecret -o yaml

Get mysecret:

sealedsecret.bitnami.com/mysecret created
apiVersion: v1
data:
mykey: bXlrZXk=
kind: Secret
metadata:
creationTimestamp: "2019-07-17T08:42:38Z"
name: mysecret
namespace: argocd
ownerReferences:
- apiVersion: bitnami.com/v1alpha1
controller: true
kind: SealedSecret
name: mysecret
uid: d50676ae-a86e-11e9-bfe3-42010a8c0104
resourceVersion: "96285790"
selfLink: /api/v1/namespaces/argocd/secrets/mysecret
uid: d50b582b-a86e-11e9-9599-42010a8c010e
type: Opaque

結論

所以我們只要把 encrypted.yaml 推上我們的 Git Repo,讓 GitOps 工具(Argo, Flux, …)自動部署到 cluster,sealed-secrets Controller 將會解密成 Kubernetes secret。

記住,不要把未加密的 secret.yaml 傳到 Git!好好的保留在本機就好。

Other Choices

Reference

https://github.com/argoproj/argo-cd/issues/1364
https://www.weave.works/blog/storing-secure-sealed-secrets-using-gitops

Read More

GitOps Comparison - Argo, Flux

在決定要導入哪一套 GitOps Tool 之前,先看看這兩套最潮的工具的行為、CLI、Template 是否有什麼不一樣的地方。

Topic
Star
Watch Docker Registry
Watch Git Repository ✅ default: 5 mins ✅ default: 3 mins
UI ✅ See GitOps - Argo CD Note.
Pull Strategy
Centralized Config Repo link
CLI
CLI link link
Manually Operation Write Back Git Repo ✅ 使用 fluxctl 會自動同步回 Git Repo link
Template
Subdirectories Support
Kustomize Support
Helm Support

Bootsrapping

Argo CD

比較奇怪的部分就是一定要透過 CLI 或是手動點擊網頁建立 Application,而不是像 Flux 直接指定一個 Git Repo,管理所有的 application。

Ref: https://argoproj.github.io/argo-cd/operator-manual/cluster-bootstrapping/

Flux CD

安裝 Flux 時,直接指定 Git Repo 即可。

Read More

Reference

List GCR Public Images

網路上常常看到許多範例使用類似 gcr.io/google_containers/echoserver:1.10 的 Image,
讓我開始好奇 google 到底有哪些 public image 呢?

好不容易才找到這個超隱蔽的兩個 Registry:

但是沒有像 Dockerhub 一樣有美美的 UI,包含 Dockerfile,Repo,Tag,Build,…。

如果有安裝 gcloud SDK 的同學們,也可以直接使用下列指令。

gcloud container images list --project google-containers

Reference