使用Kind和Skaffold实现Kubernetes测试教程源码


在本文中,您将学习如何使用 Kind 或 Skaffold 等工具为 Kubernetes 上运行的应用程序构建集成测试。

共有三个简单的 Spring Boot 应用程序相互通信:

  • 应用first-service程序调用应用程序公开的端点caller-service,
  • 然后caller-service应用程序调用应用程序公开的端点callme-service。

简而言之,我们的目标是在 Kind 上部署所有示例应用程序,然后通过调用first-serviceKubernetes公开的端点来测试通信Service。

 GitHub 存储库

它包含三个应用程序:first-service、caller-service和callme-service。主 Skaffold 配置清单位于项目根目录中。所需的 Kubernetes YAML 清单始终放置在该k8s目录内。

使用 Skaffold 和 Jib 构建和部署
首先,让我们看看项目根目录中的主要 Maven pom.xml。我们使用最新版本的 Spring Boot 和最新 LTS 版本的 Java 进行编译。所有三个应用模块都继承了父 pom.xml 中的设置。为了使用 Maven 构建映像,我们使用了 jib-maven-plugin。由于它在默认基础映像中仍使用 Java 17,我们需要用 . 标签覆盖这一行为。我们将声明 eclipse-temurin:21-jdk-ubi9-minimal 为基本映像。请注意,只有在构建过程中启用了 jib Maven 配置文件,jib-maven-plugin 才会被激活。

<modelVersion>4.0.0</modelVersion>

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-parent</artifactId>
  <version>3.2.0</version>
  <relativePath />
</parent>

<groupId>pl.piomin.services</groupId>
<artifactId>sample-istio-services</artifactId>
<version>1.1.0</version>
<packaging>pom</packaging>

<properties>
  <java.version>21</java.version>
</properties>

<modules>
  <module>caller-service</module>
  <module>callme-service</module>
  <module>first-service</module>
</modules>

<profiles>
  <profile>
    <id>jib</id>
    <build>
      <plugins>
        <plugin>
          <groupId>com.google.cloud.tools</groupId>
          <artifactId>jib-maven-plugin</artifactId>
          <version>3.4.0</version>
          <configuration>
            <from>
              <image>eclipse-temurin:21-jdk-ubi9-minimal</image>
            </from>
          </configuration>
        </plugin>
      </plugins>
    </build>
  </profile>
</profiles>

现在,让我们来看看 skaffold.yaml 主文件。Skaffold 使用 Jib 支持构建镜像,并使用每个应用模块内 k8s/deployment.yaml 文件中的清单在 Kubernetes 上部署所有三个应用。Skaffold 禁用了 Maven 的 JUnit 测试,并激活了 jib 配置文件。激活 istio Skaffold 配置文件后,它还能部署 Istio 对象。不过,我们今天不会使用它。

apiVersion: skaffold/v4beta5
kind: Config
metadata:
  name: simple-istio-services
build:
  artifacts:
    - image: piomin/first-service
      jib:
        project: first-service
        args:
          - -Pjib
          - -DskipTests
    - image: piomin/caller-service
      jib:
        project: caller-service
        args:
          - -Pjib
          - -DskipTests
    - image: piomin/callme-service
      jib:
        project: callme-service
        args:
          - -Pjib
          - -DskipTests
  tagPolicy:
    gitCommit: {}
manifests:
  rawYaml:
    - '*/k8s/deployment.yaml'
deploy:
  kubectl: {}
profiles:
  - name: istio
    manifests:
      rawYaml:
        - k8s/istio-*.yaml
        - '*/k8s/deployment-versions.yaml'
        - '*/k8s/istio-*.yaml'


下面是我们应用程序的典型部署。应用程序在 8080 端口上运行。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: first-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: first-service
  template:
    metadata:
      labels:
        app: first-service
    spec:
      containers:
        - name: first-service
          image: piomin/first-service
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 8080
          env:
            - name: VERSION
              value: "v1"


出于测试目的,我们需要在 Kind 集群之外公开第一个服务。为此,我们将使用 Kubernetes NodePort 服务。我们的应用程序将在 30000 端口下可用。

apiVersion: v1
kind: Service
metadata:
  name: first-service
  labels:
    app: first-service
spec:
  type: NodePort
  ports:
  - port: 8080
    name: http
    nodePort: 30000
  selector:
    app: first-service


如何运行
为了在 Kind 外部公开 Kubernetes 服务,我们需要在配置清单中定义 externalPortMappings 部分。你可能还记得,我们将在 30000 端口下公开我们的应用程序。以下文件可在 k8s/kind-cluster-test.yaml 路径下的版本库中找到:

apiVersion: kind.x-k8s.io/v1alpha4
kind: Cluster
nodes:
  - role: control-plane
    extraPortMappings:
      - containerPort: 30000
        hostPort: 30000
        listenAddress: "0.0.0.0"
        protocol: tcp


假设我们已经在机器上安装了 kind CLI,我们需要执行以下命令来创建一个新群集:

$ kind create cluster --name c1 --config k8s/kind-cluster-test.yaml

我们已经准备好一个单节点 Kind 集群。Docker 上运行着一个 c1-control-plane 容器。

Kubernetes 上下文会自动切换为 kind-c1。

现在,我们只需在版本库根目录下运行以下命令,即可构建和部署应用程序:
$ skaffold run

如果在 skaffold 运行日志中看到输出,说明一切正常。

我们可以验证 Kubernetes 服务列表。
kubectl get svc

假设您已在本地安装了 Grafana k6 工具,您可以使用以下命令运行负载测试:
$ k6 run first-service/src/test/resources/k6/load-test.js