客户端 Javascript 输出"/>
Kubernetes 客户端 Javascript 输出
我正在制作一个在线编译器。我有一个 pod 可以接收带有代码的发布请求。该 pod 将继续创建作业并传递代码,以便对其进行编译和处理输出。
截至目前,我已经设法通过 kubernetes-client 为 javascript 创建工作,因为我的应用程序是基于 nodejs 的。这就是我现在正在做的更像是模型。
收到请求并继续启动作业的文件。
import express, {Request, Response} from 'express';
import {SubmissionCreatedPublisher} from '../events/publishers/submission-created-publisher';
import {natsWrapper} from '../nats-wrapper';
import {createCompilerJob} from "../jobs/create";
const router = express.Router();
router.post('/api/submission', async (req: Request, res: Response) => {
const {code} = req.body;
res.status(200).send(code);
await new SubmissionCreatedPublisher(natsWrapper.client).publish({
code: code
})
const compilerJob = new createCompilerJob;
compilerJob.create(code);
})
export {router as createRouter};
创建工作的文件。看看这里,现在我只创建了一个 docker 图像并添加了 file.js,它有简单的
console.log('this is string')
行,因为我正在测试它。我知道我需要将 code
变量传递给命令行,以便它可以将代码写入 .js 文件并执行它。
const k8s = require('@kubernetes/client-node');
export class createCompilerJob {
protected kubeConfig: any;
constructor() {
this.kubeConfig = new k8s.KubeConfig();
}
create(input:string) {
this.kubeConfig.loadFromCluster();
const batchV1Api = this.kubeConfig.makeApiClient(k8s.BatchV1Api);
try {
batchV1Api.createNamespacedJob('default', {
apiVersion: 'batch/v1',
kind: 'Job',
metadata: {
name: 'compiler-job'
},
spec: {
ttlSecondsAfterFinished: 20,
template: {
metadata: {
name: 'compiler-job'
},
spec: {
containers: [{
image: 'woofboy/compiler',
name: 'compiler',
command: ["node", "file.js"]
}],
restartPolicy: "OnFailure"
}
}
}
}).catch((e: any) => console.log(e));
} catch (error) {
console.log(error);
}
}
}
这是用于图像的 Dockerfile。
FROM node:alpine
WORKDIR /app
RUN echo "console.log('this is a line')" > file.js
我不知道如何将作业的输出传回我的 nodejs 应用程序 pod。我正在考虑使用 Job 和 Pod 都可以访问的 PV,并让 Job 将输出写入共享 PV 中的文件。 Pod 检查 Job 完成状态然后继续从 PV 文件读取输出?
这是正确的方法还是有其他更好的方法?据我所知,我们只能获取 Job 的日志,我认为这不是过滤和找到正确输出或 stdout / stderr 的正确方法。
回答如下:这就是我得到一份工作的方式。它等到作业完成。然后阅读日志。
// launch a job and get the stdout as return
import * as k8s from '@kubernetes/client-node';
export function launchCrawler(url) {
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
const coreApi = kc.makeApiClient(k8s.CoreV1Api);
const batchApi = kc.makeApiClient(k8s.BatchV1Api);
const job = {
apiVersion: 'batch/v1',
kind: 'Job',
metadata: {
name: 'crawler-job'+(Math.random()*1000000)
},
spec: {
ttlSecondsAfterFinished: 10,
template: {
metadata: {
name: 'crawler-job-pod'
},
spec: {
containers: [{
name: 'crawler-job-container',
image: 'crawler:test',
command: ['python','main.py',url],
// env: [{
// name: 'LOGLEVEL',
// value: 'DEBUG'
// }]
}],
restartPolicy: 'Never'
}
},
backoffLimit: 0
}
};
return batchApi.createNamespacedJob('default', job)
.then((response) => {
console.log(`Job ${response.body.metadata.name} created.`);
// Wait for job to complete and get its stdout
const jobName = response.body.metadata.name;
return new Promise((resolve, reject) => {
const watch = new k8s.Watch(kc);
watch.watch(`/api/v1/namespaces/default/pods`, {}, (eventType, pod) => {
if (eventType === 'ADDED' && pod.metadata.labels['job-name'] === jobName) {
console.log(`Job pod ${pod.metadata.name} added.`);
}
if (eventType === 'MODIFIED' && pod.metadata.labels['job-name'] === jobName) {
console.log(`Job pod ${pod.metadata.name} status: ${pod.status.phase}.`);
if (pod.status.phase === 'Succeeded') {
const containerName = pod.spec.containers[0].name;
const containerLogsRequest = coreApi.readNamespacedPodLog(
pod.metadata.name,
'default',
containerName
);
containerLogsRequest.then((response) => {
resolve(response.body);
}).catch((error) => {
reject(error);
});
} else if (pod.status.phase === 'Failed') {
reject(`Job failed. Pod ${pod.metadata.name} status: ${pod.status.phase}.`);
}
}
}, (error) => {
reject(error);
})
});
})
}
更多推荐
Kubernetes 客户端 Javascript 输出
发布评论