diff --git a/src/apps/apps.service.ts b/src/apps/apps.service.ts index 8ed699c..ef5b048 100644 --- a/src/apps/apps.service.ts +++ b/src/apps/apps.service.ts @@ -484,10 +484,12 @@ export class AppsService { ); } - logs.push(`[apply] ingress/${ingressName}`); + await this.deleteLegacyIngress(logs, namespace, ingressName); + + logs.push(`[apply] ingressroute/${ingressName}`); appendOutput( logs, - await this.applyK8sManifest(createIngressManifest({ + await this.applyK8sManifest(createTraefikIngressRouteManifest({ namespace, name: ingressName, host: rule.host, @@ -1113,10 +1115,12 @@ export class AppsService { ); } - logs.push(`[apply] ingress/${ingressName}`); + await this.deleteLegacyIngress(logs, namespace, ingressName); + + logs.push(`[apply] ingressroute/${ingressName}`); appendOutput( logs, - await this.applyK8sManifest(createIngressManifest({ + await this.applyK8sManifest(createTraefikIngressRouteManifest({ namespace, name: ingressName, host: rule.host, @@ -1345,6 +1349,16 @@ export class AppsService { } } + private async deleteLegacyIngress(logs: string[], namespace: string, name: string) { + try { + const output = await this.kubectl(['delete', 'ingress', name, '-n', namespace, '--ignore-not-found=true']); + if (output.trim()) appendOutput(logs, output); + } catch (error) { + const message = error instanceof Error ? error.message : 'delete legacy ingress failed'; + logs.push(`[warn] legacy ingress/${name} 정리는 건너뜀: ${message}`); + } + } + private async applyDatabaseResources(input: { namespace: string; appKey: string; @@ -2086,7 +2100,7 @@ function createServiceManifest(input: { }; } -function createIngressManifest(input: { +function createTraefikIngressRouteManifest(input: { namespace: string; name: string; host: string; @@ -2097,51 +2111,36 @@ function createIngressManifest(input: { tlsEnabled: boolean; tlsSecretName?: string | null; }) { - const annotations: Record = {}; - - if (input.middlewareName) { - annotations['traefik.ingress.kubernetes.io/router.middlewares'] = `${input.namespace}-${input.middlewareName}@kubernetescrd`; - } - const manifest: Record = { - apiVersion: 'networking.k8s.io/v1', - kind: 'Ingress', + apiVersion: 'traefik.io/v1alpha1', + kind: 'IngressRoute', metadata: { name: input.name, namespace: input.namespace, - labels: getManagedLabels(input.name, 'ingress'), - ...(Object.keys(annotations).length > 0 ? { annotations } : {}), + labels: getManagedLabels(input.name, 'ingressroute'), }, spec: { - rules: [ + entryPoints: [input.tlsEnabled ? 'websecure' : 'web'], + routes: [ { - host: input.host, - http: { - paths: [ - { - path: input.path, - pathType: 'Prefix', - backend: { - service: { - name: input.serviceName, - port: { number: input.servicePort }, - }, - }, - }, - ], - }, + match: `Host(\`${input.host}\`) && PathPrefix(\`${input.path}\`)`, + kind: 'Rule', + ...(input.middlewareName ? { middlewares: [{ name: input.middlewareName }] } : {}), + services: [ + { + name: input.serviceName, + port: input.servicePort, + }, + ], }, ], }, }; if (input.tlsEnabled && input.tlsSecretName) { - (manifest.spec as Record).tls = [ - { - hosts: [input.host], - secretName: input.tlsSecretName, - }, - ]; + (manifest.spec as Record).tls = { + secretName: input.tlsSecretName, + }; } return manifest;