如何测试在 kubernetes 集群上作为 pod 部署的 nodejs 应用程序?
我开发了一个 nodejs REST API,为其构建了一个 docker 镜像,现在将其作为 pod 部署在我的 kubernetes 集群上。
Dockerfile
FROM mhart/alpine-node:8
WORKDIR /home/appHome/
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD [ "npm", "start" ]
但是,我将 npm start 作为我的容器启动命令传递。
但是如何使用 npm test 测试我的 node js 应用程序并验证测试结果?
当我在本地系统中执行此操作时,我习惯在后端运行应用程序并在另一个窗口中运行
npm test
。如何在 kubernetes 集群上部署时实现相同目标!一旦成功,就删除测试部分!
下面是我的 package.json 脚本,
"scripts": {
"test": "mocha ./test/scheduledTaskTest.js",
"start": "nodemon app.js --exec babel-node --presets es2015,stage-2",
"cmd": "set NODE_ENV=devConfig&& npm start"
},
下面是部署和作业 yaml 文件。
Deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: scheduled-task-test
spec:
replicas: 1
selector:
matchLabels:
app: scheduled-task-test
template:
metadata:
labels:
app: scheduled-task-test
spec: # pod spec
containers:
- name: st-c1
image: 104466/st
imagePullPolicy: Always
env:
- name: NODE_ENV
value: devConfig
- name: st-c2
image: 104466/st
imagePullPolicy: Always
command: [ 'sh','-c','npm test && sleep 3600']'
TestJob.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: scheduled-task-test-job
labels:
purpose: test
spec:
template:
spec:
containers:
- name: st-c1
image: 104466/st
imagePullPolicy: Always
env:
- name: NODE_ENV
value: devConfig
- name: st-c2
image: 104466/st
imagePullPolicy: Always
command: [ 'sh','-c','npm test && sleep 3600']
restartPolicy: Never
Pod 状态
scheduled-task-test-7d86c87d44-q9zdv 2/2 Running 1 8m 100.96.9.87 ip-172-20-34-139.us-west-2.compute.internal
scheduled-task-test-job-gt9hx 1/2 Error 0 7m 100.96.9.88 ip-172-20-34-139.us-west-2.compute.internal
成功执行的测试用例 pod 日志(部署结果)
kubectl logs scheduled-task-test-7d86c87d44-q9zdv -c st-c2
> [email protected] test /home/appHome/ScheduledTask
> mocha ./test/scheduledTaskTest.js
Testing listTask api
✓ List all the Tasks (435ms)
Testing addTask api
✓ Add a new task (438ms)
Testing updateTask api
✓ Update task
Testing delete task api
✓ Delete task (434ms)
4 passing (1s)
测试失败日志,(以作业形式执行的容器)
kubectl logs scheduled-task-test-job-gt9hx -c st-c2
> [email protected] test /home/appHome/ScheduledTask
> mocha ./test/scheduledTaskTest.js
Testing listTask api
1) List all the Tasks
Testing addTask api
2) Add a new task
Testing updateTask api
3) Update task
Testing delete task api
4) Delete task
0 passing (61ms)
4 failing
1) Testing listTask api
List all the Tasks:
Uncaught TypeError: Cannot read property 'body' of undefined
at Request._callback (test/scheduledTaskTest.js:24:29)
at self.callback (node_modules/request/request.js:186:22)
at Request.onRequestError (node_modules/request/request.js:878:8)
at Socket.socketErrorListener (_http_client.js:387:9)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
2) Testing addTask api
Add a new task :
Uncaught TypeError: Cannot read property 'body' of undefined
at Request._callback (test/scheduledTaskTest.js:43:20)
at self.callback (node_modules/request/request.js:186:22)
at Request.onRequestError (node_modules/request/request.js:878:8)
at Socket.socketErrorListener (_http_client.js:387:9)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
3) Testing updateTask api
Update task :
Uncaught TypeError: Cannot read property 'body' of undefined
at Request._callback (test/scheduledTaskTest.js:63:20)
at self.callback (node_modules/request/request.js:186:22)
at Request.onRequestError (node_modules/request/request.js:878:8)
at Socket.socketErrorListener (_http_client.js:387:9)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
4) Testing delete task api
Delete task :
Uncaught TypeError: Cannot read property 'body' of undefined
at Request._callback (test/scheduledTaskTest.js:83:20)
at self.callback (node_modules/request/request.js:186:22)
at Request.onRequestError (node_modules/request/request.js:878:8)
at Socket.socketErrorListener (_http_client.js:387:9)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
npm ERR! Test failed. See above for more details.
描述 Pod 的日志(作为作业部署的容器)
kubectl describe pod scheduled-task-test-job-gt9hx
Name: scheduled-task-test-job-gt9hx
Namespace: default
Node: ip-172-20-34-139.us-west-2.compute.internal/172.20.34.139
Start Time: Tue, 19 Jun 2018 16:28:06 +0000
Labels: controller-uid=bf5569e5-73dd-11e8-8ede-02924b27b126
job-name=scheduled-task-test-job
Annotations: kubernetes.io/created-by={"kind":"SerializedReference","apiVersion":"v1","reference":{"kind":"Job","namespace":"default","name":"scheduled-task-test-job","uid":"bf5569e5-73dd-11e8-8ede-02924b27b126","...
kubernetes.io/limit-ranger=LimitRanger plugin set: cpu request for container st-c1; cpu request for container st-c2
Status: Running
IP: 100.96.9.88
Created By: Job/scheduled-task-test-job
Controlled By: Job/scheduled-task-test-job
Containers:
st-c1:
Container ID: docker://7fc17e717921020cec074774ccb87956979712e7de55480be6e6bd586b28ce6d
Image: 104466/st
Image ID: docker-pullable://104466/st@sha256:91414cc48e86975041c233329b1814d7c6d2b76bc839a24fa68e99f92750390f
Port: <none>
State: Running
Started: Tue, 19 Jun 2018 16:28:08 +0000
Ready: True
Restart Count: 0
Requests:
cpu: 100m
Environment:
NODE_ENV: devConfig
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-2tvsm (ro)
st-c2:
Container ID: docker://95837799d34e1e14f7718acc1dc745042b94a33f115aab11a03a25ab4a569c18
Image: 104466/st
Image ID: docker-pullable://104466/st@sha256:91414cc48e86975041c233329b1814d7c6d2b76bc839a24fa68e99f92750390f
Port: <none>
Command:
sh
-c
npm test && sleep 3600
State: Terminated
Reason: Error
Exit Code: 1
Started: Tue, 19 Jun 2018 16:28:10 +0000
Finished: Tue, 19 Jun 2018 16:28:12 +0000
Ready: False
Restart Count: 0
Requests:
cpu: 100m
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-2tvsm (ro)
Conditions:
Type Status
Initialized True
Ready False
PodScheduled True
Volumes:
default-token-2tvsm:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-2tvsm
Optional: false
QoS Class: Burstable
Node-Selectors: <none>
Tolerations: node.alpha.kubernetes.io/notReady:NoExecute for 300s
node.alpha.kubernetes.io/unreachable:NoExecute for 300s
Events: <none>
如果您只想使用 Kubernetes,那么使用作业将是最简单的方法。作业会创建一个或多个 Pod,并确保指定数量的 Pod 成功终止。随着 Pod 成功完成,作业会跟踪成功完成的情况。当达到指定数量的成功完成时,作业本身就完成了。
粗略计划:
1. 为您的应用程序创建一个作业。
您可以使用应用程序的部署作为模板。您需要更改
kind: Job
并添加
spec.containers.command: ["npm", "test"]
,最后一个将替换 Dockerfile 中定义的
CMD [ "npm", "start" ]
。以下是示例:
apiVersion: batch/v1
kind: Job
metadata:
name: npm-test-job
labels:
purpose: test
spec:
template:
spec:
containers:
- name: npm-test-job
image: <your-image>
command: ["npm", "test"]
restartPolicy: Never
2.运行作业
运行作业并等待其完成:
kubectl create -f npm-test-job
3. 检查作业状态
检查作业状态,例如:
kubectl describe jobs kubectl describe jobs | grep "Pods Statuses"
4. 运行部署
如果测试成功完成,您可以开始部署:
kubectl create -f npm-deployment
当然,您需要自动化此过程。因此,您需要开发一个脚本来实现此逻辑。
但我的建议是:最好使用 CI 工具,例如 Jenkins。它可以轻松与 Kubernetes 集成,并为此类情况提供大量功能。
只需在 deploy.yaml 的容器部分指定“command: [ “npm”, “test” ]”即可。