diff --git a/Dockerfile b/Dockerfile index 7e74b46..3ba42de 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM node:21.6.2 AS builder +FROM m.daocloud.io/docker.io/library/node:21.6.2 AS builder WORKDIR /src @@ -6,9 +6,10 @@ RUN npm install -g pnpm COPY . . +RUN pnpm config set registry https://registry.npmmirror.com RUN make build-all -FROM node:21.6.2-slim +FROM m.daocloud.io/docker.io/library/node:21.6.2-slim COPY --from=builder /src/dist/ /apps/dist/ COPY --from=builder /src/node_modules/ /apps/node_modules/ diff --git a/Makefile b/Makefile index f276fbc..0e72588 100644 --- a/Makefile +++ b/Makefile @@ -41,11 +41,11 @@ start-prod: .PHONY: build-image build-image: - docker build --platform linux/amd64 -t ${DOCKER_IMAGE}:${VERSION} . + nerdctl -nk8s.io build --platform linux/amd64 -t ${DOCKER_IMAGE}:${VERSION} . .PHONY: push-image push-image: - docker push ${DOCKER_IMAGE}:${VERSION} + nerdctl -nk8s.io push ${DOCKER_IMAGE}:${VERSION} .PHONY: release -release: build-image push-image \ No newline at end of file +release: build-image push-image diff --git a/k8s.yml b/k8s.yml new file mode 100644 index 0000000..0f39f1a --- /dev/null +++ b/k8s.yml @@ -0,0 +1,150 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + annotations: + meta.helm.sh/release-name: hami-webui + meta.helm.sh/release-namespace: kube-system + labels: + app.kubernetes.io/component: hami-webui + app.kubernetes.io/instance: hami-webui + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: hami-webui + app.kubernetes.io/version: 1.0.5 + helm.sh/chart: hami-webui-1.0.5 + name: hami-webui + namespace: kube-system + resourceVersion: '215714495' +spec: + progressDeadlineSeconds: 600 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/component: hami-webui + app.kubernetes.io/instance: hami-webui + app.kubernetes.io/name: hami-webui + strategy: + rollingUpdate: + maxSurge: 25% + maxUnavailable: 25% + type: RollingUpdate + template: + metadata: + creationTimestamp: null + labels: + app.kubernetes.io/component: hami-webui + app.kubernetes.io/instance: hami-webui + app.kubernetes.io/name: hami-webui + spec: + containers: + - args: + - /apps/dist/main + command: + - node + env: + - name: TZ + value: Asia/Shanghai + image: 'projecthami/hami-webui-fe:dev' + imagePullPolicy: IfNotPresent + name: hami-webui-fe-oss + ports: + - containerPort: 3000 + name: http + protocol: TCP + resources: + limits: + cpu: 200m + memory: 500Mi + requests: + cpu: 200m + memory: 500Mi + securityContext: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + - args: + - '--conf' + - /apps/config/config.yaml + command: + - /apps/server + env: + - name: TZ + value: Asia/Shanghai + image: 'projecthami/hami-webui-be:dev' + imagePullPolicy: IfNotPresent + name: hami-webui-be-oss + ports: + - containerPort: 8000 + name: metrics + protocol: TCP + resources: + limits: + cpu: 50m + memory: 250Mi + requests: + cpu: 50m + memory: 250Mi + securityContext: {} + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /apps/config/ + name: config + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: {} + serviceAccount: hami-webui + serviceAccountName: hami-webui + terminationGracePeriodSeconds: 30 + volumes: + - configMap: + defaultMode: 420 + name: hami-webui-config + name: config + +--- +apiVersion: v1 +kind: Service +metadata: + annotations: + meta.helm.sh/release-name: hami-webui + meta.helm.sh/release-namespace: kube-system + labels: + app.kubernetes.io/component: hami-webui + app.kubernetes.io/instance: hami-webui + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: hami-webui + app.kubernetes.io/version: 1.0.5 + helm.sh/chart: hami-webui-1.0.5 + name: hami-webui + namespace: kube-system + resourceVersion: '207243046' +spec: + clusterIP: 10.96.3.221 + clusterIPs: + - 10.96.3.221 + externalTrafficPolicy: Cluster + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: http + nodePort: 29999 + port: 3000 + protocol: TCP + targetPort: http + - name: metrics + nodePort: 5063 + port: 8000 + protocol: TCP + targetPort: metrics + selector: + app.kubernetes.io/component: hami-webui + app.kubernetes.io/instance: hami-webui + app.kubernetes.io/name: hami-webui + sessionAffinity: None + type: NodePort + + diff --git a/packages/web/projects/vgpu/api/poll.js b/packages/web/projects/vgpu/api/poll.js new file mode 100644 index 0000000..155737e --- /dev/null +++ b/packages/web/projects/vgpu/api/poll.js @@ -0,0 +1,36 @@ +import request from '@/utils/request'; + +const apiPrefix = '/api/vgpu'; + + +class pollApi { + getPollList(params) { + return request({ + url: apiPrefix + '/v1/resource/pool/list', + method: 'GET', + params, + }); + } + + // getNodes(data) { + // return request({ + // url: apiPrefix + '/v1/nodes', + // method: 'POST', + // data, + // }); + // } + + // getNodeDetail(params) { + // return request({ + // url: apiPrefix + '/v1/node', + // method: 'GET', + // params, + // }); + // } + + // getNodeListReq(data) { + // return request(this.getNodeList(data)); + // } +} + +export default new pollApi(); diff --git a/packages/web/projects/vgpu/hooks/useParentAction.js b/packages/web/projects/vgpu/hooks/useParentAction.js new file mode 100644 index 0000000..dbd9828 --- /dev/null +++ b/packages/web/projects/vgpu/hooks/useParentAction.js @@ -0,0 +1,22 @@ +import { useRouter } from 'vue-router'; + +export default function useParentAction() { + const router = useRouter(); + + const sendRouteChange = (url) => { + if (window.parent !== window) { + // 在 iframe 中,通知父窗口 + const message = { + type: 'ChangeThePath', + data: url + }; + window.parent.postMessage(JSON.stringify(message), '*'); + } else { + // 不在 iframe 中,直接使用 router 跳转 + router.push(url); + } + }; + const hasParentWindow = window.parent !== window; + + return { sendRouteChange, hasParentWindow }; +} \ No newline at end of file diff --git a/packages/web/projects/vgpu/router.js b/packages/web/projects/vgpu/router.js index d5d29e3..ca7f48a 100644 --- a/packages/web/projects/vgpu/router.js +++ b/packages/web/projects/vgpu/router.js @@ -20,6 +20,12 @@ export default (Layout) => ({ name: 'overview', meta: { title: '资源总览', icon: 'dashboard', noCache: true }, }, + { + path: '/admin/vgpu/poll/admin', + component: () => import('~/vgpu/views/poll/admin/index.vue'), + name: 'poll-admin', + meta: { title: '资源池管理', icon: 'vgpu-pool-tab', noCache: true }, + }, { path: '/admin/vgpu/node/admin', component: () => import('~/vgpu/views/node/admin/index.vue'), diff --git a/packages/web/projects/vgpu/views/monitor/overview/config.js b/packages/web/projects/vgpu/views/monitor/overview/config.js index f61321c..5f078ec 100644 --- a/packages/web/projects/vgpu/views/monitor/overview/config.js +++ b/packages/web/projects/vgpu/views/monitor/overview/config.js @@ -11,29 +11,29 @@ export const rangeConfigInit = [ normal: { color: { type: 'linear', - x: 0, // 渐变起始点 0% - y: 0, // 渐变起始点 0% - x2: 0, // 渐变结束点 100% - y2: 1, // 渐变结束点 100% + x: 0, + y: 0, + x2: 0, + y2: 1, colorStops: [ { offset: 0, - color: 'rgba(250, 200, 88, 0.16)', // 渐变起始颜色 + color: 'rgba(250, 200, 88, 0.16)', }, { offset: 1, - color: 'rgba(250, 200, 88, 0.00)', // 渐变结束颜色 + color: 'rgba(250, 200, 88, 0.00)', }, ], - global: false, // 缺省为 false + global: false, }, }, }, itemStyle: { - color: 'rgb(250, 200, 88)', // 设置线条颜色为橙色 + color: 'rgb(250, 200, 88)', }, lineStyle: { - color: 'rgb(250, 200, 88)', // 设置线条颜色为橙色 + color: 'rgb(250, 200, 88)', }, }, { @@ -45,65 +45,134 @@ export const rangeConfigInit = [ normal: { color: { type: 'linear', - x: 0, // 渐变起始点 0% - y: 0, // 渐变起始点 0% - x2: 0, // 渐变结束点 100% - y2: 1, // 渐变结束点 100% + x: 0, + y: 0, + x2: 0, + y2: 1, colorStops: [ { offset: 0, - color: 'rgba(84, 112, 198, 0.16)', // 渐变起始颜色 + color: 'rgba(84, 112, 198, 0.16)', }, { offset: 1, - color: 'rgba(84, 112, 198, 0.00)', // 渐变结束颜色 + color: 'rgba(84, 112, 198, 0.00)', }, ], - global: false, // 缺省为 false + global: false, }, }, }, itemStyle: { - color: 'rgb(84, 112, 198)', // 设置线条颜色为橙色 + color: 'rgb(84, 112, 198)', }, lineStyle: { - color: 'rgb(84, 112, 198)', // 设置线条颜色为橙色 + color: 'rgb(84, 112, 198)', }, }, { name: '显存', query: `sum(hami_container_vmemory_allocated) / sum(hami_memory_size) * 100`, data: [], + type: 'line', areaStyle: { normal: { color: { type: 'linear', - x: 0, // 渐变起始点 0% - y: 0, // 渐变起始点 0% - x2: 0, // 渐变结束点 100% - y2: 1, // 渐变结束点 100% + x: 0, + y: 0, + x2: 0, + y2: 1, colorStops: [ { offset: 0, - color: 'rgba(34, 139, 34, 0.16)', // 渐变起始颜色 + color: 'rgba(34, 139, 34, 0.16)', }, { offset: 1, - color: 'rgba(34, 139, 34, 0.00)', // 渐变结束颜色 + color: 'rgba(34, 139, 34, 0.00)', }, ], - global: false, // 缺省为 false + global: false, }, }, }, itemStyle: { - color: 'rgb(145, 204, 117)', // 设置线条颜色为橙色 + color: 'rgb(145, 204, 117)', }, lineStyle: { - color: 'rgb(145, 204, 117)', // 设置线条颜色为橙色 + color: 'rgb(145, 204, 117)', }, }, - ], + { + name: 'CPU', + query: `sum(hami_container_cpu_allocated) / sum(hami_cpu_count) * 100`, + data: [], + type: 'line', + areaStyle: { + normal: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { + offset: 0, + color: 'rgba(255, 99, 71, 0.16)', + }, + { + offset: 1, + color: 'rgba(255, 99, 71, 0.00)', + }, + ], + global: false, + }, + }, + }, + itemStyle: { + color: 'rgb(255, 99, 71)', + }, + lineStyle: { + color: 'rgb(255, 99, 71)', + }, + }, + { + name: '内存', + query: `sum(hami_container_memory_allocated) / sum(hami_memory_capacity) * 100`, + data: [], + type: 'line', + areaStyle: { + normal: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { + offset: 0, + color: 'rgba(138, 43, 226, 0.16)', + }, + { + offset: 1, + color: 'rgba(138, 43, 226, 0.00)', + }, + ], + global: false, + }, + }, + }, + itemStyle: { + color: 'rgb(138, 43, 226)', + }, + lineStyle: { + color: 'rgb(138, 43, 226)', + }, + } + ] }, { title: '资源使用趋势', @@ -174,6 +243,74 @@ export const rangeConfigInit = [ color: 'rgb(145, 204, 117)', // 设置线条颜色为橙色 }, }, + { + name: 'CPU', + query: `sum(hami_container_cpu_allocated) / sum(hami_cpu_count) * 100`, + data: [], + type: 'line', + areaStyle: { + normal: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { + offset: 0, + color: 'rgba(255, 99, 71, 0.16)', + }, + { + offset: 1, + color: 'rgba(255, 99, 71, 0.00)', + }, + ], + global: false, + }, + }, + }, + itemStyle: { + color: 'rgb(255, 99, 71)', + }, + lineStyle: { + color: 'rgb(255, 99, 71)', + }, + }, + { + name: '内存', + query: `sum(hami_container_memory_allocated) / sum(hami_memory_capacity) * 100`, + data: [], + type: 'line', + areaStyle: { + normal: { + color: { + type: 'linear', + x: 0, + y: 0, + x2: 0, + y2: 1, + colorStops: [ + { + offset: 0, + color: 'rgba(138, 43, 226, 0.16)', + }, + { + offset: 1, + color: 'rgba(138, 43, 226, 0.00)', + }, + ], + global: false, + }, + }, + }, + itemStyle: { + color: 'rgb(138, 43, 226)', + }, + lineStyle: { + color: 'rgb(138, 43, 226)', + }, + } ], }, ]; diff --git a/packages/web/projects/vgpu/views/monitor/overview/index.vue b/packages/web/projects/vgpu/views/monitor/overview/index.vue index 5e54652..8ee6f77 100644 --- a/packages/web/projects/vgpu/views/monitor/overview/index.vue +++ b/packages/web/projects/vgpu/views/monitor/overview/index.vue @@ -3,28 +3,30 @@