Hand in hand to teach you how to write Kubernetes'golang service

Links to the original text: https://www.qikqiak.com/post/write-kubernets-golang-service-step-by-step/

We've talked a lot about the operation of kubernetes itself, but we haven't talked about how to write a complete kubernetes application. In this article, we will introduce how to write a kubernetes golang service step by step.

golang

For the installation and configuration of golang, we will not elaborate here, because this is not our focus, I believe you can complete this step independently.

One of the more exciting things is that now users in China can visit golang website without ladders, and we can visit it freely. https://golang.google.cn/ Website.

Create a new project folder goappk8s, and then create a new src directory under that directory

$ mkdir goappk8s && cd goappk8s
$ mkdir src

Create a new GOPATH script in the goappk8s directory: (setup-gopath.sh)

#!/bin/bash
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
export GOPATH="$DIR"

Then we execute the script above and set GOPATH to the current project directory:

$ source setup-gopath.sh
$ echo $GOPATH
/Users/ych/devs/workspace/yidianzhishi/goappk8s

We can see that GOPATH has been set to the current project root directory. Then add the golang code under the src directory:

$ mkdir -p github.com/cnych/goappk8s && cd github.com/cnych/goappk8s
$ touch main.go

We add a simplest golang service that provides a ping interface:

package main

import (
    "github.com/gin-gonic/gin"
    "net/http"
)

func main() {
    router := gin.Default()
    router.GET("/ping", func(c *gin.Context) {
        c.String(http.StatusOK, "PONG")
    })
    router.Run(":8080")
}

We can see that the above service relies on a third-party package github.com/gin-gonic/gin. You can download the dependency package manually and put it under GOPATH. In order to use govendor for management, of course, you can use other package management tools, such as dep, glide and so on. Do the following under the github.com/cnych/goappk8s directory:

$ govendor init
$ govendor fetch github.com/gin-gonic/gin

Note that the top bags need to be pulled out of some of the wall bags.

Then we switch to the project root directory, which is the path of GOPATH, and execute the following commands:

$ go install github.com/cnych/goappk8s && ./bin/goappk8s
[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:   export GIN_MODE=release
 - using code:  gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /ping                     --> main.main.func1 (3 handlers)
[GIN-debug] Listening and serving HTTP on :8080

We can see that our golang service is running, and then we open the link in our browser. http://127.0.0.1:8080/ping You can see that PONG is printed on the page, which proves that our service has been started properly.

Docker

According to the previous article Multi-stage Construction of Docker We can easily write a Docker file for the golang service above: (in the same directory as main.go)

FROM golang AS build-env
ADD . /go/src/app
WORKDIR /go/src/app
RUN go get -u -v github.com/kardianos/govendor
RUN govendor sync
RUN GOOS=linux GOARCH=386 go build -v -o /go/src/app/app-server

FROM alpine
RUN apk add -U tzdata
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime
COPY --from=build-env /go/src/app/app-server /usr/local/bin/app-server
EXPOSE 8080
CMD [ "app-server" ]

Then build the Docker image:

$ docker build -t cnych/goappk8s:v1.0.0 .
.......(which is)
Successfully built 00751f94d8a9
Successfully tagged cnych/goappk8s:v1.0.0
$ docker push cnych/goappk8s:v1.0.0

The above operation can push our local mirror cnych/goappk8s:v1.0.0 onto the public dockerhub (provided you register first, of course).

Now that we can use the above image to run a container easily, let's introduce how to deploy the service to kubernetes.

Kubernetes

Of course, first of all, you have to have a usable kubernetes environment. If you are not familiar with this part, I suggest you look at the one in front of us first. Related articles . New files under the same directory are used to describe how kubernetes are deployed: (k8s.yaml)

---
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: goapp-deploy
  namespace: kube-apps
  labels:
    k8s-app: goappk8s
spec:
  replicas: 2
  revisionHistoryLimit: 10
  minReadySeconds: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  template:
    metadata:
      labels:
        k8s-app: goappk8s
    spec:
      containers:
      - image: cnych/goappk8s:v1.0.0
        imagePullPolicy: Always
        name: goappk8s
        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

---
apiVersion: v1
kind: Service
metadata:
  name: goapp-svc
  namespace: kube-apps
  labels:
    k8s-app: goappk8s
spec:
  ports:
    - name: api
      port: 8080
      protocol: TCP
      targetPort: 8080
  selector:
    k8s-app: goappk8s

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: goapp-ingress
  namespace: kube-apps
spec:
  rules:
  - host: goappk8s.local
    http:
      paths:
      - path: /
        backend:
          serviceName: goapp-svc
          servicePort: api

In the above k8s.yaml file, we define three kinds of resources: Deployment, Service, Ingress. If you don't know much about YAML file, you can see the previous article. Creating Kubernetes Deployment Using YAML Files We set up replicas: 2 to indicate that we will run two PODs. We also define strategy's rolling strategy as Rolling Update. The resources area defines our POD's resource limitation. Health checks are set up through Liveness Probe and Readiness Probe. Then we use kubectl to execute the following commands:

$ kubectl apply -f k8s.yaml
deployment "goapp-deploy" created
service "goapp-svc" created
ingress "goapp-ingress" created

We can see that all three resources defined above have been successfully created. Then look at the resource status:

$ kubectl get deployments -n kube-apps |grep goapp
goapp-deploy     2         2         2            2           57s
$ kubectl get svc -n kube-apps |grep goapp
goapp-svc      ClusterIP   10.254.109.69    <none>        8080/TCP                         1m
$ kubectl get ingress -n kube-apps |grep goapp
goapp-ingress   goappk8s.local              80        1m
$ kubectl get pods -n kube-apps |grep goapp
goapp-deploy-84bb6979c-59qkl                             1/1       Running   0          2m
goapp-deploy-84bb6979c-mgg2r                             1/1       Running   0          2m

We can see that two POD s are already running in the kubernetes cluster, and then we can define the domain names defined in Ingress above in local / etc/hosts:

Your k8s cluster node IP goappk8s.local

Then we access the links in the browser http://goappk8s.local/ping You can see that PONG has been printed on the page.

Finally, the code is sorted out and submitted to us. github Go ahead.

Finally, we can add the continuous integration function with CI/CD, so that after we update the code, we can automatically update our kubernetes application. This part will be explained separately later.

 

The original text is reproduced from: https://www.qikqiak.com/post/write-kubernets-golang-service-step-by-step/

Keywords: Kubernetes github Docker Google

Added by Gamerz on Mon, 12 Aug 2019 07:08:00 +0300