禁止:禁止更新 'replicas'、'template' 和 'updateStrategy' 以外的字段的 statefulset 规范
Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden
我使用 io.fabric8.kubernetes-client,版本 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()));
}
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异常
Failure executing: PUT at: https://kubernetes.default.svc/apis/apps/v1beta1/namespaces/itsma1/statefulsets/pro-rabbitmq. Message: StatefulSet.apps "pro-rabbitmq" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden.. Received status: Status(apiVersion=v1, code=422, details=StatusDetails(causes=[StatusCause(field=spec, message=Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden., reason=FieldValueForbidden, additionalProperties={})], group=apps, kind=StatefulSet, name=pro-rabbitmq, retryAfterSeconds=null, uid=null, additionalProperties={}), kind=Status, message=StatefulSet.apps "pro-rabbitmq" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden., metadata=ListMeta(resourceVersion=null, selfLink=null, additionalProperties={}), reason=Invalid, status=Failure, additionalProperties={}).
我很好奇为什么会出现错误以及如何解决。
在 StatefulSet 中,与 Deployment 不同,您只能更新有限数量的值 - replicas
、template
和 updateStrategy
。
你出现这个问题是因为 Fabric 试图更新无法更新的值。
您唯一可以做的就是仔细准备一个新的 statefulSet
对象,该对象将与旧对象同名,但仅包含您可以更新的值。
另一种方法是先删除旧的 statefulSet
,然后再上传同名的新文件。
此外,如果不使用,请尝试使用 1.9 以上的 Kubernetes 版本,因为 statefulSet
官方仅在 1.9 及更高版本中稳定。
顺便说一句,Fabric 的 GitHub 中有一个 bug 可以影响您的代码。
您可以试试这个来更新 StatefulSet
client.apps().statefulSets().withName("repl1").rolling().withTimeout(5, TimeUnit.MINUTES).updateImage("");
如果只想缩放,可以试试这个
client.apps().statefulSets().withName("repl1").scale(5, true);
我最近也有这个问题,我发现问题是客户端试图修改 spec->selector->matchLabels->deployment,然后服务器抛回那个错误,因为该字段基于错误信息。所以,我向他们提交了 issue。
但是,如果您想要真正 "rolling" 更新您的有状态集并且您的 kube 集群足够新,您可以尝试
k8client.apps().statefulSets().inNamespace(namespace).withName(name).cascading(false).replace(statefulSet)
cascading(false)
似乎成功了,它基本上告诉客户端只需更新有状态集而不先缩小 pods。如果您的更新策略是滚动的,集群将为您处理滚动过程。
我使用 io.fabric8.kubernetes-client,版本 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()));
}
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异常
Failure executing: PUT at: https://kubernetes.default.svc/apis/apps/v1beta1/namespaces/itsma1/statefulsets/pro-rabbitmq. Message: StatefulSet.apps "pro-rabbitmq" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden.. Received status: Status(apiVersion=v1, code=422, details=StatusDetails(causes=[StatusCause(field=spec, message=Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden., reason=FieldValueForbidden, additionalProperties={})], group=apps, kind=StatefulSet, name=pro-rabbitmq, retryAfterSeconds=null, uid=null, additionalProperties={}), kind=Status, message=StatefulSet.apps "pro-rabbitmq" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden., metadata=ListMeta(resourceVersion=null, selfLink=null, additionalProperties={}), reason=Invalid, status=Failure, additionalProperties={}).
我很好奇为什么会出现错误以及如何解决。
在 StatefulSet 中,与 Deployment 不同,您只能更新有限数量的值 - replicas
、template
和 updateStrategy
。
你出现这个问题是因为 Fabric 试图更新无法更新的值。
您唯一可以做的就是仔细准备一个新的 statefulSet
对象,该对象将与旧对象同名,但仅包含您可以更新的值。
另一种方法是先删除旧的 statefulSet
,然后再上传同名的新文件。
此外,如果不使用,请尝试使用 1.9 以上的 Kubernetes 版本,因为 statefulSet
官方仅在 1.9 及更高版本中稳定。
顺便说一句,Fabric 的 GitHub 中有一个 bug 可以影响您的代码。
您可以试试这个来更新 StatefulSet
client.apps().statefulSets().withName("repl1").rolling().withTimeout(5, TimeUnit.MINUTES).updateImage("");
如果只想缩放,可以试试这个
client.apps().statefulSets().withName("repl1").scale(5, true);
我最近也有这个问题,我发现问题是客户端试图修改 spec->selector->matchLabels->deployment,然后服务器抛回那个错误,因为该字段基于错误信息。所以,我向他们提交了 issue。
但是,如果您想要真正 "rolling" 更新您的有状态集并且您的 kube 集群足够新,您可以尝试
k8client.apps().statefulSets().inNamespace(namespace).withName(name).cascading(false).replace(statefulSet)
cascading(false)
似乎成功了,它基本上告诉客户端只需更新有状态集而不先缩小 pods。如果您的更新策略是滚动的,集群将为您处理滚动过程。