介紹
今天的文章我準備和大家一起一步步地嘗試做一個Go
應用程式的Docker
映象,把它部署到Minikuebe
上執行。今天的文章不需要什麼基礎,Kubernetes
的新手朋友們先一起上車學起來。
應用程式程式碼
我們用Go
寫一個簡單的HTTP Server
,Server
偵聽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
),以及執行的容器名和容器的映象、資源大小等資訊。
Deployment
是Kubernetes
物件的一種,還有其他很多種物件分別對應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和埠為準)訪問應用程式定義的兩個路由的結果如下:
總結
今天的文章簡單的總結了一下將應用程式部署到Kubernetes
叢集的步驟,Kubernetes
裡有很多種物件來代表其內部的各種資源,今天部署應用用到的Deployment
就是其中的一種,kubectl
會根據.yaml
檔案中的配置資訊請求Kubernetes
的apiServer
建立各種物件,我們後續要做的就是繼續研究清楚這些常用到的Kubernetes
物件。由於鄙人也是剛開始學習,難免有表達不精確的地方,還請見諒。
本作品採用《CC 協議》,轉載必須註明作者和本文連結