Kubernetes客户端Javascript输出

yftpprvb  于 2023-03-29  发布在  Kubernetes
关注(0)|答案(1)|浏览(122)

我正在做一个在线编译器。我有一个接收post请求的pod。这个pod将继续创建一个作业并传递代码,以便它可以被编译并处理输出。
到目前为止,我已经设法通过kubernetes-client for javascript创建了job,因为我的应用程序是基于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);
        }
    }
}

这是用于图像的停靠文件。

FROM node:alpine

WORKDIR /app
RUN echo "console.log('this is a line')" > file.js

我不知道如何将job的输出传递回我的nodejs应用程序pod。我在想使用一个PV,Job和Pod都可以访问,并让Job将输出写入共享PV中的文件。Pod检查Job完成状态,然后继续从PV文件读取输出?
这是正确的方法还是有其他更好的方法?据我所知,我们只能得到作业的日志,我不认为这是正确的方法来过滤和找到正确的输出或stdout / stderr。

h7wcgrx3

h7wcgrx31#

这是我从作业中获取stdout的方法。它等待作业完成。然后读取日志。

// 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);
            })
        });
    })

}

相关问题