如何 运行 spring 在 Kubernetes 中启动集成测试
How to run spring boot integration test in Kubernetes
我在 src/intrgTest/groovy
位置对我的 spring 启动应用程序进行了简单的集成测试,下面是测试
@AutoConfigureMockMvc
@WebMvcTest
class WebControllerTest extends Specification {
@Autowired
private MockMvc mvc
def "when get is performed then the response has status 200 and content is 'Hello world!'"() {
expect: "Status is 200 and the response is 'Hello world!'"
mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andReturn()
.response
.contentAsString == "Hello world!"
}
}
当我在 Kubernetes 中创建一个 pod 时,我想 运行 这个测试用例来检查应用程序是否正常工作。我怎样才能做到这一点?
下面是 kubernetes
的 deployment.yml 文件
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: spring-boot-deployment
spec:
selector:
matchLabels:
app: spring-boot-app
replicas: 2
template:
metadata:
labels:
app: spring-boot-app
spec:
containers:
- name: spring-boot-app
image: spring-boot-test-images:63
ports:
- containerPort: 80
查看测试,它是健康检查而不是集成测试。理想情况下,集成测试应该 运行 使用 mvn test
作为持续集成的一部分,然后再执行实际部署,而不是之后。
你真的不需要写一个健康检查的测试,然后在应用程序部署到kubernetes上后执行它。您可以简单地在部署 yaml 中定义 readiness probe,Kubernetes 将在将 pod 标记为 READY 并开始向其发送流量之前执行健康检查。
如果您使用 spring 启动版本早于 2.3,那么您可以使用执行器端点 /actuator/health
,如果您使用 spring 启动 2.3,则 /actuator/health/readiness
端点作为就绪探测器。
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: spring-boot-deployment
spec:
selector:
matchLabels:
app: spring-boot-app
replicas: 2
template:
metadata:
labels:
app: spring-boot-app
spec:
containers:
- name: spring-boot-app
image: spring-boot-test-images:63
ports:
- containerPort: 80
readinessProbe:
httpGet:
port: 8080
path: /actuator/health
initialDelaySeconds: 10
如果你想在某些外部系统(如 redis 或 dynamo)上进行健康检查,你可以为此编写 custom health indicator。以下示例来自 spring,提供 RedisHealthIndicator
public class RedisHealthIndicator extends AbstractHealthIndicator {
private final RedisConnectionFactory redisConnectionFactory;
public RedisHealthIndicator(RedisConnectionFactory connectionFactory) {
super("Redis health check failed");
Assert.notNull(connectionFactory, "ConnectionFactory must not be null");
this.redisConnectionFactory = connectionFactory;
}
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
RedisConnection connection = RedisConnectionUtils.getConnection(this.redisConnectionFactory);
try {
doHealthCheck(builder, connection);
}
finally {
RedisConnectionUtils.releaseConnection(connection, this.redisConnectionFactory, false);
}
}
private void doHealthCheck(Health.Builder builder, RedisConnection connection) {
if (connection instanceof RedisClusterConnection) {
RedisHealth.up(builder, ((RedisClusterConnection) connection).clusterGetClusterInfo());
}
else {
RedisHealth.up(builder, connection.info());
}
}
}
我在 src/intrgTest/groovy
位置对我的 spring 启动应用程序进行了简单的集成测试,下面是测试
@AutoConfigureMockMvc
@WebMvcTest
class WebControllerTest extends Specification {
@Autowired
private MockMvc mvc
def "when get is performed then the response has status 200 and content is 'Hello world!'"() {
expect: "Status is 200 and the response is 'Hello world!'"
mvc.perform(get("/hello"))
.andExpect(status().isOk())
.andReturn()
.response
.contentAsString == "Hello world!"
}
}
当我在 Kubernetes 中创建一个 pod 时,我想 运行 这个测试用例来检查应用程序是否正常工作。我怎样才能做到这一点?
下面是 kubernetes
的 deployment.yml 文件apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: spring-boot-deployment
spec:
selector:
matchLabels:
app: spring-boot-app
replicas: 2
template:
metadata:
labels:
app: spring-boot-app
spec:
containers:
- name: spring-boot-app
image: spring-boot-test-images:63
ports:
- containerPort: 80
查看测试,它是健康检查而不是集成测试。理想情况下,集成测试应该 运行 使用 mvn test
作为持续集成的一部分,然后再执行实际部署,而不是之后。
你真的不需要写一个健康检查的测试,然后在应用程序部署到kubernetes上后执行它。您可以简单地在部署 yaml 中定义 readiness probe,Kubernetes 将在将 pod 标记为 READY 并开始向其发送流量之前执行健康检查。
如果您使用 spring 启动版本早于 2.3,那么您可以使用执行器端点 /actuator/health
,如果您使用 spring 启动 2.3,则 /actuator/health/readiness
端点作为就绪探测器。
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: spring-boot-deployment
spec:
selector:
matchLabels:
app: spring-boot-app
replicas: 2
template:
metadata:
labels:
app: spring-boot-app
spec:
containers:
- name: spring-boot-app
image: spring-boot-test-images:63
ports:
- containerPort: 80
readinessProbe:
httpGet:
port: 8080
path: /actuator/health
initialDelaySeconds: 10
如果你想在某些外部系统(如 redis 或 dynamo)上进行健康检查,你可以为此编写 custom health indicator。以下示例来自 spring,提供 RedisHealthIndicator
public class RedisHealthIndicator extends AbstractHealthIndicator {
private final RedisConnectionFactory redisConnectionFactory;
public RedisHealthIndicator(RedisConnectionFactory connectionFactory) {
super("Redis health check failed");
Assert.notNull(connectionFactory, "ConnectionFactory must not be null");
this.redisConnectionFactory = connectionFactory;
}
@Override
protected void doHealthCheck(Health.Builder builder) throws Exception {
RedisConnection connection = RedisConnectionUtils.getConnection(this.redisConnectionFactory);
try {
doHealthCheck(builder, connection);
}
finally {
RedisConnectionUtils.releaseConnection(connection, this.redisConnectionFactory, false);
}
}
private void doHealthCheck(Health.Builder builder, RedisConnection connection) {
if (connection instanceof RedisClusterConnection) {
RedisHealth.up(builder, ((RedisClusterConnection) connection).clusterGetClusterInfo());
}
else {
RedisHealth.up(builder, connection.info());
}
}
}