禁止访问:禁止对“复制副本”,“模板”和“updateStrategy”以外的字段更新statefulset规范

时间:2018-03-16 01:38:11

标签: java kubernetes fabric8

我使用io.fabric8.kubernetes-client,版本3.1.8来执行kubernetes资源的RollingUpdate。它适用于部署。但我遇到StatefulSet的例外。但是如果我使用'kubectl apply -f ***。yaml'作为StatefulSet也没关系。

RollingUpdate部署代码:

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()));
}

RollingUpdate 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()));
}

执行StatefulSet的RollingUpdate时的异常

  

执行失败:PUT位于:https://kubernetes.default.svc/apis/apps/v1beta1/namespaces/itsma1/statefulsets/pro-rabbitmq。消息:StatefulSet.apps“pro-rabbitmq”无效:spec:Forbidden:禁止对'replicas','template'和'updateStrategy'以外的字段更新statefulset规范。收到状态:状态(apiVersion = v1, code = 422,details = StatusDetails(cause = [StatusCause(field = spec,message = Forbidden:禁止对'replicas','template'和'updateStrategy'以外的字段更新statefulset规范。,reason = FieldValueForbidden,additionalProperties = {})],group = apps,kind = StatefulSet,name = pro-rabbitmq,retryAfterSeconds = null,uid = null,additionalProperties = {}),kind = Status,message = StatefulSet.apps“pro-rabbitmq”无效:spec:Forbidden:禁止对'replicas','template'和'updateStrategy'以外的字段更新statefulset规范。,metadata = ListMeta(resourceVersion = null,selfLink = null,additionalProperties = {}),reason = Invalid ,status = Failure,additionalProperties = {})。

我很好奇为什么错误发生以及如何解决。

3 个答案:

答案 0 :(得分:0)

在StatefulSet中,与部署不同,您只能更新有限数量的值 - replicastemplateupdateStrategy

您发布的问题是因为Fabric尝试更新无法更新的值。

您唯一能做的就是仔细准备一个新的statefulSet对象,该对象的名称与旧对象相同,但只包含可以更新的值。

替代方法是在上传具有相同名称的新statefulSet之前删除旧statefulSet

另外,如果你不这样做,请尝试使用Kubernetes版本1.9,因为crawl仅在1.9及以上版本中正式稳定。

BTW,这是Fabric的GitHub中的bug,可以影响您的代码。

答案 1 :(得分:0)

您可以尝试此操作来更新StatefulSet

client.apps().statefulSets().withName("repl1").rolling().withTimeout(5, TimeUnit.MINUTES).updateImage("");

如果您只想缩放,可以试试这个

client.apps().statefulSets().withName("repl1").scale(5, true);

答案 2 :(得分:0)

我最近也遇到了这个问题,我发现问题是客户端试图修改spec-&gt; selector-&gt; matchLabels-&gt;部署,然后服务器抛出该错误,因为该字段不可编辑基于错误消息。所以,我向他们提交了issue

但是,如果你想要对你的有状态集进行真正的“滚动”更新并且你的kube集群已经足够了,你可以尝试

k8client.apps().statefulSets().inNamespace(namespace).withName(name).cascading(false).replace(statefulSet)

cascading(false)似乎成功了,它基本上告诉客户端只更新有状态集而不首先缩小pod。如果您的更新策略正在滚动,群集将为您处理滚动过程。