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

FunTester · 2025年04月04日 · 98 次阅读

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 风采
视频专题
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册