k8s自动部署Hexo博客
刚开始时候博客部署在Github Pages上面,当时感觉用了github的托管就没啥归属感。再接着使用rsync将github action生成的public文件夹同步到国内云服务器的caddy服务器里面,使用自己的服务器域名,但是rsync这个方案不太优雅每次部署时阿里云都会有访问告警。现在自己的k3s集群起来了一切就好说了。
主要的想法是CI部分依旧白嫖github,将编译好的网站文件夹连同caddy服务器打包成docker镜像,依靠Helm3实现CD。
这里先放出完整的github ci文件
The deploy_hexo updated at: 2022.08.01
1 | name: deploy_hexo |
网站镜像build与push
第一大部分还是编译Hexo博客,和之前的没有任何区别,编译生成的文件都在public
文件夹里。编译完成后就是打包镜像并push到dockerhub等镜像仓库里面去。
Dockerfile
dockerfile很简单,这里直接把Caddyfile放在了dockerfile里头,并且添加GET http://*:8080/healthz
作为k3s健康检测的endpoint,且关闭自动https。
1 | FROM caddy:2 |
构建与推送镜像
此步骤在workflows有三部分:
- 用
docker/setup-buildx-action@v2
来设置构建环境。 - 用
docker/login-action@v2
登陆到docker hub。 - 用
docker/build-push-action@v3
构建并推送镜像。
这里需要用到docker hub的token,登陆后在Account Settings->Security
里面创建一个token,记下token下面要用,不得不说docker hub有点小气就给一个免费的token:
在博客的仓库添加两个secret,分别是docker hub的用户名DOCKERHUB_USERNAME
和tokenDOCKERHUB_TOKEN
,该部分workflow如下:
1 | - name: Set up Docker Buildx |
dockerfile等都放在项目跟目录,所以这了context
就是.
,tag
就是推送上去镜像名字。注意这里的id: docker_build
一定要加,接下来的部署过程会用到。
Helm模板
This section updated at: 2022.08.01
删除helm chart内容,直接展示chart repo
helm使用v3版本,把chart做到了私人的repo里去
https://github.com/c1emon/helm-charts
1 | helm repo add clemon https://helm-charts.clemon.icu |
简单的values.yaml
文件,开启了tls
1 | image: |
自动部署
为Github CI创建k3s凭证
这部分是我花时间最多的,首先说下我并没有系统性的学习过k3s,甚至本身不是计算机科班出身也不干这行。所以对k3s权限以及API等部分理解的却是不好。刚开始一个劲想要为github ci分配一个serviceAccount,但是不停尝试都不能生成个能用的kubeconfig,依稀记得之前玩k8s的时候这样只能拿到一个token(可以登陆dashboard)。接着好好想了想,github ci不就是相当于一个运维人员吗,所以给个user类型的账号做好权限控制就行了~
这篇Kubernetes RBAC 详解写的很好,可以参考~
本地创建密钥文件
gh-ci.key
1
openssl genrsa -out gh-ci.key 4096
为key生成签名请求文件
gh-ci.csr
1
openssl req -new -key gh-ci.key -out gh-ci.csr -subj "/CN=github-ci/O=clemon"
这里的
CN=github-ci
表示用户名就是github-ci
,O=clemon
表示该用户属于组织clemon
进行签名,获得签名完成的文件
gh-ci.crt
- k3s的证书与密钥在master节点的
/var/lib/rancher/k3s/server/tls
目录下,分别是client-ca.crt
和client-ca.key
1
openssl x509 -req -in gh-ci.csr -CA /var/lib/rancher/k3s/server/tls/client-ca.crt -CAkey /var/lib/rancher/k3s/server/tls/client-ca.key -CAcreateserial -out gh-ci.crt -days 3650
This section updated at: 2022.08.01
这种签名方法麻烦而且需要额外保存签名文件,推荐使用CertificateSigningRequest进行签名
- k3s的证书与密钥在master节点的
生成kubeconfig文
<ca-tata>
就是/etc/rancher/k3s/k3s.yaml
的certificate-authority-data
内容,看了很多文章都会用/var/lib/rancher/k3s/server/tls/client-ca.crt
,如果用这个的话kubectl提示证书无法验证,可以通过--insecure-skip-tls-verify
跳过,但是这种情况导致了helm部署失败,因为helm没有这个跳过验证证书的flag。1
2
3
4kubectl --kubeconfig=gh-ci.kubeconfig config set-cluster default --server=https://apiserver.domain.or.ip:6443 --certificate-authority=<ca-tata> --embed-certs=true
kubectl --kubeconfig=gh-ci.kubeconfig config set-credentials github-ci --client-certificate=`pwd`/gh-ci.crt --client-key=`pwd`/gh-ci.key --embed-certs=true
kubectl --kubeconfig=gh-ci.kubeconfig config set-context gh-ci --cluster default --user=github-ci
kubectl --kubeconfig=gh-ci.kubeconfig config set current-context gh-ci到这里一个用户就创建好了,但是现在这个用户没有权限,所以不能执行任何操作。
授权
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: blog-maintainer
namespace: blog
rules:
- apiGroups: ["", "apps", "networking.k8s.io"] # 空字符串""表明使用core API group
resources: ["services", "deployments", "ingresses", "secrets"]
verbs: ["*"]
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: blog-maintainer-authorization
namespace: blog
subjects:
- kind: User
name: github-ci
apiGroup: ""
roleRef:
kind: Role
name: blog-maintainer
apiGroup: ""此处给出的权限可能过大,还需要慢慢调整。这里
subjects.name
要和你的用户名对应!
自动部署
最后就是部署部分了:
1 | - name: Deploy to k3s |
首先在本地手动部署一个到k3s集群中,接下来直接自动化~万岁~完结撒花~