GitHub Actions + K3S 部署到云服务器
前端CI/CD的简单实践
# 安装前的准备
- 一个带公网IP的服务器
- 域名以及ssl证书
- github 账号
- 可部署的应用(这里以本博客为例子)
- 任意厂商的docker镜像仓库
# 安装K3S
执行命令官方文档的命令安装
curl -sLS https://get.k3s.io | INSTALL_K3S_EXEC='server --tls-san (公网ip或域名)' sh -
这里一定要添加--tls-san 否则在github Action apply yml文件时会报错的只需要填写括号里面的内容即可。
# 编写action文件
在 K3s 安装完成并且配置成公网可以访问后,我们就可以开始准备将博客的 github 项目上的 Github Actions 了.
文件名称可以随意取,这里以本博客为例,创建一个docker-image.yml
文件到根目录的.github/workflows
文件夹下
### docker-image.yml
name: Docker Image CI
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build the Docker image
uses: actions/setup-node@v2
with:
node-version: 16
- run: npm install
- run: npm run build
- run: docker login --username=${{ secrets.DOCKER_USERNAME }} registry.cn-hangzhou.aliyuncs.com --password=${{ secrets.DOCKER_PASSWORD }}
- run: docker build . --file Dockerfile --tag registry.cn-hangzhou.aliyuncs.com/docker/blog:${{ github.sha }}
- run: docker push registry.cn-hangzhou.aliyuncs.com/docker/blog:${{ github.sha }}
deploy:
needs: build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- run: ls
- run: sed -i 's/{TAG}/${{ github.sha }}/g' nginx-deployment.yml
- name: deploy to cluster
uses: steebchen/kubectl@master
with:
config: ${{ secrets.KUBE_CONFIG_DATA }}
version: v1.22.7
command: apply -f nginx-deployment.yml
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
其中包含了npm run build 以及 deploy的步骤
- 第一步
编写Dockerfile
来制作镜像,对应到build 步骤里的docker build .
下面给出我的Dockerfile文件
FROM nginx:alpine
RUN adduser -D -H -u 5000 -s /bin/sh www
RUN rm /etc/nginx/conf.d/default.conf
ADD scripts/nginx.conf /etc/nginx/
ADD scripts/app.conf /etc/nginx/sites-available/
ADD public /var/www
VOLUME /var/www
CMD ["nginx"]
2
3
4
5
6
7
8
其中 scripts/app.conf 需要在github项目的根目录下创建文件夹scripts
并在其中添加配置文件app.conf
### app.conf
server {
listen 80;
root /var/www;
location ~* .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$ {
expires 30d;
}
location / {
# 用于配合 browserHistory使用
try_files $uri $uri /index.html;
add_header Cache-Control "no-cache";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
是打包博客项目并上传到镜像仓库,secrets.DOCKER_USERNAME
secrets.DOCKER_PASSWORD
这两个属性是配置在github项目里的 在Settings->Secrets->Actions 里面配置这DOCKER_USERNAME
,DOCKER_USERNAME
两个参数
- 第二步
就是要执行kubectl applay 的命令了,这样就可以把应用部署到K3s上。
- run: sed -i 's/{TAG}/${{ github.sha }}/g' nginx-deployment.yml
这里需要注意以下secrets.KUBE_CONFIG_DATA
这个值的生成,一定要在安装K3S时添加参数--tls-san否则无法在服务器上部署
KUBE_CONFIG_DATA
的获取通过执行cat $HOME/.kube/config | base64
命令获取,然后按第一步配置到项目中,一般情况下里面的IP 是 127.0.0.1
我们需要改成自己的服务器IP,建议先cat出内容保存到一个位置修改后再进行base64转换
如:
cat $HOME/.kube/config >> config
vim config
···
:wq
cat config | base64
2
3
4
5
使用其他方式获取因为有可能没办法获得证书,这样获取的比较完整。
在github项目根目录准备好nginx-deployment.yml
文件来启动pod
### nginx-deployment.yml
apiVersion: apps/v1 #与k8s集群版本有关,使用 kubectl api-versions 即可查看当前集群支持的版本
kind: Deployment #该配置的类型,我们使用的是 Deployment
metadata: #译名为元数据,即 Deployment 的一些基本属性和信息
name: nginx-deployment #Deployment 的名称
labels: #标签,可以灵活定位一个或多个资源,其中key和value均可自定义,可以定义多组,目前不需要理解
app: nginx #为该Deployment设置key为app,value为nginx的标签
spec: #这是关于该Deployment的描述,可以理解为你期待该Deployment在k8s中如何使用
replicas: 3 #使用该Deployment创建一个应用程序实例
selector: #标签选择器,与上面的标签共同作用,目前不需要理解
matchLabels: #选择包含标签app:nginx的资源
app: nginx
template: #这是选择或创建的Pod的模板
metadata: #Pod的元数据
labels: #Pod的标签,上面的selector即选择包含标签app:nginx的Pod
app: nginx
spec: #期望Pod实现的功能(即在pod中部署)
containers: #生成container,与docker中的container是同一种
- name: nginx #container的名称
image: registry.cn-hangzhou.aliyuncs.com/docker/blog:{TAG} #使用镜像nginx创建container,
imagePullPolicy: Always
ports:
- containerPort: 80 #内部服务暴露的端口
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
其次服务器上需要准备好 ingress(k3s 自带) 以及 service并执行命令
kubectl apply -f xxx.yml
这里贴出我的这两个文件
service.yml
### service.yml
apiVersion: v1
kind: Service #该配置的类型,我们使用的是 Service 服务类型
metadata:
name: nginx-service #该服务类型的名称
spec:
selector: #选中的app部署实例
app: nginx #为该Deployment设置key为app,value为nginx的标签
ports: #暴露的端口
- protocol: TCP # 走得tcp 协议
port: 80 #默认端口
targetPort: 80 #内建服务端口
nodePort: 30080 #对外服务端口
type: NodePort
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ingress.yml
### ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: docker
spec:
tls:
- hosts:
- xxx.com ### 域名
- www.xxx.com ### 域名
secretName: secretName ### 生成secret名称 在下面的步骤中出现
rules:
- host: xxx.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
- host: www.xxx.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-service
port:
number: 80
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 证书的配置
可以在域名提供商上申请并下载,这里我选择的是阿里云的nginx证书下载后会有.key
和.pem
两个文件
kubectl create secret generic secretName --from-file=tls.key=./xxx.key --from-file=tls.crt=./xxx.pem
其中secretName
就是要生成的名称然后配置到ingress里面
tls:
- hosts:
- xxx.com ### 域名
- www.xxx.com ### 域名
secretName: secretName
### 完整内容在上面
2
3
4
5
6
# 总结
按照以上步骤希望能给到正在给自己的个人服务器编写ci/cd的朋友提供一些帮助,目前的个人服务器配置比较低,使用K3S对配置要求不是那么高,可以进行单机部署,安装简单快捷。在这次实践中查阅了其他人的博客,但总会遇到一些坑,一般来说是由于版本问题引起的,这里给出我当前的版本。
kubectl version
Client Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.7+k3s1", GitTreeState:"clean", BuildDate:"2022-02-24T23:03:47Z", GoVersion:"go1.16.10", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.7+k3s1", GitTreeState:"clean", BuildDate:"2022-02-24T23:03:47Z", GoVersion:"go1.16.10", Compiler:"gc", Platform:"linux/amd64"}
2