Docker 与 Kubernetes 协作
Kubernetes 和 Docker 协同工作,以简化应用程序的部署和管理。Docker 将应用程序及其依赖项打包到一个可移植的 container 中,确保开发、staging、测试和生产环境一致。接下来,Kubernetes 通过自动化来编排所有这些 Docker container,例如 scaling、负载均衡、自愈等任务。
Kubernetes 集群由运行 Docker container 的 worker node 和管理集群状态的 master node 组成。通过在 YAML 文件中定义应用程序的期望状态,Kubernetes 会持续监控 Deployment 并遵守规范,从而提供高可用性和高效的资源利用率。
在本章中,我们来看一个实际示例,展示 Docker container 和 Kubernetes 如何协同工作,使集群的部署和管理变得更容易。
准备 Java Spring Boot 应用程序包
- 访问 Spring Initializr − 打开您喜欢的网页浏览器,导航至 https://start.spring.io/。
- 选择 Dependencies − 在此处为您的应用程序选择 dependencies。要构建一个简单的 REST API,您可以选择 Spring Web。
- 创建项目 − 选择“Generate”,然后“Download ZIP File”。
- 导入项目 − 将项目导入您喜欢的 IDE,例如 IntelliJ IDEA 或 Eclipse。
使用 RESTController 创建 REST Endpoints
现在让我们创建一个普通的 REST controller −
package com.example.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@GetMapping("/")
public String hello() {
return "Hello from Spring Boot!";
}
}
构建应用程序
要将应用程序打包成 JAR 文件,请运行以下 Maven 命令 −
$ mvn clean package
生成的 JAR 文件将被放置在 target 目录中。
其他注意事项
- 依赖管理 − 使用 Maven 或 Gradle 进行正确的依赖管理,以避免其他地方的冲突。
- 配置 − 使配置可外部化,将配置保存在应用程序外部的 properties 文件中,甚至作为 environment variables。
- 测试 − 编写单元测试和集成测试,以确保代码质量。
Spring Boot 应用程序打包完成后,我们就可以创建 Docker image 了。
构建 Docker 镜像
让我们创建一个 Dockerfile 来定义构建 Spring Boot 应用 Docker 镜像的指令。
编写 Dockerfile
在 Spring Boot 项目的根目录下创建一个名为 Dockerfile 的文件。
FROM openjdk:17-jdk-alpine WORKDIR /app COPY target/*.jar app.jar ENTRYPOINT ["java", "-jar", "app.jar"]
- FROM openjdk:17-jdk-alpine − 提供基础镜像。
- WORKDIR /app − 设置 container 内部的工作目录。
- COPY target/*.jar app.jar − 将 target 文件夹中创建的 jar 文件复制到 container 中的 /app 目录。
- ENTRYPOINT ["java", "-jar", "app.jar"] − 设置 container 启动时执行的入口点命令;在这种情况下,是 Java JAR。
您可以使用以下命令构建 Docker 镜像 −
$ docker build -t my-spring-boot-app .
- -t my-spring-boot-app − 将您的镜像标记为 my-spring-boot-app。
- . (dot) − 表示当前目录作为构建上下文。
运行以下命令验证镜像是否创建成功 −
$ docker images
新创建的镜像应该出现在输出中。
其他注意事项
- Base Image − 选择满足应用需求和性能要求的 base image。
- Multi-Stage Builds − 在优化镜像大小时,考虑使用 multi-stage builds,并分离构建和运行时环境。
- Dockerfile best practices − 使用编写 Dockerfile 的最佳实践来减小镜像大小。
现在我们有了 Docker 镜像,就可以将其部署到 Kubernetes 集群中了。
Kubernetes 安装和设置
要部署我们的 Spring Boot 应用,我们需要一个 Kubernetes 集群。我们将看到如何使用 Minikube 设置本地 Kubernetes 环境。
设置 Minikube
Minikube 是一个让您设置单节点 Kubernetes 的工具。
前提条件
- 启用虚拟化(例如 VirtualBox、Hyper-V)
安装
1. 下载 Minikube 二进制文件 −
curl -L https://github.com/minikube/minikube/releases/latest/download/minikube-linux-amd64 > minikube chmod +x minikube sudo mv minikube /usr/local/bin/
将 minikube-linux-amd64 替换为适合您操作系统的相应二进制文件。
2. 启动 Minikube 集群 −
$ minikube start
安装 kubectl
Kubectl 是一个用于控制 Kubernetes 的命令行工具。
安装
1. 下载 Kubectl 二进制文件 −
curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl chmod +x kubectl sudo mv kubectl /usr/local/bin/
将 linux/amd64 替换为适合您操作系统的相应二进制文件。
2. 配置 kubectl 使用 Minikube −
minikube config set context minikube
验证安装
要验证本地 `minikube` 和使用 `kubectl` 设置的集群,请运行 −
minikube status kubectl cluster-info
这将获取 Minikube 集群的详细信息以及您环境中运行的资源。
其他注意事项
- Kubernetes Distributions − 检查其他 Kubernetes 发行版是个好主意,例如针对不同用例的 K3s 或 MicroK8s。
- Cloud Provided − 对于生产平台,云提供商提供托管的 Kubernetes 服务,如 Google Kubernetes Engine、Amazon EKS 和 Azure Kubernetes Service。
- Cluster Configuration − 根据您的资源限制和需求自定义 Minikube 配置。
最后,安装了 Minikube 和 kubectl 后,我们现在可以继续编写必要的 YAML 配置来部署我们的应用了。
设置 Kubernetes 集群
以下是主要的 Kubernetes 组件 −
- Master Node − 控制集群并管理 worker nodes。
- Worker Nodes − 运行 containerized applications。
- Pods − Kubernetes 中最小的可部署单元,包含一个或多个 containers。
- Deployments − 管理 Pod replicas 的期望状态。
- Services − 将运行在 Pods 上的 applications 暴露为网络服务。
检查集群状态
您可以使用以下命令验证 Minikube 集群是否正常运行 −
$ kubectl cluster-info
上述命令的结果将显示集群信息,包括 Kubernetes 版本和 master 地址。
检查节点状态
要查看集群中的节点,可以使用以下命令 −
$ kubectl get nodes
您将看到列出一个节点,那就是 Minikube 节点。
其他注意事项
- Cluster Size − 对于生产环境,应根据工作负载确定最佳节点数量。
- Node Resources − 应配置节点资源(CPU、内存)以匹配应用的需要。
- Network Configuration − 请确保节点与外部环境之间的网络连接正常。
现在我们准备好为应用创建 YAML 配置了。
编写 YAML 配置
您需要一个 YAML 配置文件来在 Kubernetes 上部署 Spring Boot 应用。您可以在此文件中定义应用所需资源,如 deployments 和 services。
Deployment 配置
Kubernetes 中的 Deployment 管理一组相同的 pods。以下是一个为您的应用定义 Deployment 的示例 YAML 文件 −
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-spring-boot-app
spec:
replicas: 3
selector:
matchLabels:
app: my-spring-boot-app
template:
metadata:
labels:
app: my-spring-boot-app
spec:
containers:
- name: my-spring-boot-app
image: my-spring-boot-app:latest
ports:
- containerPort: 8080
- replicas − 指定 pod 实例的数量。
- matchLabels − 确保 Deployment 管理正确的 pods。
- image − 引用我们之前构建的 Docker image。
- containerPort − 定义容器内应用监听的端口。
Service 配置
Service 将您的应用暴露到网络。以下是一个 Service YAML 文件的示例 −
apiVersion: v1
kind: Service
metadata:
name: my-spring-boot-app-service
spec:
type: NodePort
selector:
app: my-spring-boot-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
- type − NodePort 在每个节点的 IP 上静态端口暴露服务。
- port − 服务暴露的端口。
- targetPort − 服务将流量转发到的 pod 端口。
应用配置
要部署您的应用,可以使用 kubectl 应用这些配置 −
kubectl apply -f deployment.yaml kubectl apply -f service.yaml
验证部署
要检查 pods 和 services 的状态,可以使用以下命令 −
kubectl get pods kubectl get services
您将看到应用正在运行,service 正在暴露它。
访问应用
要访问您的应用,可以使用 Minikube IP 和分配给您的 service 的 NodePort −
$ minikube service my-spring-boot-app-service
运行此命令将打开浏览器指向服务 URL。
其他注意事项
- Scaling − 应始终根据流量调整 Deployment YAML 中的 replicas 数量以处理更多负载。
- Security − 考虑添加 security contexts 和 network policies。
- Monitoring − 在生产应用中,应实施如 Prometheus 和 Grafana 的监控解决方案以实现 observability。
通过这些配置,您已成功在 Kubernetes 集群上部署了 Spring Boot 应用。
结论
换句话说,将 Docker 集成到 Kubernetes 中提供了一种有效的方式来部署和管理应用程序。虽然 Docker 容器确保了所有开发阶段的一致环境,但 Kubernetes 会自动编排它们,以实现可扩展性、高可用性和最佳资源利用率。使用 YAML 配置 Minikube 本地化 Kubernetes 环境,将使开发者的工作流程变得简单,便于部署和维护健壮的应用程序。
Docker 与 Kubernetes 协作的常见问题
1. Docker 和 Kubernetes 有什么区别?
Docker 是一种用于构建、执行和管理容器的软件。它主要将应用程序及其依赖项安装在称为容器的标准包中。另一方面,Kubernetes 是一个编排平台,处理诸如自动部署或扩展运行在多个主机上的应用程序等操作。由于 Docker 围绕单个容器运行,Kubernetes 则负责静态容器集的实现、扩展和管理。
2. Kubernetes 如何编排容器?
Kubernetes 通过一系列资源来编排容器,包括 pods、deployments、services 等。Pods 被分类为共享资源的容器组。Deployments 负责管理 pod 副本的期望状态,而 services 则为 pod 集维护稳定的网络端点。Kubernetes 会根据配置自动处理容器的生命周期、负载均衡或扩展。