在这个例子中,我们将使用GitHub行动将我们的Golang应用程序部署到Kubernetes集群。我们有qa,stage 和prod Kubernetes 环境。我们有三个不同的工作流程来处理这些环境。我将使用一个本地的Minikube集群,所以下面会有一个 "设置 "部分,用Ngrok把它暴露给公众。
结构
虽然我们在这里将专注于Kubernetes,但你可以运行go run -ldflags "-s -w -X main.commit=`git rev-parse --short HEAD`" -race main.go 命令,在你的本地环境中运行应用程序,并通过http://0.0.0.0:3000 访问它。
├── .env
文件
.env
# All these values are used for the local environment, not K8S!
.dockerignore
bin/
Docker文件
FROM golang:1.15-alpine3.12 as build
main.go
package main
main_test.go
package main
GitHub工作流程
我尽可能地减少了工作,否则这篇文章会非常长。因此,某些步骤被忽略了,比如linter等等。
pull_request_builder.yaml
# Trigger the workflow only when:
continuous_deployment.yaml
# Trigger the workflow to deploy to qa environment only when:
manual_deployment.yaml
# Trigger the workflow to deploy a specific git reference to a specific environment only when:
Kubernetes配置
如下图所示,有三个环境,每个环境都被隔离在其专用命名空间内。rollout 和imagePullPolicy 属性确保每次部署都会拉出新的镜像。
qa.yaml
apiVersion: v1
stage.yaml
apiVersion: v1
prod.yaml
apiVersion: v1
逻辑
拉动请求
- First time PR creation runs pull_request_builder.yaml
发布/热修复
- First time release/hotfix creation against develop/master runs pull_request_builder.yaml
标签
- Manually creating a tag does nt trigger any pipeline
手动部署
- Manually deploying a specific git ref (branch/tag/sha) to a specific environment
其他的
- Closed PRs will not trigger any pipeline
设置
在GitHub上添加Docker机密和Kube配置
这将使你的工作流程能够将图像推送到DockerHub注册处。
DOCKERHUB_USERNAME
这将使你的工作流程能够将应用程序部署到你的本地K8S集群。
// Enable routing public requests to K8S API.
// Expose kubectl proxy to the Internet with ngrok.
// Create a modified copy of your local kube config.
这是你应该拥有的东西。
准备好本地集群
你必须为每三个环境重复这些步骤。
// Create namespace
// Create application secrets for the deployment beforehand
测试
假设你已经完成了所有这些步骤,那么pull request builder和部署就成功了。让我们测试一下API。第一次部署将有两个副本,但随后的副本将只有一个,因为我们打了 "推出 "注释。
集群信息
$ kubectl --namespace=pipeline-qa get all
日志
$ kubectl --namespace=pipeline-qa logs pod/pipeline-deployment-5767699c9c-dzp2m
访问应用程序
$ kubectl --namespace=pipeline-qa port-forward service/pipeline-service 3000:80
这是你应该得到的结果。
$ curl http://0.0.0.0:3000