Fabric8io K8s java 客户端是否支持使用 YAML 片段的 patch() 或 rollingupdate()?
Does Fabric8io K8s java client support patch() or rollingupdate() using YAML snippets?
我正在尝试通过将部署片段作为输入来对 k8s 应用程序的 patching/rolling 升级进行编程。我使用 patch()
方法将代码片段应用到现有部署中,作为滚动更新的一部分,使用 fabric8io's k8s client APIS.. Fabric8.io kubernetes-client
版本 4.10.1
我还使用了 kubernetes-api 3.0.12.
中的一些 loadYaml 辅助方法
这是我的示例片段 - 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
我将上面的文件内容(替换了所有占位符)作为字符串发送到 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";
}
它抛出以下异常:
> 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={}).
我还用 kubectl patch deployment <DEPLOYMENT_NAME> -n <MY_NAMESPACE> --patch "$(cat adminpatch.yaml)
尝试了原始代码段(带有标签和选择器),这很好地应用了相同的代码段。
我无法获得有关 fabric8io k8s 客户端补丁 () java API 的大量文档。任何帮助将不胜感激。
这是 Fabric8io rolling API 中的相关错误:https://github.com/fabric8io/kubernetes-client/issues/1868
截至目前,我发现使用 fabri8io APIs 实现修补的一种方法是:
- 获取运行部署对象
- add/replace 个容器和新容器
- 使用
createOrReplace()
API重新部署部署对象
但是可以理解,您的补丁可能不仅仅是对容器领域的更新。在那种情况下,处理每个可编辑字段会变得混乱。
我继续使用官方 K8s 客户端的 patchNamespacedDeployment() API 来实现补丁。 https://github.com/kubernetes-client/java/blob/356109457499862a581a951a710cd808d0b9c622/examples/src/main/java/io/kubernetes/client/examples/PatchExample.java
随着 Fabric8 Kubernetes Client 的最新改进,除了使用旧答案中提到的 createOrReplace()
之外,您还可以通过 patch()
和 rolling()
API 来完成。
使用 patch()
调用修补 JSON/Yaml 字符串:
根据最新版本 v5.4.0,Fabric8 Kubernetes Client 支持通过原始字符串打补丁。它可以是 YAML 或 JSON,请参阅 PatchTest.java。下面是一个使用原始 JSON 字符串更新 Deployment 图像的示例:
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\"}]}}}}");
}
滚动更新以更改容器映像:
但是,如果您只想进行滚动更新;您可能想改用 rolling()
API。这是更新现有 Deployment 图像的样子:
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");
}
滚动更新以更改多容器部署中的多个图像:
如果你想用多个容器更新 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);
}
滚动更新重启现有部署
如果您需要重新启动现有部署,您可以使用 rolling().restart()
DSL 方法,如下所示:
try (KubernetesClient client = new DefaultKubernetesClient()) {
client.apps().deployments()
.inNamespace(namespace)
.withName(deployment.getMetadata().getName())
.rolling()
.restart();
}
我正在尝试通过将部署片段作为输入来对 k8s 应用程序的 patching/rolling 升级进行编程。我使用 patch()
方法将代码片段应用到现有部署中,作为滚动更新的一部分,使用 fabric8io's k8s client APIS.. Fabric8.io kubernetes-client
版本 4.10.1
我还使用了 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
我将上面的文件内容(替换了所有占位符)作为字符串发送到 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";
}
它抛出以下异常:
> 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={}).
我还用 kubectl patch deployment <DEPLOYMENT_NAME> -n <MY_NAMESPACE> --patch "$(cat adminpatch.yaml)
尝试了原始代码段(带有标签和选择器),这很好地应用了相同的代码段。
我无法获得有关 fabric8io k8s 客户端补丁 () java API 的大量文档。任何帮助将不胜感激。
这是 Fabric8io rolling API 中的相关错误:https://github.com/fabric8io/kubernetes-client/issues/1868
截至目前,我发现使用 fabri8io APIs 实现修补的一种方法是:
- 获取运行部署对象
- add/replace 个容器和新容器
- 使用
createOrReplace()
API重新部署部署对象
但是可以理解,您的补丁可能不仅仅是对容器领域的更新。在那种情况下,处理每个可编辑字段会变得混乱。
我继续使用官方 K8s 客户端的 patchNamespacedDeployment() API 来实现补丁。 https://github.com/kubernetes-client/java/blob/356109457499862a581a951a710cd808d0b9c622/examples/src/main/java/io/kubernetes/client/examples/PatchExample.java
随着 Fabric8 Kubernetes Client 的最新改进,除了使用旧答案中提到的 createOrReplace()
之外,您还可以通过 patch()
和 rolling()
API 来完成。
使用 patch()
调用修补 JSON/Yaml 字符串:
根据最新版本 v5.4.0,Fabric8 Kubernetes Client 支持通过原始字符串打补丁。它可以是 YAML 或 JSON,请参阅 PatchTest.java。下面是一个使用原始 JSON 字符串更新 Deployment 图像的示例:
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\"}]}}}}");
}
滚动更新以更改容器映像:
但是,如果您只想进行滚动更新;您可能想改用 rolling()
API。这是更新现有 Deployment 图像的样子:
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");
}
滚动更新以更改多容器部署中的多个图像:
如果你想用多个容器更新 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);
}
滚动更新重启现有部署
如果您需要重新启动现有部署,您可以使用 rolling().restart()
DSL 方法,如下所示:
try (KubernetesClient client = new DefaultKubernetesClient()) {
client.apps().deployments()
.inNamespace(namespace)
.withName(deployment.getMetadata().getName())
.rolling()
.restart();
}