Kubernetes 入門實踐--部署執行 Go 專案

KevinYan發表於2020-07-06

介紹

今天的文章我準備和大家一起一步步地嘗試做一個Go應用程式的Docker映象,把它部署到Minikuebe上執行。今天的文章不需要什麼基礎,Kubernetes的新手朋友們先一起上車學起來。

應用程式程式碼

我們用Go寫一個簡單的HTTP ServerServer偵聽3000埠包含"/""/health_check"兩個路由,今天文章的關注點不在怎麼用Go開發程式所以都是Hello World級別的程式碼,就不更多解釋了,直接看程式碼吧。

package main

import (
    "fmt"
    "net/http"
)

func index(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "<h1>Hello World</h1>")
}

func check(w http.ResponseWriter, r *http.Request) {
    fmt.Fprintf(w, "<h1>Health check</h1>")
}

func main() {
    http.HandleFunc("/", index)
    http.HandleFunc("/health_check", check)
    fmt.Println("Server starting...")
    http.ListenAndServe(":3000", nil)
}

製作程式映象

接下來開始製作包含應用程式程式碼的Docker映象。關於docker相關的使用方法和如何編寫Dockerfile,可以在公眾號裡回覆關鍵字docker獲取完整的參考筆記。

dockerfile

在應用程式的根目錄新增名為Dockerfile的檔案,在檔案裡新增如下指令:

FROM golang:alpine
RUN mkdir /app
COPY . /app
WORKDIR /app
RUN go build -o main . 
CMD ["/app/main"]

build 映象

Dockerfile所在的目錄下執行docker build構建映象

➜  docker build -t go-app-img .

docker會依據Dockerfile裡的指令構建映象,整個構建的過程類似下面:

➜  docker build -t go-app-img .
Sending build context to Docker daemon  9.216kB
Step 1/6 : FROM golang:alpine
alpine: Pulling from library/golang
df20fa9351a1: Pull complete 
ed8968b2872e: Pull complete 
a92cc7c5fd73: Pull complete 
9e0cccf56431: Pull complete 
cbe0275821fc: Pull complete 
Digest: sha256:6042b9cfb4eb303f3bdcbfeaba79b45130d170939318de85ac5b9508cb6f0f7e
Status: Downloaded newer image for golang:alpine
 ---> 3289bf11c284
Step 2/6 : RUN mkdir /app
 ---> Running in b34dccb1f3de
Removing intermediate container b34dccb1f3de
 ---> 1fa1a1c21aa2
Step 3/6 : COPY . /app
 ---> 815660da9d1a
Step 4/6 : WORKDIR /app
 ---> Running in 49dc25fe6bb7
Removing intermediate container 49dc25fe6bb7
 ---> 14776702ccf7
Step 5/6 : RUN go build -o main .
 ---> Running in 3bd4dc1e2bf6
Removing intermediate container 3bd4dc1e2bf6
 ---> 59aa7f96ee42
Step 6/6 : CMD ["/app/main"]
 ---> Running in 6309f604d662
Removing intermediate container 6309f604d662
 ---> 023baffdcb28
Successfully built 023baffdcb28
Successfully tagged go-app-img:latest

驗證映象

這一步其實可以省略,不過為了確保製作的映象是沒有問題,我們通過docker run命令用這個映象執行容器驗證一下。

➜ docker run -d -p 3333:3000 --rm --name go-app-container go-app-img

在這裡,我們指示docker從映象go-app-img執行容器,將主機埠3333繫結到容器的內部埠3000,以後臺模式(-d)執行容器,給此容器命名為go-app-container,並在容器結束執行後自動刪除容器(–rm)。

開啟瀏覽器輸入localhost:3333訪問到的頁面輸出會是:

圖片

推送映象到DockerHub

測試映象沒問題後,將映象推送到DockerHub,到時候Kubernetes在部署應用時會根據指定的映象名稱從DockerHub上拉取映象(映象源是可配置的,不一定非得是DockerHub,可以是私有映象倉庫)。

➜  docker build -t kevinyan001/kube-go-app .   
...

➜  docker push  kevinyan001/kube-go-app
...

Dockerfile重新構建映象,指定映象倉庫名。構建完成後將映象然後推送到DockerHub上。

上面倉庫名中的kevinyan001是我自己的DockerHub賬號,你們可以直接使用下面的命令拉取我的映象使用,不過還是建議每個人動手製作自己的映象。

docker pull kevinyan001/kube-go-app:latest

Kubernetes部署應用

部署應用開始需要先定義預期狀態,就是在yaml檔案裡宣告具體的Kubernetes物件的各種預期的狀態。然後讓Kubernetes建立物件,之後它會始終驅動叢集的當前狀態向預期狀態移動(比如有節點掛了,會新起節點替代掛掉的節點)。部署完應用後後我們還需要通過Service向外部暴露應用,這樣才能訪問執行在Kubernetes叢集裡的應用。

下面我們來一步步遞進地執行這三個步驟。

開始之前我們需要啟動一下Minikube

minikube start

如果你還沒有安裝可以參照《Minikube-執行在筆記本上的Kubernetes叢集》裡的安裝步驟

定義預期狀態

在部署清單檔案(deployment.yaml)中定義預期狀態

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-go-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: go-app
  template:
    metadata:
      labels:
        app: go-app
    spec:
      containers:
        - name: go-app-container
          image: kevinyan001/kube-go-app
          resources:
            limits:
              memory: "128Mi"
              cpu: "500m"
          ports:
            - containerPort: 3000

Kubernetes Deployment 物件(清單檔案的kind裡指定的)表示執行在叢集中的應用。檔案裡還指定了應用需要一個副本執行(replicas),以及執行的容器名和容器的映象、資源大小等資訊。

DeploymentKubernetes物件的一種,還有其他很多種物件分別對應Kubernetes裡的不同型別的資源。

部署應用

使用上面定義的deployment.yaml建立Deployment物件來執行Go應用程式的容器:

➜ kubectl create -f deployment.yaml
deployment.apps/my-go-app created

➜ kubectl get deployments
NAME        READY     UP-TO-DATE   AVAILABLE   AGE
my-go-app   1/1       1            1           24s

➜ kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
my-go-app-5bb8767f6d-2pdtk   1/1       Running   0          43s

暴露應用

應用部署完後還不能從外部直接訪問,需要把剛才Deployment物件執行的應用程式作為Kubernetes的一個Service對外暴露。

➜ kubectl expose deployment my-go-app --type=NodePort --name=go-app-svc --target-port=3000 
service/go-app-svc exposed

➜ kubectl get svc
NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
go-app-svc   NodePort    10.104.190.231   <none>        3000:31425/TCP   40h
kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP          6d13h

➜ minikube ip
192.168.64.4

通過kubectl get svc查詢Service可以得到主機的31425埠對映到了Kubernetes執行著應用的容器的3000埠。在瀏覽器裡使用Kubernetes叢集IP加NodePort即可訪問到Kubernetes部署的Go應用程式。

開啟瀏覽器通過192.168.64.4:31425(以自己實踐時查到的IP和埠為準)訪問應用程式定義的兩個路由的結果如下:

IndexPage

HealthCheckPage

總結

今天的文章簡單的總結了一下將應用程式部署到Kubernetes叢集的步驟,Kubernetes裡有很多種物件來代表其內部的各種資源,今天部署應用用到的Deployment就是其中的一種,kubectl會根據.yaml檔案中的配置資訊請求KubernetesapiServer建立各種物件,我們後續要做的就是繼續研究清楚這些常用到的Kubernetes物件。由於鄙人也是剛開始學習,難免有表達不精確的地方,還請見諒。

本作品採用《CC 協議》,轉載必須註明作者和本文連結

公眾號:網管叨bi叨 | Golang、PHP、Laravel、Docker等學習經驗分享

相關文章