1-2可以再本地环境执行,只需要部署一个docker镜像
1. 项目信息
1.1 目录结构
# 项目目录信息
$ tree go-container
go-container
├── Dockerfile
├── go.mod
├── go.sum
└── main.go
1.2 主代码信息
main.go
代码如下:
package main
import (
"github.com/gin-gonic/gin"
"os"
"time"
)
func main() {
engine := gin.Default()
engine.GET("/", func(context *gin.Context) {
// 显示主机名字
hostName, _ := os.Hostname()
context.JSON(200, gin.H{
"version": "v1",
"hostName": hostName,
"time": time.Now().Format("2006-01-02 15:04:05"),
})
})
_ = engine.Run(":80")
}
2. 制作镜像
2.1 编写Dockerfile
# Golang版本;Alpine镜像的体积较小。
FROM golang:1.18 as builder
# 将代码复制到构建镜像中。
ADD . /workspace
WORKDIR /workspace
# 挂载构建缓存。
# GOPROXY防止下载失败。
RUN --mount=type=cache,target=/go \
env GOPROXY=https://goproxy.cn,direct \
go build -buildmode=pie -ldflags "-linkmode external -extldflags -static -w" \
-o /workspace/gin-hello
# 运行时镜像。
# Alpine兼顾了镜像大小和运维性。
FROM alpine:3.14
EXPOSE 8080
# 复制构建产物。
COPY --from=builder /workspace/gin-hello /app/
# 指定默认的启动命令。
CMD ["/app/gin-hello"]
2.2 构建镜像
# 进入项目目录执行
$ docker build -t liuqinghui/gin-hello:v1 .
[+] Building 30.7s (12/12) FINISHED
...
=> => naming to docker.io/liuqinghui/gin-hello:v1
2.3 推送镜像
这里将镜像推送到https://hub.docker.com/
# 先登陆
$ docker login
Authenticating with existing credentials...
Login Succeeded
# 推送
$ docker push liuqinghui/gin-hello:v1
The push refers to repository [docker.io/liuqinghui/gin-hello]
1320a677095b: Pushed
63493a9ab2d4: Mounted from library/alpine
v1: digest: sha256:25ae6ce90d8810450b9f84d89fe7499f6ce24167ec47b4fbd8aeb79a02632fa5 size: 739

3. 部署到Kubernetes
3.1 编写yaml
文件:gin-hello.yaml
apiVersion: apps/v1 # 配置格式版本
kind: Deployment #资源类型,Deployment
metadata:
name: gin-hello-deploy #Deployment 的名称
spec:
replicas: 2 # 副本数量
selector: #标签选择器,
matchLabels: #选择包含标签app:gin_hello_pod的资源
app: gin_hello_pod
template: #Pod信息
metadata:
labels:
app: gin_hello_pod
spec:
containers:
- name: gin-hello
image: docker.io/liuqinghui/gin-hello:v1 # 我们构建的镜像
---
apiVersion: v1
kind: Service
metadata:
name: gin-hello-svc
spec:
type: NodePort
selector:
app: gin_hello_pod
ports:
- name: http
protocol: TCP
port: 8080 # ClusterIP监听的端口
targetPort: 80 # Pod监听的端口
nodePort: 30001
deployment、service等多个资源类型的配置可以写到一个文件,使用
---
间隔开即可。
3.2 部署
$ kubectl apply -f gin-hello.yaml
deployment.apps/gin-hello-deploy created
service/gin-hello-svc created
问题
The Service "gin-hello-svc" is invalid: spec.ports[0].nodePort: Invalid value: 30000: provided port is already allocated
解决:此问题代表30000端口已经分配了,可以查看kubectl get pod,service,svc -A
查看,修改nodePort
的值即可
3.3 验证
# 查看 deployment
$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
gin-hello-deploy 2/2 2 2 6m
# 查看pod
$ kubectl get pod
NAME READY STATUS RESTARTS AGE NODE
gin-hello-deploy-86f8cfb7b9-29lmg 1/1 Running 0 6m38s node1
gin-hello-deploy-86f8cfb7b9-4vcj6 1/1 Running 0 6m38s node2
# 查看 service
$ kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
gin-hello-svc NodePort 10.102.86.126 <none> 8080:30001/TCP 9m17s

4. 服务升级
4.1 修改yaml
通过修改镜像版本,来实现服务升级,为了便于观察,把副本数量调大
修改文件 gin-hello.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: gin-hello-deploy
spec:
replicas: 3 # 调大副本数量
selector:
matchLabels:
app: gin_hello_pod
template:
metadata:
labels:
app: gin_hello_pod
spec:
containers:
- name: gin-hello
image: docker.io/liuqinghui/gin-hello:v2 # 升级镜像为v2
---
...
4.2 发布
# 依旧通过 kubectl apply 发布
$ kubectl apply -f gin-hello.yaml
deployment.apps/gin-hello-deploy configured
service/gin-hello-svc unchanged
$ kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
gin-hello-deploy-86f8cfb7b9-29lmg 1/1 Running 0 12m 10.244.166.162 node1
gin-hello-deploy-86f8cfb7b9-4vcj6 1/1 Running 0 12m 10.244.104.11 node2
gin-hello-deploy-86f8cfb7b9-srgz4 1/1 Running 0 23s 10.244.104.12 node2
4.3 访问验证
10.110.146.17 为service的ip
$ curl 10.110.146.17:8080
{"hostName":"gin-hello-deploy-6bb7456d9b-lk4tw","time":"2024-05-14 07:55:49","version":"v2"}
$ curl 10.110.146.17:8080
{"hostName":"gin-hello-deploy-6bb7456d9b-l99cb","time":"2024-05-14 07:55:53","version":"v2"}
$ curl 10.110.146.17:8080
{"hostName":"gin-hello-deploy-6bb7456d9b-p7rj4","time":"2024-05-14 07:55:55","version":"v2"}
5. 服务回滚
5.1 准备yaml
文件
为了方便操作和后续回滚,编写多个配置文件,具体版本对应如下:
配置文件 | 镜像版本 |
---|---|
gin-hello-v1.yaml | gin-hello:v1 |
gin-hello-v2.yaml | gin-hello:v2 |
gin-hello-v3.yaml | gin-hello:v3 |
5.2 保存发布记录
kubectl apply
每次更新应用时,Kubernetes
都会记录下当前的配置,保存为一个revision
(版次),这样就可以回滚到某个特定revision
。发布时,携带参数 --record,可以将当前命令记录到revision记录中。
为了方便后面回滚,按照顺序都发布下。
# 发布 v1
$ kubectl apply -f gin-hello-v1.yaml --record
# 验证 v1
$ curl 10.110.146.17:8080
{"hostName":"gin-hello-deploy-86f8cfb7b9-qmvfs","time":"2024-05-14 08:11:32","version":"v1"}
# 发布 v2
$ kubectl apply -f gin-hello-v2.yaml --record
# 验证 v2
$ curl 10.110.146.17:8080
{"hostName":"gin-hello-deploy-6bb7456d9b-j2rmg","time":"2024-05-14 08:12:04","version":"v2"}
# 发布 v3
$ kubectl apply -f gin-hello-v3.yaml --record
# 验证 v3
$ curl 10.110.146.17:8080
{"hostName":"gin-hello-deploy-69c4fd68ff-c48kf","time":"2024-05-14 08:13:05","version":"v3"}
5.3 查看发布历史
通过
kubectl rollout history deployment 名称
查看revison
历史记录
# 查看发布历史
$ kubectl rollout history deployment gin-hello-deploy
deployment.apps/gin-hello-deploy
REVISION CHANGE-CAUSE
3 kubectl apply --filename=gin-hello-v1.yaml --record=true
4 kubectl apply --filename=gin-hello-v2.yaml --record=true
5 kubectl apply --filename=gin-hello-v3.yaml --record=true
5.4 回滚指定版本
通过执行命令
kubectl rollout undo deployment 名称 --to-revision=?
,其中--to-revision=
的值,就历史记录中REVISION
,所对应的值。
# 查看当前所在版本
$ curl 10.105.12.214:8080
{"hostName":"gin-hello-deploy-69c4fd68ff-4ppfh","time":"2022-08-10 11:06:17","version":"v3"}
# 回滚到v1,而v1对应的REVISION = 3
$ kubectl rollout undo deployment gin-hello-deploy --to-revision=3
deployment.apps/gin-hello-deploy rolled back
# 验证结果
$ curl 10.105.12.214:8080
{"hostName":"gin-hello-deploy-86f8cfb7b9-tbj78","time":"2024-05-14 08:16:39","version":"v1"}
网友评论