开篇词
该指南将引导你在 Kubernetes 上部署 Spring Boot 应用的过程。如何使用 Spring Boot 和 Kuberntes 进行操作有很多选择 - 该指南的目的是使你尽快起步并运行,而不是讨论所有替代方案或部署至生产环境的所有细节(当然,这是我们最喜欢地方)。
有一些交互式教程可以补充和扩展 Katacoda/springguides 上该指南的内容。如果我们遵循这些教程,则所有代码都将在浏览器中的云中运行。或者,我们可以创建自己的集群并在本地安装所需的所有工具,然后从指南中复制粘贴。
Kuberntes 上的 Spring Boot 入门:与该指南相同的材料,但是在我们的浏览器中运行。
安装 Kuberntes:使用 Kind 在本地安装 Kubernetes 的指南。如果我们希望在笔记本上运行教程,可以使用它在笔记本电脑上进行设置。
Spring Boot 的 Kubernetes 探针:Spring Boot 的活跃性和就绪性探针指南。
你将创建的应用
Kubernetes 是一个开源系统,用于自动化容器化应用的部署、扩展及管理。它将组成应用的容器分组为逻辑单元,以便于管理及发现。在该指南中,我们将构建并部署一个简单的 Spring 引导应用。
你将需要的工具
我们将需要 Linux 或类似 Linux 的命令行。该指南中的命令行示例适用于 Linux,带 Shell 的 MaxOS 终端或 Windows 上的 WSL。
我们还需要一个 Kubernetes 集群和命令行工具 kubectl。我们可以使用 Kind(在 Docker 上)或 Minikube 在本地创建集群。或者,我们可以使用云提供商,例如 Google Cloud Platform、Amazon Web Services 或 Microsoft Azure。在继续进行之前,请确认我们可以从 shell 运行 kubectl
命令。例如(使用 kind
):
$ kubectl cluster-info
Kubernetes master is running at https://127.0.0.1:46253
KubeDNS is running at https://127.0.0.1:46253/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.
and
$ kubectl get all
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 7m13s
创建 Spring Boot 应用
我们要做的第一件事是创建一个 Spring Boot 应用。如果我们希望在 github 中使用它,则可以在终端中将其克隆(已经安装了 git 和 java)。或者,我们可以使用 start.spring.io 从头开始创建应用:
curl https://start.spring.io/starter.tgz -d dependencies=webflux,actuator | tar -xzvf -
然后,我们可以构建该应用:
./mvnw install
第一次将花费几分钟,但是一旦所有依赖项都被缓存,它将很快。
我们可以看到构建的结果。如果构建成功,则应该看到一个 JAR 文件,如下所示:
ls -l target/*.jar
-rw-r--r-- 1 root root 19463334 Nov 15 11:54 target/demo-0.0.1-SNAPSHOT.jar
JAR 是可执行的:
$ java -jar target/*.jar
该应用具有一些内置的 HTTP 端点,这取决于我们在下载项目时添加的 “actuator” 依赖。因此,我们将在启动日志中看到以下内容:
...
2019-11-15 12:12:35.333 INFO 13912 --- [ main] o.s.b.a.e.web.EndpointLinksResolver : Exposing 2 endpoint(s) beneath base path '/actuator'
2019-11-15 12:12:36.448 INFO 13912 --- [ main] o.s.b.web.embedded.netty.NettyWebServer : Netty started on port(s): 8080
...
因此,我们可以在另一个终端中请求端点:
$ curl localhost:8080/actuator | jq .
{
"_links": {
"self": {
"href": "http://localhost:8080/actuator",
"templated": false
},
"health-path": {
"href": "http://localhost:8080/actuator/health/{*path}",
"templated": true
},
"health": {
"href": "http://localhost:8080/actuator/health",
"templated": false
},
"info": {
"href": "http://localhost:8080/actuator/info",
"templated": false
}
}
}
要完成该步骤,请发送 Ctrl + C 终止该应用。
容器化应用
有多个选项可用于容器化 Spring Boot 应用。对于本地开发和测试,从 Dokerfile 开始是有意义的,因为构建工作流程通常是众所周知的。
如果我们在本地没有 docker,或者想自动将镜像推送到注册表,那么 Jib 将是一个不错的选择。在企业环境中,当我们需要 CI/CD 管道的受信构建服务时,可以查看 Cloud Native Buildpacks。
首先创建一个 Dockerfile
:
FROM openjdk:8-jdk-alpine AS builder
WORKDIR target/dependency
ARG APPJAR=target/*.jar
COPY ${APPJAR} app.jar
RUN jar -xf ./app.jar
FROM openjdk:8-jre-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY --from=builder ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY --from=builder ${DEPENDENCY}/META-INF /app/META-INF
COPY --from=builder ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","com.example.demo.DemoApplication"]
然后构建容器镜像,并为其提供标签(如果我们要使用 Dockerhub,请选择我们自己的 ID 而不是 “springguides”):
$ docker build -t springguides/demo .
我们可以在本地运行容器:
$ docker run -p 8080:8080 springguides/demo
并检查它是否可以在另一个终端上运行:
$ curl localhost:8080/actuator/health
通过终止容器结束。
除非我们通过 Dockerhub 进行身份验证(docker login
),否则我们将无法推送该图像,但是已经有一个图像应该可以工作了。如果我们通过了身份验证,则可以:
$ docker push springguides/demo
在现实生活中,需要将镜像推送到 Dockerhub(或其他可访问的存储库),因为 Kubernetes 会从其 Kubelet(节点)内部拉取镜像,这些 Kubelet 通常不连接到本地 docker 守护进程。对于这种情况,我们可以省略推送,而只使用已有的图像。
仅出于测试目的,有一些变通办法,例如,使 docker push
与不安全的本地注册表一起使用,但在该方案的范围之外。
部署应用至 Kubernetes
我们有一个运行并公开 8080 端口的容器,因此,要使 Kubernetes 运行,只需要一些 YAML。为了避免不得不查看或编辑 YAML,现在,我们可以要求 kubectl 为我们生成它。唯一可能有所不同的地方是 --image 名称。如果将容器部署到自己的存储库,请使用其标记而不是以下标记:
$ kubectl create deployment demo --image=springguides/demo --dry-run -o=yaml > deployment.yaml
$ echo --- >> deployment.yaml
$ kubectl create service clusterip demo --tcp=8080:8080 --dry-run -o=yaml >> deployment.yaml
我们可以采用上面生成的 YAML 并根据需要进行编辑,也可以仅应用它:
$ kubectl apply -f deployment.yaml
deployment.apps/demo created
service/demo created
检查应用是否正在运行:
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/demo-658b7f4997-qfw9l 1/1 Running 0 146m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.43.0.1 <none> 443/TCP 2d18h
service/demo ClusterIP 10.43.138.213 <none> 8080/TCP 21h
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/demo 1/1 1 1 21h
NAME DESIRED CURRENT READY AGE
replicaset.apps/demo-658b7f4997 1 1 1 21h
d
继续执行
kubectl get all
知道演示窗格显示其状态为 “正在运行” 为止。
现在,我们需要能够连接到在 Kubernetes 中做为服务公开的应用。一种在开发时有效的方法是创建 SSH 通道:
$ kubectl port-forward svc/demo 8080:8080
那么我们可以验证该应用是否在其他终端上运行:
$ curl localhost:8080/actuator/health
{"status":"UP"}
概述
恭喜你!我们刚刚在 Kubernetes 上运行了项目。
想看指南的其他内容?请访问该指南的所属专栏:《Spring 官方指南》