背景
需求是这样的,需要部署一批静态站点在Kubernetes上,这批静态站点的所有静态资源全都推送在Git仓库的某个固定分支下,比如master分支下。对部署的要求特别简单,只需要把仓库克隆到本地,然后Nginx的root参数值修改到仓库目录位置即可,例子如下
rm -rf /var/www/html
git clone --depth=1 https://github.com/lizhongit/static.git /var/www/html
默认Nginx的default server的root路径就在/var/www/html
下,注意必须先删除/var/www/html
,否则克隆会失败提示你目录已存在。另外,建议添加上--depth=1
参数只克隆第一层,因为作为部署资源来说,没有必要clone整个仓库,那会造成下载资源众多导致部署周期变长。
初次部署的方案搞定了,接下来就是更新,更新其实并不复杂,只需要隔一段时间执行以下命令即可,比如每隔五分钟执行一下更新命令
cd /var/www/html
git pull
接下来要实现这个计划任务面临以下两个方案选择了
方案一:依赖k8s CronJob
这种方案,比较贴合k8s的环境,k8s提供了CronJob方案解决所有计划任务的需求,例子如下
deployment.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: html
spec:
accessModes:
- ReadWriteMany
storageClassName: html
resources:
requests:
storage: 100Mi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: ubuntu
env:
- name: DEBIAN_FRONTEND
value: noninteractive
ports:
- containerPort: 80
command:
- /bin/sh
- -c
- |
apt update
apt install -y git nginx
rm -rf /var/www/html
git clone --depth=1 https://github.com/lizhongit/static.git /var/www/html
/usr/sbin/nginx -g 'daemon off;'
volumeMounts:
- name: html
mountPath: /var/www/html
volumes:
- name: html
persistentVolumeClaim:
claimName: "html"
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- name: web
port: 80
targetPort: 80
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: update
spec:
schedule: "*/5 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: crontab
image: ubuntu
env:
- name: DEBIAN_FRONTEND
value: noninteractive
command:
- /bin/sh
- -c
- |
cd /html
apt update
apt install -y git
git pull
volumeMounts:
- name: html
mountPath: /html
volumes:
- name: html
persistentVolumeClaim:
claimName: "html"
以上YAML配置文件主要创建了一个Deployment和CronJob,Deployment负责运行Web静态服务器,CronJob负责每五分钟使用git pull
命令更新内容。虽说能工作,但这种方案有以下缺点
- 需要额外创建一个可支持多个Pod读写的PVC
- 需要创建CronJob
方案二:依赖容器内的Crontab程序
接下来,我们来介绍这种依赖容器内的Crontab程序达到更新的目的,先上YAML配置
deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 1
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: ubuntu
env:
- name: DEBIAN_FRONTEND
value: noninteractive
ports:
- containerPort: 80
command:
- /bin/sh
- -c
- |
apt update
apt install -y git cron nginx
rm -rf /var/www/html
git clone --depth=1 https://github.com/lizhongit/static.git /var/www/html
cat <<EOF | tee /etc/cron.d/web-cron
*/5 * * * * cd /var/www/html && /usr/bin/git pull
EOF
chmod 0644 /etc/cron.d/web-cron
crontab /etc/cron.d/web-cron
cron
/usr/sbin/nginx -g 'daemon off;'
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- name: web
port: 80
targetPort: 80
测试一下
$ kubectl apply -f deployment.yaml
deployment.apps/web created
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web ClusterIP 10.110.192.135 <none> 80/TCP 4m27s
$ curl 10.110.192.135
<!DOCTYPE html>
<html lang="zh-hans">
<head>
<meta charset="UTF-8" />
<title>琼台博客</title>
</head>
<body>
<h1>Hello World</h1>
<a href="https://www.qttc.net">琼台博客</a>
</body>
</html>
以上方案相比第一种有以下优点
- 不需要PVC做存储支持
- 不需要额外部署CronJob
- 由于不依赖PVC,所以可以横向扩展大量副本用于高并发
以上YAML文件均测试可用,大家也可以在自己的环境上试试!