From c2b3d83d87ecb50e8cc324e7bb1a0254c49add71 Mon Sep 17 00:00:00 2001 From: led Date: Fri, 4 Sep 2026 14:17:52 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20HTTP=20=EC=84=9C=EB=B2=84=EB=A1=9C=20?= =?UTF-8?q?=EC=A0=84=ED=99=98=20+=20Kaniko=20=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=20=EB=B9=8C=EB=93=9C/K8s=20=EB=B0=B0=ED=8F=AC=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=B4=ED=94=84=EB=9D=BC=EC=9D=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 4 +++ Jenkinsfile | 49 ++++++++++++++++++++++++++++++- k8s/deployment.yaml | 39 ++++++++++++++++++++++++ k8s/ingress.yaml | 18 ++++++++++++ k8s/service.yaml | 11 +++++++ src/main/java/com/cstest/App.java | 31 +++++++++++++++++-- 6 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 Dockerfile create mode 100644 k8s/deployment.yaml create mode 100644 k8s/ingress.yaml create mode 100644 k8s/service.yaml diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8a53afc --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM eclipse-temurin:21-jre +WORKDIR /app +COPY build/libs/*.jar app.jar +ENTRYPOINT ["java", "-jar", "/app/app.jar"] diff --git a/Jenkinsfile b/Jenkinsfile index 312c56d..6796019 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -5,19 +5,66 @@ pipeline { apiVersion: v1 kind: Pod spec: + serviceAccountName: jenkins-deployer containers: - name: gradle image: eclipse-temurin:21-jdk command: ["sleep"] args: ["99d"] + - name: kaniko + image: gcr.io/kaniko-project/executor:debug + command: ["sleep"] + args: ["99d"] + volumeMounts: + - name: docker-config + mountPath: /kaniko/.docker + - name: kubectl + image: bitnami/kubectl:1.31 + command: ["sleep"] + args: ["99d"] + volumes: + - name: docker-config + secret: + secretName: gitea-registry-cred + items: + - key: .dockerconfigjson + path: config.json ''' } } + environment { + IMAGE = "gitea.led.ectech.co.kr/ledmega/cstest:${env.BUILD_NUMBER}" + } stages { stage('Build') { steps { container('gradle') { - sh 'chmod +x gradlew && ./gradlew build --console=plain' + sh 'chmod +x gradlew && ./gradlew build --console=plain -x test' + } + } + } + stage('Image') { + steps { + container('kaniko') { + sh ''' + /kaniko/executor \ + --context `pwd` \ + --dockerfile Dockerfile \ + --destination ${IMAGE} + ''' + } + } + } + stage('Deploy') { + steps { + container('kubectl') { + sh ''' + sed "s#IMAGE_PLACEHOLDER#${IMAGE}#" k8s/deployment.yaml > /tmp/deployment.yaml + kubectl apply -f /tmp/deployment.yaml + kubectl apply -f k8s/service.yaml + kubectl apply -f k8s/ingress.yaml + kubectl -n apps rollout status deployment/cstest --timeout=90s + ''' } } } diff --git a/k8s/deployment.yaml b/k8s/deployment.yaml new file mode 100644 index 0000000..ebcad22 --- /dev/null +++ b/k8s/deployment.yaml @@ -0,0 +1,39 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cstest + namespace: apps +spec: + replicas: 2 + selector: + matchLabels: + app: cstest + template: + metadata: + labels: + app: cstest + spec: + containers: + - name: cstest + image: IMAGE_PLACEHOLDER + ports: + - containerPort: 8080 + readinessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 3 + periodSeconds: 5 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + requests: + cpu: "50m" + memory: "128Mi" + limits: + cpu: "250m" + memory: "256Mi" diff --git a/k8s/ingress.yaml b/k8s/ingress.yaml new file mode 100644 index 0000000..caa19d8 --- /dev/null +++ b/k8s/ingress.yaml @@ -0,0 +1,18 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: cstest + namespace: apps +spec: + ingressClassName: traefik + rules: + - host: cstest.led.ectech.co.kr + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: cstest + port: + number: 8080 diff --git a/k8s/service.yaml b/k8s/service.yaml new file mode 100644 index 0000000..c6e933f --- /dev/null +++ b/k8s/service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: cstest + namespace: apps +spec: + selector: + app: cstest + ports: + - port: 8080 + targetPort: 8080 diff --git a/src/main/java/com/cstest/App.java b/src/main/java/com/cstest/App.java index 44e72b7..77d81ce 100644 --- a/src/main/java/com/cstest/App.java +++ b/src/main/java/com/cstest/App.java @@ -1,12 +1,37 @@ package com.cstest; +import com.sun.net.httpserver.HttpServer; +import java.io.IOException; +import java.io.OutputStream; +import java.net.InetSocketAddress; +import java.nio.charset.StandardCharsets; + public class App { public String greeting() { - return "Hello for real this time from cstest — Gitea/Jenkins CI/CD 연동 테스트용 프로그램"; + return "Hello for real this time from cstest — Gitea/Jenkins/K8s CI/CD 연동 테스트용 프로그램"; } - public static void main(String[] args) { - System.out.println(new App().greeting()); + public static void main(String[] args) throws IOException { + App app = new App(); + int port = 8080; + HttpServer server = HttpServer.create(new InetSocketAddress(port), 0); + server.createContext("/", exchange -> { + byte[] body = app.greeting().getBytes(StandardCharsets.UTF_8); + exchange.getResponseHeaders().add("Content-Type", "text/plain; charset=utf-8"); + exchange.sendResponseHeaders(200, body.length); + try (OutputStream os = exchange.getResponseBody()) { + os.write(body); + } + }); + server.createContext("/healthz", exchange -> { + byte[] body = "OK".getBytes(StandardCharsets.UTF_8); + exchange.sendResponseHeaders(200, body.length); + try (OutputStream os = exchange.getResponseBody()) { + os.write(body); + } + }); + server.start(); + System.out.println("cstest listening on :" + port); } }