1. 项目信息 1.1 目录结构 $ tree go-container go-container ├── Dockerfile ├── go.mod ├── go.sum └── main.go
1.2 主代码信息 main.go
代码如下:
package mainimport ( "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
FROM golang:1.18 as builderADD . /workspace WORKDIR /workspace 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 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 metadata: name: gin-hello-deploy spec: replicas: 2 selector: matchLabels: app: gin_hello_pod template: 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 targetPort: 80 nodePort: 30000
deployment、service等多个资源类型的配置可以写到一个文件,使用---
间隔开即可。
3.2 部署 $ kubectl apply -f gin-hello.yaml deployment.apps/gin-hello-deploy created service/gin-hello-svc created
3.3 验证 $ kubectl get deployment NAME READY UP-TO-DATE AVAILABLE AGE gin-hello-deploy 2/2 2 2 13m $ kubectl get pod NAME READY STATUS RESTARTS AGE gin-hello-deploy-86f8cfb7b9-bkmhv 1/1 Running 0 14m gin-hello-deploy-86f8cfb7b9-dwgwk 1/1 Running 0 14m $ kubectl get service NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE gin-hello-svc NodePort 10.105.12.214 <none> 8080:30000/TCP 14m
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 --- ...
4.2 发布 $ kubectl apply -f gin-hello.yaml deployment.apps/gin-hello-deploy configured service/gin-hello-svc unchanged
4.3 访问验证 $ curl 10.105.12.214:8080 {"hostName" :"gin-hello-deploy-6bb7456d9b-bk9mf" ,"time" :"2022-08-10 09:12:04" ,"version" :"v2" } $ curl 10.105.12.214:8080 {"hostName" :"gin-hello-deploy-6bb7456d9b-vqds9" ,"time" :"2022-08-10 09:12:33" ,"version" :"v2" } $ curl 10.105.12.214:8080 {"hostName" :"gin-hello-deploy-6bb7456d9b-2j9p2" ,"time" :"2022-08-10 09:12:34" ,"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记录中。
为了方便后面回滚,按照顺序都发布下。
$ kubectl apply -f gin-hello-v1.yaml --record $ curl 10.105.12.214:8080 {"hostName" :"gin-hello-deploy-86f8cfb7b9-4z8kj" ,"time" :"2022-08-10 11:03:45" ,"version" :"v1" } $ kubectl apply -f gin-hello-v2.yaml --record $ curl 10.105.12.214:8080 {"hostName" :"gin-hello-deploy-6bb7456d9b-p8hw2" ,"time" :"2022-08-10 11:04:19" ,"version" :"v2" } $ kubectl apply -f gin-hello-v3.yaml --record $ curl 10.105.12.214:8080 {"hostName" :"gin-hello-deploy-69c4fd68ff-4ppfh" ,"time" :"2022-08-10 11:06:17" ,"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" } $ 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-r2jvr" ,"time" :"2022-08-10 11:14:31" ,"version" :"v1" }