我使用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 = {})。
我很好奇为什么错误发生以及如何解决。
答案 0 :(得分:0)
在StatefulSet中,与部署不同,您只能更新有限数量的值 - replicas
,template
和updateStrategy
。
您发布的问题是因为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。如果您的更新策略正在滚动,群集将为您处理滚动过程。