Docker 中 Kubernetes 到底是怎么工作的?

文章导读
Previous Quiz Next Kubernetes 和 Docker 协同工作,以简化应用程序的部署和管理。Docker 将应用程序及其依赖项打包到一个可移植的 container 中,确保开发、staging、测试和生产环境一致。接下来,Kubernetes 通过
📋 目录
  1. 准备 Java Spring Boot 应用程序包
  2. 构建 Docker 镜像
  3. Kubernetes 安装和设置
  4. 设置 Kubernetes 集群
  5. 编写 YAML 配置
  6. 结论
  7. Docker 与 Kubernetes 协作的常见问题
A A

Docker 与 Kubernetes 协作



Previous
Quiz
Next

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!";
   }
}
Docker Working of Kubernetes 1

构建应用程序

要将应用程序打包成 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 Working of Kubernetes 2

运行以下命令验证镜像是否创建成功 −

$ docker images
Docker Working of Kubernetes 3

新创建的镜像应该出现在输出中。

其他注意事项

  • 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/
Docker Working of Kubernetes 4

将 minikube-linux-amd64 替换为适合您操作系统的相应二进制文件。

2. 启动 Minikube 集群

$ minikube start
Docker Working of Kubernetes 5

安装 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
Docker Working of Kubernetes 6

Docker Working of Kubernetes 7

这将获取 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
Docker Working of Kubernetes 8

您将看到列出一个节点,那就是 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 会根据配置自动处理容器的生命周期、负载均衡或扩展。