目录
前言
- 之前有写过利用k8s实现滚动发布,关于滚动发布的介绍请参考拙作kubernetes(k8s)滚动发布,不宕机实战。之前是使用k8s + docker,本文使用轻量级的 Kubernetes发行版K3S,容器运行时工具使用 containerd。
安装
curl -sfL https://rancher-mirror.rancher.cn/k3s/k3s-install.sh | INSTALL_K3S_MIRROR=cn sh -
如果镜像拉不下来
- 注意:安装后可能拉不下来镜像,两个方案。
方案一:代理
vim /etc/systemd/system/k3s.service.env
HTTP_PROXY=http://your-proxy.example.com:8888
HTTPS_PROXY=http://your-proxy.example.com:8888
NO_PROXY=127.0.0.0/8,10.0.0.0/8,172.16.0.0/12,192.168.0.0/16
方案二:更改镜像源
- 官方文档:https://docs.k3s.io/zh/installation/private-registry
vim /etc/rancher/k3s/registries.yaml
mirrors:
docker.io:
endpoint:
- "https://docker.m.daocloud.io"
配置nerdctl和buildkitd
新版本K3s 默认使用 containerd。这里我们使用nerdctl来打包成containerd镜像。nerdctl 是一个与 docker CLI 风格兼容的 containerd 的 CLI 工具,使用体验和 docker 基本一致。
下载地址:https://github.com/containerd/nerdctl/releases,下载全量包,即包含nerdctl和buildkitd。
解压到
/usr/local/nerdctl
目录,使用 nerdctl 管理 K3s 环境中的容器,手动指定 containerd socket,配置环境变量vim /etc/profile
export CONTAINERD_ADDRESS="unix:///run/k3s/containerd/containerd.sock"
export PATH=$PATH:/usr/local/nerdctl/bin
- nerdctl打包镜像要依赖buildkitd服务,为
buildkitd
添加到服务。 vim /etc/systemd/system/buildkitd.service
[Unit]
Description=buildkitd-server
After=k3s.service
[Service]
Type=simple
ExecStart=/usr/local/nerdctl/bin/buildkitd --containerd-worker-addr="/run/k3s/containerd/containerd.sock" --oci-worker=false --containerd-worker=true
[Install]
WantedBy=multi-user.target
- 启动
buildkitd
,并设置开机自启动
systemctl start buildkitd
systemctl enable buildkitd
部署Jar
- 本文以部署https://gitee.com/y_project/RuoYi-Vue.git后端程序为例。
配置文件
k3s配置
deployment.yaml
,相较kubernetes(k8s)滚动发布,不宕机实战的配置增加日志挂载到宿主机上,实现日志持久化。
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-boot-kubernetes-deployment
spec:
replicas: 1
strategy:
rollingUpdate:
maxSurge: 1 # 最大峰值用来指定可以创建的超出期望 Pod 个数的 Pod 数量。此值可以是绝对数(例如,5)或所需 Pods 的百分比(例如,10%)
maxUnavailable: 0 #最大不可用 是一个可选字段,用来指定 更新过程中不可用的 Pod 的个数上限。该值可以是绝对数字(例如,5)也可以是所需 Pods 的百分比(例如,10%)
selector:
matchLabels:
app: spring-boot-kubernetes-deployment
template:
metadata:
labels:
app: spring-boot-kubernetes-deployment
spec:
terminationGracePeriodSeconds: 300 #如果需要的优雅终止时间比较长 (preStop + 业务进程停止可能超过 30s),可根据实际情况自定义 terminationGracePeriodSeconds,避免过早的被 SIGKILL杀死,与下面preStop有关联,300属于总时间
containers:
- name: spring-boot-kubernetes
image: spring-boot-kubernetes:1.0.0
volumeMounts:
- name: log-volume
mountPath: /home/ruoyi
subPathExpr: $(POD_NAME)
imagePullPolicy: Never # 只使用本地镜像,防止ErrImagePull异常
ports:
- containerPort: 8080
readinessProbe: #就绪探针
httpGet:
path: /
port: 8080
initialDelaySeconds: 50 #容器启动后要等待多少秒后才启动存活和就绪探测器, 默认是 0 秒,最小值是 0
periodSeconds: 5 # 指定了 kubelet 应该每 5 秒执行一次存活探测。
successThreshold: 1 #探测器在失败后,被视为成功的最小连续成功数。默认值是 1。 存活和启动探测的这个值必须是 1。最小值是 1。
failureThreshold: 2 #当探测失败时,Kubernetes 的重试次数。 对存活探测而言,放弃就意味着重新启动容器。 对就绪探测而言,放弃意味着 Pod 会被打上未就绪的标签。默认值是 3。最小值是 1
env: # 解决Java程序时区问题
- name: TZ
value: Asia/Shanghai
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name # 注入 pod 名称
lifecycle:
preStop:
exec:
command: ["/bin/sh","-c","echo this pod is stopping. > /stop.log && sleep 90s"]
volumes:
- name: log-volume
hostPath:
path: /var/log/ruoyi #日志挂载到宿主机上
type: DirectoryOrCreate
service.yaml
apiVersion: v1
kind: Service
metadata:
name: spring-boot-kubernetes-nodeport
spec:
selector:
app: spring-boot-kubernetes-deployment
ports:
- name: http
port: 9090 # 暴露出来访问的端口
protocol: TCP
targetPort: 8080 # 目标端口
type: NodePort
Dockerfile
- Dockerfile内容
FROM m.daocloud.io/docker.io/library/openjdk:8-jdk-alpine
ADD ruoyi-admin.jar app.jar
ENTRYPOINT [ "java","-server", "-jar", "app.jar"]
打包镜像
- 将
ruoyi-admin.jar
放到Dockerfile
同级目录,执行命令。
# 注意: 这里要加命名空间k8s.io
nerdctl build -t spring-boot-kubernetes:1.0.0 . --namespace=k8s.io
crictl images
检查有没有镜像
运行apply deployment 和 service
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
初步验证
- 运行
kubectl get svc
找到服务
curl 10.43.96.156:9090
(替换成自己的CLUSTER-IP
)
- 接口能通就代表成功了
滚动发布验证
- 再构建一个镜像
nerdctl build -t spring-boot-kubernetes:1.0.1 . --namespace=k8s.io
- 我使用
jmeter
来验证滚动发布过程中是否有异常(30255是前面服务分配的端口,外部可访问的)。
jmeter
请求过程中我会使用以下命令升级镜像。
kubectl set image deployment/spring-boot-kubernetes-deployment spring-boot-kubernetes=spring-boot-kubernetes:1.0.1
验证结果
无异常发生表示滚动发布成功了
总结
- 与kubernetes(k8s)滚动发布,不宕机实战相比大改动还是docker换成了containerd,打包镜像要nerdctl和buildkitd配合。增加了挂载日志。
- 注意的点:
- 1、拉不下来镜像配置源或设置代理
- 2、打包镜像要增加
--namespace=k8s.io
参数,否则k3s获取不到镜像