今天你接到了一份新任務,要求在 Kubernetes 的 NodeJS 應用增添一個 MongoDB ,身為維運人員的你要怎麼做 ?
在之前的章節我們已經將 NodeJS 應用包在 Helm Chart 裡面,內容如下
webapp
├── charts
├── Chart.yaml
├── templates
│ ├── deployment.yaml
│ ├── service.yaml
│ └── tests
└── values.yaml
若需要對 Kubernetes 應用增加新功能,可以遵循以下流程
萬事起頭難,一開始要先想好需要創建哪些 yaml 檔案,可以簡單畫個架構圖幫助思考。
目標很簡單,就是創建讓 App 可以 Access 到的 Database ,總共有以下 yaml 檔案需要創建
db-service
clusterIP
使內部可以訪問該服務,而外部則無法存取db-pvc
db-secret
db-deployment
進入 Cloud Shell 網站
點擊倒三角形->點選專案的 PROJECT_ID
,開啟專案 Terminal
templates
資料夾,建立所需 yaml 檔案cd ~/webapp/templates
touch db-deployment.yaml db-pvc.yaml db-secret.yaml db-service.yaml
左上 Explorer -> Open Folder -> 選擇 webapp 資料夾 -> Open
db-pvc.yaml
檔案並貼上以下內容apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: db-pv-claim
labels:
app: mongo
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
PVC 只是對存儲空間提出請求,使用上還需要在 deployment 裡設定 mount 的方式。
secret.yaml
檔案並貼上以下內容apiVersion: v1
kind: Secret
metadata:
name: db-secret
labels:
app: mongo
data:
MONGO_INITDB_ROOT_USERNAME: ZGJ1c2Vy
MONGO_INITDB_ROOT_PASSWORD: ZGJwYXNzd2Q=
secret 對變數要求 base64 的編碼,上述的亂碼是由
echo -n "string" | base64
所生成的
db-deployment.yaml
檔案並貼上以下內容apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo
labels:
app: mongo
spec:
selector:
matchLabels:
app: mongo
replicas: 1
template:
metadata:
labels:
app: mongo
spec:
containers:
- image: mongo:latest
name: mongo
ports:
- containerPort: 27017
name: mongo
volumeMounts:
- name: mongo-persistent-storage
mountPath: /data/db
envFrom:
- secretRef:
name: db-secret
volumes:
- name: mongo-persistent-storage
persistentVolumeClaim:
claimName: db-pv-claim
這裡會建立 PV ,並將 /data/db 路徑 Mount 到 PV 上,並且將 Secret 作為環境變數來設定 DB 的帳密。
deployment.yaml
並在最後新增以下內容 envFrom:
- secretRef:
name: db-secret
將 Secret 作為環境變數,讓 Application 有 DB 的權限。
db-service.yaml
檔案並貼上以下內容apiVersion: v1
kind: Service
metadata:
labels:
app: mongo
name: mongo
spec:
clusterIP: None
ports:
- port: 27017
targetPort: 27017
selector:
app: mongo
這裡的 clusterIP 設為 None 是希望 App 能以 Domain Name 去連線
需要的 yaml 檔案都已建置完成,新的 Helm Chart 目錄內容如下
webapp/
├── charts
├── Chart.yaml
├── templates
│ ├── db-deployment.yaml
│ ├── db-pvc.yaml
│ ├── db-secret.yaml
│ ├── db-service.yaml
│ ├── deployment.yaml
│ ├── service.yaml
│ └── tests
├── values.production.yaml
├── values.stage.yaml
└── values.yaml
所需的 yaml 檔案都已建置完成,就可以部屬到測試環境檢查。
cd ~/webapp
helm install webapp-dev .
若之前已經安裝好了可以下
helm upgrade webapp-dev .
來更新環境
(輸出結果)
NAME: webapp-dev
LAST DEPLOYED: Fri Sep 24 13:54:55 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None
kubectl get all -l app=mongo
(輸出結果)
NAME READY STATUS RESTARTS AGE
pod/mongo-7f6477fbcb-xfmwd 1/1 Running 0 43s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/mongo ClusterIP None <none> 27017/TCP 46s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/mongo 1/1 1 1 46s
NAME DESIRED CURRENT READY AGE
replicaset.apps/mongo-7f6477fbcb 1 1 1 44s
看到 Database 成功運行先別高興太早,還需要測試 App 是否有權限 Access 到 DB。
kubectl get pods
(輸出結果)
NAME READY STATUS RESTARTS AGE
mongo-7f6477fbcb-xfmwd 1/1 Running 0 9m13s
webapp-dev-7744f58bf6-hjjdv 1/1 Running 0 9m13s
webapp-dev-7744f58bf6-k25dk 1/1 Running 0 9m13s
webapp-dev-7744f58bf6-zbnfx 1/1 Running 0 9m13s
再來我們下一個特殊的指令,使用 kubectl exec -it <pod name> -- /bin/sh
進入到容器內部,就能直接從內部測試。
<pod name>
改成其中一個 webapp pod 的名稱kubectl exec -it <pod name> -- /bin/sh
看到
/usr/src/app #
就成功進入到容器內部了。
可以先 ping 看看網路有沒有通,這裡要 ping 的是 db-Service 的名稱( mongo )
ping mongo -c 3
(輸出結果)
PING mongo (10.0.5.6): 56 data bytes
64 bytes from 10.0.5.6: seq=0 ttl=62 time=0.237 ms
64 bytes from 10.0.5.6: seq=1 ttl=62 time=0.220 ms
64 bytes from 10.0.5.6: seq=2 ttl=62 time=0.231 ms
在容器裡面是使用 NodeJS 的環境 ,可以使用 mongoose
來測試連線。
npm install mongoose
test.js
程式cat > test.js <<EOF
const mongoose = require('mongoose');
const DATABASEURL = "mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@${MONGO_HOST}:27017/test?authSource=admin"
mongoose.connect(DATABASEURL, {useNewUrlParser: true, useUnifiedTopology: true})
.then(()=> {
console.log("CONNECTION SUCCESS!!");
})
.catch(err => {
console.log("ERROR");
console.log(err);
})
EOF
這裡是測試是否能用環境變數裡的帳密連線到 mongo 裡面
node test.js
(輸出結果)
CONNECTION SUCCESS!!
成功的連線到 mongoDB !!
Ctrl + c
退出程式今天以趕火車的速度講解完如何在 Helm Chart 部屬新的元件,以及講解環境測試的一些實用小技巧,很多細節就沒有一一介紹了。