【问题标题】:Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden禁止:禁止对“replicas”、“template”和“updateStrategy”以外的字段更新 statefulset 规范
【发布时间】:2018-08-24 23:59:14
【问题描述】:

我使用 io.fabric8.kubernetes-client, version 3.1.8 来做 kubernetes 资源的 RollingUpdate。部署很好。但是我遇到了 StatefulSet 的例外。但如果我对 StatefulSet 使用 'kubectl apply -f ***.yaml' 也没问题。

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”无效:规范:禁止:禁止对“副本”、“模板”和“更新策略”以外的字段更新状态集规范。收到状态:状态(apiVersion=v1, code=422, details=StatusDetails(causes=[StatusCause(field=spec, message=Forbidden: 禁止对'replicas'、'template'和'updateStrategy'以外的字段的statefulset规范进行更新。原因=FieldValueForbidden、additionalProperties ={})], group=apps, kind=StatefulSet, name=pro-rabbitmq, retryAfterSeconds=null, uid=null, additionalProperties={}), kind=Status, message=StatefulSet.apps "pro-rabbitmq" 无效:规范:禁止:禁止对“副本”、“模板”和“更新策略”以外的字段的状态集规范进行更新。元数据=ListMeta(resourceVersion=null, selfLink=null, additionalProperties={}), reason=Invalid , status=Failure, additionalProperties={})。

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

【问题讨论】:

    标签: java kubernetes fabric8


    【解决方案1】:

    你可以试试这个来更新 StatefulSet

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

    如果你只想扩展,你可以试试这个

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

    【讨论】:

    • 谢谢。我用client.apps().statefulSets().withName("repl1").patch(oldStatefulSet);解决了这个问题。
    【解决方案2】:

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

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

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

    另一种方法是删除旧的statefulSet,然后再上传一个同名的新@。

    另外,如果你不使用 Kubernetes 版本,请尝试使用 1.9 以上版本,因为statefulSet 官方仅在 1.9 及以上版本中稳定。

    顺便说一句,这是 Fabric 的 GitHub 中的 bug,它可以影响您的代码。

    【讨论】:

      【解决方案3】:

      我最近也遇到了这个问题,我发现问题是客户端尝试修改 spec->selector->matchLabels->deployment,然后服务器抛出该错误,因为根据错误消息该字段不可编辑.所以,我向他们提交了issue

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

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

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

      【讨论】:

      • 谢谢。我会尝试并密切关注这个问题。
      猜你喜欢
      • 2021-06-17
      • 2019-04-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-01
      • 2011-05-10
      • 2018-01-18
      • 1970-01-01
      相关资源
      最近更新 更多