将 Kotlin 部署到 Kubernetes:基础实践指南
Kubernetes (K8s) 已成为容器化应用编排的标准。如果您正在使用 Kotlin(结合 Ktor、Spring Boot 或 http4k)开发服务器端应用,迟早会面临将其部署到集群中的问题。在本指南中,我们将从将 Kotlin 应用打包成 Docker 镜像,到使用 ConfigMap 和 Ingress 在 Kubernetes 中运行它,一步步完成整个过程。所有示例都是可运行的,并可直接进行调整。
1. 准备 Kotlin 应用和 Docker 镜像
以 Ktor 上的一个简单应用为例(可替换为任何其他框架)。我们的应用将监听端口 8080 并返回包含版本信息的 JSON。
// src/main/kotlin/com/example/Application.ktimport io.ktor.server.engine.*import io.ktor.server.netty.*import io.ktor.server.routing.*import io.ktor.server.response.*
fun main() { embeddedServer(Netty, port = 8080) { routing { get("/") { call.respond(mapOf("app" to "kotlin-on-k8s", "version" to "1.0.0")) } } }.start(wait = true)}使用 Gradle(shadow 插件)将应用打包成 fat JAR。构建完成后,创建 Dockerfile:
# DockerfileFROM openjdk:17-jdk-slimWORKDIR /appCOPY build/libs/app-all.jar app.jarEXPOSE 8080CMD ["java", "-jar", "app.jar"]构建镜像并推送到仓库(例如 Docker Hub):
docker build -t youruser/kotlin-app:1.0.0 .docker push youruser/kotlin-app:1.0.02. 创建 Kubernetes 清单文件
现在描述用于部署的资源。创建三个文件:deployment.yaml、service.yaml 和 configmap.yaml。
2.1. 用于配置的 ConfigMap
将应用设置(例如日志级别或连接字符串)提取到 ConfigMap 中:
# configmap.yamlapiVersion: v1kind: ConfigMapmetadata: name: app-configdata: LOG_LEVEL: "DEBUG" APP_MODE: "production"2.2. Deployment
在 Deployment 清单中指定镜像、端口、副本数,并从 ConfigMap 注入变量:
# deployment.yamlapiVersion: apps/v1kind: Deploymentmetadata: name: kotlin-appspec: replicas: 2 selector: matchLabels: app: kotlin-app template: metadata: labels: app: kotlin-app spec: containers: - name: app image: youruser/kotlin-app:1.0.0 ports: - containerPort: 8080 envFrom: - configMapRef: name: app-config livenessProbe: httpGet: path: / port: 8080 initialDelaySeconds: 10 periodSeconds: 52.3. Service
Service 将在 Pod 之间平衡流量:
# service.yamlapiVersion: v1kind: Servicemetadata: name: kotlin-app-servicespec: selector: app: kotlin-app ports: - protocol: TCP port: 80 targetPort: 8080 type: ClusterIP3. 部署到集群并配置 Ingress
应用清单文件:
kubectl apply -f configmap.yamlkubectl apply -f deployment.yamlkubectl apply -f service.yaml检查 Pod 是否已启动:
kubectl get podskubectl logs <pod-name>现在让应用可从外部访问。创建 Ingress(假设集群中已安装 Ingress Controller,例如 NGINX):
# ingress.yamlapiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: kotlin-app-ingressspec: rules: - host: kotlin.example.com http: paths: