在上一篇文章中,我们介绍了有关 Kubernetes 的理论介绍。
在本教程中,我们将讨论如何在本地 Kubernetes 环境(也称为 Minikube)上部署 Spring Boot 应用程序。
作为本文的一部分,我们将:
Minikube的安装基本上包括三个步骤:安装Hypervisor(如VirtualBox),CLIkubectl以及Minikube本身。
官方文档提供了每个步骤以及所有流行操作系统的详细说明。
完成安装后,我们可以启动 Minikube,将 VirtualBox 设置为 Hypervisor,并配置kubectl以与名为minikube 的集群通信:
$> minikube start
$> minikube config set vm-driver virtualbox
$> kubectl config use-context minikube之后,我们可以验证kubectl与我们的集群是否正确通信:
$> kubectl cluster-info输出应如下所示:
Kubernetes master is running at https://192.168.99.100:8443
To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.在此阶段,我们将保持响应中的 IP 关闭(在本例中为 192.168.99.100)。我们稍后将其称为NodeIP,它是从集群外部调用资源所必需的,例如从我们的浏览器调用。
最后,我们可以检查集群的状态:
$> minikube dashboard此命令在我们的默认浏览器中打开一个站点,该站点提供了有关群集状态的广泛概述。
由于我们的集群现在正在运行并准备好进行部署,因此我们需要一个演示应用程序。
为此,我们将创建一个简单的“Hello world”应用程序,由两个 Spring Boot 服务组成,我们称之为前端和后端。
后端在端口 8080 上提供一个 REST 终结点,返回包含其主机名的字符串。前端在端口 8081 上可用,它只需调用后端终结点并返回其响应。
之后,我们必须从每个应用程序构建一个 Docker 映像。有关如何构建 Docker 映像的详细说明,请查看Docker化Spring Boot 应用程序。
我们必须确保在 Minikube 集群的 Docker 主机上触发构建过程,否则,Minikube 稍后在部署期间找不到映像。此外,我们主机上的工作区必须挂载到 Minikube VM 中:
$> minikube ssh
$> cd /c/workspace/tutorials/spring-cloud/spring-cloud-kubernetes/demo-backend
$> docker build --file=Dockerfile \
--tag=demo-backend:latest --rm=true .之后,我们可以从 Minikube VM 注销,所有进一步的步骤将使用kubectl和minikube命令行工具在我们的主机上执行。
第一步,我们将为演示后端应用创建一个部署,仅包含一个 Pod。基于此,我们将讨论一些命令,以便我们可以验证部署、检查日志并在最后清理它。
我们将使用kubectl,将所有必需的命令作为参数传递:
$> kubectl run demo-backend --image=demo-backend:latest \
--port=8080 --image-pull-policy Never正如我们所看到的,我们创建了一个称为demo-backend的部署,它是从一个也称为demo-backend的映像实例化的,版本是最新的。
With–port,我们指定部署为其 Pod 打开端口 8080(因为我们的演示后端应用侦听端口 8080)。
标志-映像拉取-策略从不确保,Minikube 不会尝试从注册表中提取映像,而是从本地 Docker 主机获取映像。
现在,我们可以检查部署是否成功:
$> kubectl get deployments输出如下所示:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
demo-backend 1 1 1 1 19s如果我们想查看应用程序日志,我们首先需要 Pod ID:
$> kubectl get pods
$> kubectl logs <pod id>若要使后端应用的 REST 终结点可用,我们需要创建一个服务:
$> kubectl expose deployment demo-backend --type=NodePort–type=NodePort使服务可从群集外部使用。它将在<NodeIP>:<NodePort>可用,即服务将任何传入<NodePort>的请求映射到其分配的Pod的端口8080。
我们使用 expose 命令,所以NodePort会自动由集群设置(这是一个技术限制),默认范围是 30000-32767。要获得我们选择的端口,我们可以使用配置文件,我们将在下一节中看到。
我们可以验证服务是否已成功创建:
$> kubectl get services输出如下所示:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-backend NodePort 10.106.11.133 <none> 8080:30117/TCP 11m如我们所见,我们有一个名为demo-backend的服务,类型为NodePort,可在集群内部IP 10.106.11.133中使用。
我们必须仔细查看列 PORT(S):由于端口 8080 是在部署中定义的,因此服务将流量转发到此端口。但是,如果我们想从浏览器调用演示后端,则必须使用端口 30117,该端口可从集群外部访问。
现在,我们可以第一次调用我们的后端服务:
$> minikube service demo-backend此命令将启动我们的默认浏览器,打开<NodeIP>:<NodePort>。在我们的示例中,这将是http://192.168.99.100:30117。
之后,我们可以删除服务和部署:
$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend对于更复杂的设置,配置文件是更好的选择,而不是通过命令行参数传递所有参数。
配置文件是记录部署的好方法,并且可以对其进行版本控制。
让我们使用配置文件重新定义后端的服务:
kind: Service
apiVersion: v1
metadata:
name: demo-backend
spec:
selector:
app: demo-backend
ports:
- protocol: TCP
port: 8080
type: ClusterIP我们创建一个名为demo-backend的服务,由元数据:名称字段指示。
它针对任何带有app=demo-backend标签的 Pod 上的 TCP 端口 8080。
最后,键入:ClusterIP表示它只能从集群内部使用(因为这次我们想从演示前端应用调用端点,但不再像前面的例子那样直接从浏览器调用端点)。
接下来,我们可以定义实际的部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-backend
spec:
selector:
matchLabels:
app: demo-backend
replicas: 3
template:
metadata:
labels:
app: demo-backend
spec:
containers:
- name: demo-backend
image: demo-backend:latest
imagePullPolicy: Never
ports:
- containerPort: 8080我们创建一个名为demo-backend 的部署,由元数据:“名称字段指示。
spec: 选择器字段定义部署如何查找要管理的 Pod。在这种情况下,我们只选择在 Pod 模板中定义的一个标签(app:demo-backend)。
我们希望有三个复制的 Pod,我们用副本字段来指示。
模板字段定义了实际的 Pod:
现在,我们可以触发部署:
$> kubectl create -f backend-deployment.yaml让我们验证部署是否成功:
$> kubectl get deployments输出如下所示:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
demo-backend 3 3 3 3 25s我们还可以检查服务是否可用:
$> kubectl get services输出如下所示:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
demo-backend ClusterIP 10.102.17.114 <none> 8080/TCP 30s
如我们所见,该服务的类型为ClusterIP,它不提供 30000-32767 范围内的外部端口,这与前面在第 5 节中的示例不同。之后,我们可以为前端定义服务和部署:
kind: Service
apiVersion: v1
metadata:
name: demo-frontend
spec:
selector:
app: demo-frontend
ports:
- protocol: TCP
port: 8081
nodePort: 30001
type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-frontend
spec:
selector:
matchLabels:
app: demo-frontend
replicas: 3
template:
metadata:
labels:
app: demo-frontend
spec:
containers:
- name: demo-frontend
image: demo-frontend:latest
imagePullPolicy: Never
ports:
- containerPort: 8081
前端和后端几乎相同,后端和前端之间的唯一区别是服务的规格:对于前端,我们将类型定义为NodePort(因为我们希望前端可供集群外部使用)。后端只需要可以从群集内访问,因此类型为ClusterIP。
如前所述,我们还使用nodePort字段手动指定NodePort。
现在,我们可以通过相同的方式触发此部署:
$> kubectl create -f frontend-deployment.yaml让我们快速验证部署是否成功以及服务是否可用:
$> kubectl get deployments
$> kubectl get services
之后,我们终于可以调用前端应用的 REST 端点了:$> minikube service demo-frontend此命令将再次启动我们的默认浏览器,打开<NodeIP>:<NodePort>,这是本例http://192.168.99.100:30001。
最后,我们可以通过删除服务和部署来清理:
$> kubectl delete service demo-frontend
$> kubectl delete deployment demo-frontend
$> kubectl delete service demo-backend
$> kubectl delete deployment demo-backend在本文中,我们快速浏览了如何使用 Minikube 在本地 Kubernetes 集群上部署 Spring Boot “Hello world” 应用程序。
我们详细讨论了如何: