FunTester Fabric8 Kubernetes 教程——CSR、ListOptions、DeleteOptions

FunTester · April 04, 2025 · 53 hits

CertificateSigningRequest (CSR)

CertificateSigningRequest (CSR) 是 Kubernetes 中用于请求集群证书颁发机构(CA)签发证书的对象,通常用于为节点或用户申请 TLS 证书。

Kubernetes 客户端提供了对 CertificateSigningRequest 的支持,允许你创建、批准或拒绝 CSR。

创建 CertificateSigningRequest

try (KubernetesClient client = new KubernetesClientBuilder().build()) {
    CertificateSigningRequest csr = new CertificateSigningRequestBuilder()
            .withNewMetadata().withName("test-k8s-csr").endMetadata()
            .withNewSpec()
            .addNewGroup("system:authenticated")
            .withRequest("LS VE9PQotL BSRVFVRVNULS0tLS0K")
            .addNewUsage("FunTesterclient auth")
            .endSpec()
            .build();

    client.certificates().v1().certificateSigningRequests().resource(csr).create();
}

批准 CertificateSigningRequest

CertificateSigningRequestCondition csrCondition = new CertificateSigningRequestConditionBuilder()
        .withType("Approved")
        .withStatus("True")
        .withReason("Approved ViaRESTApi")
        .withMessage("Approved by REST API /approval endpoint.")
        .build();
client.certificates().v1().certificateSigningRequests().withName("test-k8s-csr").approve(csrCondition);

拒绝 CertificateSigningRequest

CertificateSigningRequestCondition csrCondition = new CertificateSigningRequestConditionBuilder()
        .withType("Denied")
        .withStatus("True")
        .withReason("Denied ViaRESTApi")
        .withMessage("Denied by REST API /approval endpoint.")
        .build();
client.certificates().v1().certificateSigningRequests().withName("test-k8s-csr").deny(csrCondition);

SharedInformers

SharedInformers 是 Kubernetes 客户端库(client-go)中的一种机制,用于高效地监听和缓存资源对象的变更,减少对 API Server 的请求压力,提升性能。

Kubernetes 客户端提供了 SharedInformer 支持,用于监听 Kubernetes 资源的变化。

获取 SharedInformerFactory

SharedInformerFactory sharedInformerFactory = client.informers();

创建 SharedIndexInformer 监听 Pod 资源:

SharedIndexInformer<Pod> podInformer = sharedInformerFactory.sharedIndexInformerFor(Pod.class, 30 * 1000L);
podInformer.addEventHandler(new ResourceEventHandler<Pod>() {
  @Override
  public void onAdd(Pod pod) {
    logger.info("{} pod added", pod.getMetadata().getName());
  }

  @Override
  public void onUpdate(Pod oldPod, Pod newPod) {
    logger.info("{} pod updated", oldPod.getMetadata().getName());
  }

  @Override
  public void onDelete(Pod pod, boolean deletedFinalStateUnknown) {
    logger.info("{} pod deleted", pod.getMetadata().getName());
  }
});

启动所有已注册的 Informer:

sharedInformerFactory.startAllRegisteredInformers();

停止所有已注册的 Informer:

sharedInformerFactory.stopAllRegisteredInformers();

创建命名空间的 SharedIndexInformer

SharedIndexInformer<Pod> podInformer = client.pods().inNamespace("default").inform(new ResourceEventHandler<>() {
    @Override
    public void onAdd(Pod pod) {
        logger.info("Pod " + pod.getMetadata().getName() + " got added");
    }

    @Override
    public void onUpdate(Pod oldPod, Pod newPod) {
        logger.info("Pod " + oldPod.getMetadata().getName() + " got updated");
    }

    @Override
    public void onDelete(Pod pod, boolean deletedFinalStateUnknown) {
        logger.info("Pod " + pod.getMetadata().getName() + " got deleted");
    }
},  30 * 1000L);

ListOptions

Kubernetes 客户端提供了多种选项来列出资源。

分页列表:

PodList podList = client.pods().inNamespace("FunTester").list(new ListOptionsBuilder().withLimit(5L).build());

podList = client.pods().inNamespace("FunTester").list(new ListOptionsBuilder().withLimit(5L)
        .withContinue(podList.getMetadata().getContinue())
        .build());

列出包含特定标签的资源:

PodList podList = client.pods().inNamespace("FunTester").withLabel("foo", "bar").list();

使用 ListOptions 列出资源:

PodList podList = client.pods().inNamespace("FunTester").list(new ListOptionsBuilder()
  .withLimit(1L)
  .withContinue(null)
  .build());

DeleteOptions

Kubernetes 客户端提供了删除资源及其依赖项的方法。

删除资源及其依赖项:

client.apps().deployments().inNamespace("default").withName("nginx-deploy").cascading(true).delete();

指定删除的宽限期:

client.apps().deployments().inNamespace("FunTester").withName("mydeployment").withPropagationPolicy(DeletionPropagation.FOREGROUND).withGracePeriod(10).delete();

WatchOptions

Kubernetes 客户端提供了多种方式来使用 Watch

使用 ListOptions 进行观察:

client.pods().watch(new ListOptionsBuilder().withTimeoutSeconds(30L).build(), new Watcher<>() {
  @Override
  public void eventReceived(Action action, Pod resource) { }

  @Override
  public void onClose(WatcherException cause) { }
});

LogOptions

获取特定容器的日志:

client.pods().inNamespace("FunTester").withName("foo").inContainer("container1").getLog();

获取最近日志文件的行数:

client.pods().inNamespace("FunTester").withName("foo").tailingLines(10).getLog();

序列化为 YAML

将资源导出为 YAML 字符串:

Pod myPod;
String myPodAsYaml = Serialization.asYaml(myPod);

运行 Pod

通过提供镜像和名称来运行 Pod

try (KubernetesClient client = new KubernetesClientBuilder().build()) {
    client.run().inNamespace("default")
            .withName("FunTester")
            .withImage("FunTester/FunTester:3.12.9")
            .done();
}

服务器端应用

创建或更新资源:

DeploymentConfig dc = client.deploymentConfigs().inNamespace("FunTester").resource(dcToCreate).serverSideApply();

强制更新资源:

DeploymentConfig dc = client.deploymentConfigs().inNamespace("FunTester").resource(dcToCreate).forceConflicts().serverSideApply();

通过这些 API,你可以灵活地管理和操作 Kubernetes 集群中的各种资源,无论是内置资源还是自定义资源。

最佳实践建议

  1. 资源清理:始终使用 try-with-resources 确保客户端正确关闭
  2. 错误处理:对所有 Kubernetes API 调用实现健壮的错误处理
  3. 性能优化
    • 对大列表使用分页查询
    • 优先使用 SharedInformer 而非直接 Watch
  4. 安全实践
    • 为客户端配置适当的 RBAC 权限
    • 敏感操作添加审计日志
  5. 配置管理
    • 外部化配置参数
    • 实现配置的热更新

通过合理运用这些 API 和最佳实践,开发者可以构建出高效、可靠的 Kubernetes 管理应用,满足企业级容器平台的管理需求。

FunTester 原创精华
【免费合集】从 Java 开始性能测试
故障测试与 Web 前端
服务端功能测试
性能测试专题
Java、Groovy、Go
测试开发、自动化、白盒
测试理论、FunTester 风采
视频专题
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
No Reply at the moment.
需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up