golang服务部署到kubernetes的示例

本篇主要讲解如何将golang的服务部署到kubernetes集群里,附带相关的golang的demo和yml文件内容。纯新手入门方式,生产服务需要完整的CI/CD流程来支持。

golang服务代码

这里简单写一个k8s-demo的服务,提供两个接口ping和version接口,main.go文件代码如下:

package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func statusOKHandler(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{"status": "success"})
}

func versionHandler(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{"version": "v1.0"})
}

func main() {
	router := gin.New()
	router.Use(gin.Recovery())
	router.GET("/ping", statusOKHandler)
	router.GET("/version", versionHandler)
	router.Run(":8080")
}

构建命令:CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o k8s-demo main.go

Dockerfile文件

这里只提供最基础的demo写法,如果有额外的需求在dockerfile文件内补充就行,Dockerfile文件内容如下:

FROM alpine
ADD k8s-demo /data/app/
WORKDIR /data/app/
CMD ["/bin/bash","-c","./k8s-demo"]

CI构建脚本

写一个build.sh,用于编译二进制文件,然后进行docker镜像打包和推送进行到镜像仓库:

#!/bin/bash

set -e

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o k8s-demo main.go
docker build -t www.5bug.wang/docker/k8s-demo:1.0 .
docker push www.5bug.wang/docker/k8s-demo:1.0

执行build.sh脚本文件即可,请确保此步骤成功将镜像推送到你的镜像仓库里。

kubernetes部署

准备创建deployment的yaml文件

kubernetes版本1.18,我这里使用yaml文件创建deployment来部署k8s-demo服务到k8s集群里,k8s-demo.yaml文件内容如下:

---
    apiVersion: apps/v1  #必须 指定api版本,此值必须在kubectl api-versions里
    kind: Deployment  #必须 指定资源类型
    metadata:  #必须 元数据
      name: k8s-demo  #必须 符合RFC1035规范的名称
      namespace: default  #可选 指定命名空间,默认为default
      labels:  #可选 标签选择器,一般用于selector
        app: k8s-demo  #label定义
    spec:  #必须 资源详细
      selector:  #可选 选择器
        matchLabels: 
          app: k8s-demo
      replicas: 4  #可选 创建pod的副本数量
      revisionHistoryLimit: 10  #可选 历史版本最多保留的版本数量
      minReadySeconds: 5 #可选 Pod对象启动后多长时间认为就绪,单位秒
      strategy:  # 更新策略
        type: RollingUpdate # 滚动更新
        rollingUpdate:
          maxSurge: 1  #可选 可以超过期望值的最大pod数 默认为25%,maxSurge、maxUnavailable不能同时为0,都可以设置为数字或百分比
          maxUnavailable: 1  #可选 在更新时最大不可用的pod数量 默认为25% 
      template:
        metadata:
          labels:
            app: k8s-demo
        spec:
          restartPolicy: Always  #表示自动重启
          containers:
          - image: www.5bug.wang/docker/k8s-demo:1.0  #容器使用的镜像地址
            imagePullPolicy: IfNotPresent  #镜像拉取策略Always、Never、IfNotPresent
            command: ["/bin/bash","-c","./k8s-demo"]  #启动命令,需要前台运行命令
            # env:  #指定环境变量
            #   - name: app_env
            #     value: qa
            name: k8s-demo
            ports:
            - containerPort: 8080  #容器端口
              protocol: TCP
            resources:  #定义资源数据
              limits:
                cpu: 100m
                memory: 100Mi
              requests:
                cpu: 50m
                memory: 50Mi
            livenessProbe:  #健康检查设置
              tcpSocket:
                port: 8080  #服务端口
              initialDelaySeconds: 10  #第一次检测在容器启动后多长时间后开始
              timeoutSeconds: 3  #检测的超时时间 
            readinessProbe:  #探针
              httpGet:
                path: /ping  #健康检查接口定义
                port: 8080  #健康检查端口
              initialDelaySeconds: 10
              timeoutSeconds: 2
            volumeMounts:  #挂载配置
              - name: logs  #挂载设备的名字,与volumes[*].name 需要对应    
                mountPath: /data/logs  #挂载到容器的/data/logs下
                readOnly: false  
          volumes:  #定义一组挂载设备  
            - name: logs  #定义一个挂载设备的名字  
              hostPath:
                path: /data/logs  #挂载设备类型为hostPath,路径为宿主机下的/data/logs

---
    apiVersion: v1
    kind: Service  #定义Service
    metadata:
      name: k8s-demo-svc
      namespace: default
      labels:
        app: k8s-demo
    spec:
      ports:
        - name: api
          port: 8080
          protocol: TCP
          targetPort: 8080
      selector:
        app: k8s-demo
    
---
    apiVersion: extensions/v1beta1
    kind: Ingress  #定义ingress
    metadata:
      name: k8s-demo-ingress
      namespace: default
    spec:
      rules:
      - host: k8s-demo.local  #ingress名称
        http:
          paths:
          - path: /
            backend:
              serviceName: k8s-demo-svc
              servicePort: api

此yaml文件里主要定义了三种资源:deployment、service、ingress,都配置在默认的namespace里。

k8s部署

在已经搭建好k8s环境的master节点里使用kubectl命令来执行部署,命令如下:

kubectl apply -f k8s-demo.yaml

执行效果如下:

1586531413176.jpg

稍等会通过通过查询pods列表的命令:kubectl get pods 来查看pod运行状态,如下图:

image.png

配置外部访问

k8s的服务支持外部访问的方式有好几种,我这里我采用了ingress的方式,由于是本地使用,所以这里需要绑下host文件,通过查询ingress的命令查询ingress列表可以得知host绑什么IP地址,如下::

5bug.wang-MacBook:~/codes/projects/k8s-demo$ kubectl get ingress
NAME               CLASS    HOSTS            ADDRESS          PORTS   AGE
k8s-demo-ingress   <none>   k8s-demo.local   192.168.99.103   80      7m26s

修改/etc/hosts文件,增加:192.168.99.103  k8s-demo.local即可。

浏览器里访问:http://k8s-demo.local/ping即可看到ping接口的返回值了,到这里k8s-demo成功部署到k8s集群里了。


分享:

扫一扫在手机阅读、分享本文