Java 禁止:对除';复制品'';模板';,和';更新策略';禁止
我使用io.fabric8.kubernetes-client,版本3.1.8对kubernetes资源进行RollingUpdate。这对于部署来说很好。但我遇到了StatefulSet的一个例外。但是如果我对StatefulSet使用'kubectl apply-f***.yaml'也可以 滚动更新部署的代码:Java 禁止:对除';复制品'';模板';,和';更新策略';禁止,java,kubernetes,fabric8,Java,Kubernetes,Fabric8,我使用io.fabric8.kubernetes-client,版本3.1.8对kubernetes资源进行RollingUpdate。这对于部署来说很好。但我遇到了StatefulSet的一个例外。但是如果我对StatefulSet使用'kubectl apply-f***.yaml'也可以 滚动更新部署的代码: public void createOrReplaceResourceByYaml(String namespace, KubernetesResource resource) {
public void createOrReplaceResourceByYaml(String namespace, KubernetesResource resource) {
KubernetesClient client = k8sRestClient.newKubeClient();
Deployment deployment = (Deployment) resource;
logger.info(String.format("Create/Replace Deployment [%s] in namespace [%s].", ((Deployment) resource).getMetadata().getName(), namespace));
NonNamespaceOperation<Deployment, DeploymentList, DoneableDeployment, ScalableResource<Deployment, DoneableDeployment>> deployments = client.extensions().deployments().inNamespace(namespace);
Deployment result = deployments.createOrReplace(deployment);
logger.info(String.format("Created/Replaced Deployment [%s].", result.getMetadata().getName()));
}
public void createorreplacesourcebyyaml(字符串名称空间,KubernetesResource资源){
KubernetesClient=k8sRestClient.newKubeClient();
部署=(部署)资源;
logger.info(String.format(“在命名空间[%s]中创建/替换部署[%s]”,((部署)资源).getMetadata().getName(),命名空间));
NonNamespaceOperation deployments=client.extensions().deployments().inNamespace(命名空间);
部署结果=部署。createOrReplace(部署);
logger.info(String.format(“创建/替换的部署[%s]”,result.getMetadata().getName());
}
滚动更新状态集的代码
public void createOrReplaceResourceByYaml(String namespace, KubernetesResource resource) {
KubernetesClient client = k8sRestClient.newKubeClient();
StatefulSet statefulSet = (StatefulSet) resource;
logger.info(String.format("Create/Replace StatefulSet [%s] in namespace [%s].", statefulSet.getMetadata().getName(), namespace));
NonNamespaceOperation<StatefulSet, StatefulSetList, DoneableStatefulSet, RollableScalableResource<StatefulSet, DoneableStatefulSet>> statefulSets = client.apps().statefulSets().inNamespace(namespace);
StatefulSet result = statefulSets.createOrReplace(statefulSet);
logger.info(String.format("Created/Replaced StatefulSet [%s].", result.getMetadata().getName()));
}
public void createorreplacesourcebyyaml(字符串名称空间,KubernetesResource资源){
KubernetesClient=k8sRestClient.newKubeClient();
StatefulSet StatefulSet=(StatefulSet)资源;
logger.info(String.format(“在命名空间[%s]中创建/替换StatefulSet[%s]”,StatefulSet.getMetadata().getName(),命名空间));
NonNamespaceOperation statefulSets=client.apps().statefulSets().inNamespace(命名空间);
StatefulSet结果=StatefulSet.createOrReplace(StatefulSet);
logger.info(String.format(“创建/替换的状态集[%s]”,result.getMetadata().getName());
}
执行状态集的RollingUpdate时出现异常
public void createOrReplaceResourceByYaml(String namespace, KubernetesResource resource) {
KubernetesClient client = k8sRestClient.newKubeClient();
StatefulSet statefulSet = (StatefulSet) resource;
logger.info(String.format("Create/Replace StatefulSet [%s] in namespace [%s].", statefulSet.getMetadata().getName(), namespace));
NonNamespaceOperation<StatefulSet, StatefulSetList, DoneableStatefulSet, RollableScalableResource<StatefulSet, DoneableStatefulSet>> statefulSets = client.apps().statefulSets().inNamespace(namespace);
StatefulSet result = statefulSets.createOrReplace(statefulSet);
logger.info(String.format("Created/Replaced StatefulSet [%s].", result.getMetadata().getName()));
}
执行失败:放置在:。消息:StatefulSet.apps“pro rabbitmq”无效:规范:禁止:禁止对“副本”、“模板”和“UpdateStregy”以外的字段更新StatefulSet规范。。接收状态:状态(apiVersion=v1,代码=422,详细信息=StatusDetails(原因=[StatusCause(field=spec,message=Forbidden:禁止对除“replicas”、“template”和“UpdateStregy”以外的字段更新StatefolSet spec.,原因=FieldValueForbidden,additionalProperties={})],group=apps,kind=StatefulSet,name=pro-rabbitmq,retryAfterSeconds=null,uid=null,additionalProperties={}),kind=StatefulSet.apps“pro-rabbitmq”无效:规范:禁止:禁止为“副本”、“模板”和“updateStrategy”以外的字段更新StatefulSet规范,元数据=ListMeta(resourceVersion=null,selfLink=null,additionalProperties={}),reason=Invalid,status=Failure,additionalProperties={})
我很好奇为什么会发生错误以及如何修复它。与部署不同,在statefolset中,您只能更新数量有限的值-
副本
,模板
,以及更新策略
发生此问题是因为Fabric尝试更新无法更新的值
您唯一能做的就是仔细准备一个新的statefulSet
对象,该对象将与旧对象同名,但只包含您可以更新的值
另一种方法是先删除旧的statefulSet
,然后再上载同名的新文件
此外,如果您不使用Kubernetes版本1.9,请尝试使用1.9以上版本,因为statefulSet
仅在1.9及以上版本中是正式稳定的
顺便说一句,这里有一个in Fabric的GitHub,它可以影响您的代码。您可以尝试更新StatefulSet
public void createOrReplaceResourceByYaml(String namespace, KubernetesResource resource) {
KubernetesClient client = k8sRestClient.newKubeClient();
StatefulSet statefulSet = (StatefulSet) resource;
logger.info(String.format("Create/Replace StatefulSet [%s] in namespace [%s].", statefulSet.getMetadata().getName(), namespace));
NonNamespaceOperation<StatefulSet, StatefulSetList, DoneableStatefulSet, RollableScalableResource<StatefulSet, DoneableStatefulSet>> statefulSets = client.apps().statefulSets().inNamespace(namespace);
StatefulSet result = statefulSets.createOrReplace(statefulSet);
logger.info(String.format("Created/Replaced StatefulSet [%s].", result.getMetadata().getName()));
}
client.apps();
如果您只想缩放,您可以尝试此方法
client.apps().statefulSets().withName(“repl1”).scale(5,true);
我最近也遇到了这个问题,我发现问题是客户机试图修改spec->selector->matchLabels->deployment,然后服务器抛出这个错误,因为根据错误消息,该字段不可编辑。因此,我向他们提交了一个
然而,如果您想要对有状态集进行真正的“滚动”更新,并且kube集群足够新,那么您可以尝试这样做
k8client.apps()
cascading(false)
似乎成功了,它基本上告诉客户端只需更新状态集,而不必先缩小POD。如果您的更新策略正在运行,集群将为您处理滚动过程。谢谢。我使用client.apps().statefulset().withName(“repl1”).patch(oldStatefulSet);
来解决这个问题。谢谢。我将尝试并密切关注这个问题。