今天你接到了一份新任务,要求在 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: {{ .Release.Name }}
spec:
replicas: {{ .Values.app.replicaCount }}
selector:
matchLabels:
app: {{ .Release.Name }}
template:
metadata:
labels:
app: {{ .Release.Name }}
spec:
containers:
- name: {{ .Release.Name }}
image: {{ .Values.app.image.repo }}:{{ .Values.app.image.tag }}
ports:
- containerPort: 8080
env:
- name: MONGO_HOST
value: mongo
- name: MONGO_INITDB_ROOT_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: MONGO_INITDB_ROOT_USERNAME
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: MONGO_INITDB_ROOT_PASSWORD
这里会建立 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 部属新的元件,以及讲解环境测试的一些实用小技巧,很多细节就没有一一介绍了。
>>: 09 - Metrics - 观察系统的健康指标 (3/6) - 使用 Metricbeat 掌握 Infrastructure 的健康状态 Host 篇
前言 不管你是不是学程序的,常常都会接触到网页,常常会听到网页就是HTML、CSS和JavaScri...
不要被标题一堆名词吓到;当你用过它後,你会惊讶它的易用以及,最重要的,无缝接轨辨识人脸关键点 本文...
软件开发有个情境或许大家都不陌生: 团队可能接手外包所开发的程序,或是接手团队其他成员所写的程序继续...
为什麽要建立品牌的搜寻广告活动 让使用者在搜索您的商家时可以直接进到您的商家官网,避免当使用者在搜索...
范例档案 GitHub Repo: https://github.com/kaochenlong/...