禁止:禁止更新除“副本”、“模板”和“更新策略”以外的字段的 statefulset 规范

Cai*_*ain 6 java fabric8 kubernetes

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

滚动更新部署的代码:

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()));
}
Run Code Online (Sandbox Code Playgroud)

滚动更新 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()));
}
Run Code Online (Sandbox Code Playgroud)

对 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 规范。,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 规范

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

Ant*_*nko 6

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

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

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

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

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

顺便说一句, Fabric 的 GitHub 中有一个错误,它可能会影响您的代码。


小智 3

您可以尝试这个来更新 StatefulSet

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

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

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