Fabric8io K8s java 客户端是否支持使用 YAML 片段的 patch() 或 rollingupdate()?

A.R*_*K.S 6 fabric8 kubernetes

我正在尝试通过将部署片段作为输入来对 k8s 应用程序的修补/滚动升级进行编程。我使用patch()方法将代码片段应用到现有部署上,作为使用fabric8io 的 k8s 客户端 APIS 的滚动更新的一部分。 Fabric8.iokubernetes-client版本4.10.1 我还使用了一些 loadYaml 辅助方法kubernetes-api 3.0.12.

这是我的示例片段 - adminpatch.yaml 文件:

    kind: Deployment   
    spec:
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxSurge: 1
          maxUnavailable: 0     
      template:
        spec:
          containers:
            - name: ${PATCH_IMAGE_NAME}
              image: ${PATCH_IMAGE_URL}
              imagePullPolicy: Always
Run Code Online (Sandbox Code Playgroud)

我将上述文件内容(替换了所有占位符)作为字符串发送到 patchDeployment() 方法。这是我对 fabric8 patch() 方法的调用:

     public static String patchDeployment(String deploymentName, String namespace, String deploymentYaml) {
    try {
    Deployment deploymentSnippet = (Deployment) getK8sObject(deploymentYaml);
    if(deploymentSnippet instanceof Deployment) {
            logger.debug("Valid deployment object.");
    Deployment deployment = getK8sClient().apps().deployments().inNamespace(namespace).withName(deploymentName)
        .rolling().patch(deploymentSnippet);
    System.out.println(deployment.toString());
    return getLastConfig(deployment.getMetadata(), deployment);
    }
    } catch (Exception Ex) {
      Ex.printStackTrace();
    }
      return "Failed";
  }

Run Code Online (Sandbox Code Playgroud)

它抛出以下异常:

> io.fabric8.kubernetes.client.KubernetesClientException: Failure
> executing: PATCH at:
> https://10.44.4.126:6443/apis/apps/v1/namespaces/default/deployments/patch-demo.
> Message: Deployment.apps "patch-demo" is invalid: spec.selector:
> Invalid value:
> v1.LabelSelector{MatchLabels:map[string]string{"app":"nginx",
> "deployment":"3470574ffdbd6e88d426a77dd951ed45"},
> MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is
> immutable. Received status: Status(apiVersion=v1, code=422,
> details=StatusDetails(causes=[StatusCause(field=spec.selector,
> message=Invalid value:
> v1.LabelSelector{MatchLabels:map[string]string{"app":"nginx",
> "deployment":"3470574ffdbd6e88d426a77dd951ed45"},
> MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is
> immutable, reason=FieldValueInvalid, additionalProperties={})],
> group=apps, kind=Deployment, name=patch-demo, retryAfterSeconds=null,
> uid=null, additionalProperties={}), kind=Status,
> message=Deployment.apps "patch-demo" is invalid: spec.selector:
> Invalid value:
> v1.LabelSelector{MatchLabels:map[string]string{"app":"nginx",
> "deployment":"3470574ffdbd6e88d426a77dd951ed45"},
> MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is
> immutable, metadata=ListMeta(_continue=null, remainingItemCount=null,
> resourceVersion=null, selfLink=null, additionalProperties={}),
> reason=Invalid, status=Failure, additionalProperties={}).

Run Code Online (Sandbox Code Playgroud)

我还尝试了原始片段(带有标签和选择器),kubectl patch deployment <DEPLOYMENT_NAME> -n <MY_NAMESPACE> --patch "$(cat adminpatch.yaml)这适用于相同的片段。

我无法获得有关 fabric8io k8s 客户端 patch() java API 的太多文档。任何帮助将不胜感激。

Roh*_*mar 2

通过 Fabric8 Kubernetes 客户端的最新改进,除了使用旧答案中提到的方法之外,您还可以通过 APIpatch()来完成此操作。rolling()createOrReplace()

使用调用修补 JSON/Yaml 字符串patch()

根据最新版本 v5.4.0,Fabric8 Kubernetes Client 支持通过原始字符串进行修补。它可以是 YAML 或 JSON,请参阅PatchTest.java。以下是使用原始 JSON 字符串更新部署映像的示例:

try (KubernetesClient kubernetesClient = new DefaultKubernetesClient()) {
  kubernetesClient.apps().deployments()
    .inNamespace(deployment.getMetadata().getNamespace())
    .withName(deployment.getMetadata().getName())
    .patch("{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"patch-demo-ctr-2\",\"image\":\"redis\"}]}}}}");
}
Run Code Online (Sandbox Code Playgroud)

滚动更新以更改容器映像:

但是,如果您只想进行滚动更新;您可能想改用rolling()API。以下是更新现有部署的映像的样子:

try (KubernetesClient client = new DefaultKubernetesClient()) {
    // ... Create Deployment 

    // Update Deployment for a single container Deployment
    client.apps().deployments()
            .inNamespace(namespace)
            .withName(deployment.getMetadata().getName())
            .rolling()
            .updateImage("gcr.io/google-samples/hello-app:2.0");
}
Run Code Online (Sandbox Code Playgroud)

滚动更新以更改多容器部署中的多个映像:

如果您想更新具有多个容器的 Deployment。您需要使用updateImage(Map<String, String>)方法来代替。下面是它的用法示例:

try (KubernetesClient client = new DefaultKubernetesClient()) {
    Map<String, String> containerToImageMap = new HashMap<>();
    containerToImageMap.put("nginx", "stable-perl");
    containerToImageMap.put("hello", "hello-world:linux");
    client.apps().deployments()
            .inNamespace(namespace)
            .withName("multi-container-deploy")
            .rolling()
            .updateImage(containerToImageMap);
}
Run Code Online (Sandbox Code Playgroud)

滚动更新 重新启动现有部署

如果您需要重新启动现有的部署,您可以使用rolling().restart()DSL 方法,如下所示:

try (KubernetesClient client = new DefaultKubernetesClient()) {
    client.apps().deployments()
            .inNamespace(namespace)
            .withName(deployment.getMetadata().getName())
            .rolling()
            .restart();
}
Run Code Online (Sandbox Code Playgroud)