Skip to content

Commit

Permalink
Merge pull request #34 from boostcampwm-2024/feature-be-#26
Browse files Browse the repository at this point in the history
[#26] Pod 생성 및 삭제 이벤트 발생 구독
  • Loading branch information
mintaek22 authored Jan 16, 2025
2 parents fa1ea30 + b1d6807 commit be1d8e9
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 89 deletions.
36 changes: 18 additions & 18 deletions DBManager/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 0 additions & 62 deletions DBManager/src/K8S/KubernetesService.ts

This file was deleted.

12 changes: 6 additions & 6 deletions DBManager/src/app.controller.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
import { Controller, Delete, Get, Query } from '@nestjs/common';
import { KubernetesService } from './K8S/KubernetesService';
import { Controller, Delete, Get, Param, Query } from '@nestjs/common';
import { K8SApiService } from './k8s/K8SApi.service';

@Controller()
export class AppController {
constructor(private readonly kubernetesService: KubernetesService) {}
constructor(private readonly k8SApiService: K8SApiService) {}

@Get('/pods')
async getAllPods() {
const pods = await this.kubernetesService.getAllPods();
const pods = await this.k8SApiService.getAllPods();
return pods;
}

@Get('/create-pod')
async createPod() {
const pod = await this.kubernetesService.createPod();
const pod = await this.k8SApiService.createPod();
return pod;
}

@Delete('/delete-pod')
async deletePod(@Query('podName') podName: string) {
console.log(podName);
const pod = await this.kubernetesService.deletePod(podName);
const pod = await this.k8SApiService.deletePod(podName);
return pod;
}
}
5 changes: 3 additions & 2 deletions DBManager/src/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { KubernetesService } from './K8S/KubernetesService';
import { ConfigModule } from '@nestjs/config';
import { K8SApiModule } from './k8s/K8SApi.module';

@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
}),
K8SApiModule,
],
controllers: [AppController],
providers: [KubernetesService],
providers: [],
})
export class AppModule {}
6 changes: 5 additions & 1 deletion DBManager/src/config/redis/redis.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,14 @@ export class RedisService {
return this.podConnection.hget(key, field);
}

async hsetPod(key: string, field: string, value: number): Promise<void> {
async hsetPod(key: string, field: string, value: number | string): Promise<void> {
await this.podConnection.hset(key, field, value);
}

async delPod(key: string): Promise<void> {
await this.podConnection.del(key);
}

async subscribeActiveUser(
channel: string,
onMessage: (message: string) => void,
Expand Down
10 changes: 10 additions & 0 deletions DBManager/src/k8s/K8SApi.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { Module } from '@nestjs/common';
import { K8SApiService } from './K8SApi.service';
import { RedisModule } from 'src/config/redis/redis.module';

@Module({
imports: [RedisModule],
exports: [K8SApiService],
providers: [K8SApiService],
})
export class K8SApiModule {}
98 changes: 98 additions & 0 deletions DBManager/src/k8s/K8SApi.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { Injectable, OnModuleInit } from '@nestjs/common';
import * as k8s from '@kubernetes/client-node';
import { RedisService } from 'src/config/redis/redis.service';

@Injectable()
export class K8SApiService {
private podCnt = 0;
private k8sApi;
private k8sWatch : k8s.Watch;
private namespace = 'default';

constructor(private readonly redisService: RedisService) {}

async onModuleInit() {
const kc = new k8s.KubeConfig();
kc.loadFromDefault();
this.k8sApi = kc.makeApiClient(k8s.CoreV1Api);
this.k8sWatch = new k8s.Watch(kc);
this.startWatchPod();
}

async getPodIp(podName: string): Promise<string> {
const podInfo = await this.k8sApi.readNamespacedPod(podName, this.namespace);
return podInfo.body.status.podIP || 'Pending';
}

startWatchPod() {
const path = `/api/v1/namespaces/${this.namespace}/pods`;
const queryParams = {
allowWatchBookmarks: true,
labelSelector: 'app=mysql',
};
const handlePodEvent = async (type : String, apiObj: any, watchObj: any) => {
const podName = watchObj.object.metadata.name;
const podStatus = watchObj.object.status;
const curPodIp = await this.redisService.hgetPod(podName, 'podIp');

if (type === 'ADDED') {
await this.redisService.hsetPod(podName, 'activeUser', 0);
await this.redisService.hsetPod(podName, 'podIp', podStatus.podIp || '');
} else if (type === 'MODIFIED' && podStatus.podIP && curPodIp == '') {
const podIp = podStatus.podIP;
await this.redisService.hsetPod(podName, 'podIp', podIp);
} else if (type === 'DELETED') {
await this.redisService.delPod(podName);
}
};

this.k8sWatch.watch(path, queryParams, handlePodEvent, err => {});
}

async createPod() {
const mysqlPod = {
metadata: {
generateName: 'mysql-',
labels: {
app: 'mysql',
},
},
spec: {
containers: [
{
name: 'mysql',
image: 'mysql',
},
],
},
};

const createdPod = await this.k8sApi.createNamespacedPod(this.namespace, mysqlPod);
return createdPod;
}

async deletePod(podName: string) {
const deletePod = await this.k8sApi.deleteNamespacedPod(podName, this.namespace);
return deletePod;
}

async getAllPods() {
const podList = await this.k8sApi.listNamespacedPod(this.namespace);
const podResult = {};

for (const pod of podList.body.items) {
const podName = pod.metadata.name;
console.log(podName);

const podInfo = await this.k8sApi.readNamespacedPod(podName, this.namespace);
const podIp = podInfo.body.status.podIP;
console.log(podIp);

podResult[podName] = podIp;
}
return {
podCnt : Object.keys(podResult).length,
podResult,
};
}
}

0 comments on commit be1d8e9

Please sign in to comment.