We have Helm 3.0.3 and 1.18 k8s and since one year we did not face any issue like as below before. We deploy several microservices via helm to k8s and all works fine so far. But even if we did not change anything for service field we are receiving error like as below.
Here is my command how I deploy to k8s. When I uninstall the service in k8s and start re-build it works ok but when I need to push new changes ı again face this error.
+ helm upgrade --install --debug --force xx-ui-dev --values values.dev.yaml --namespace dev --set image.tag=608 .
Error
history.go:52: [debug] getting history for release xx-ui-dev
upgrade.go:120: [debug] preparing upgrade for xx-ui-dev
upgrade.go:128: [debug] performing update for xx-ui-dev
upgrade.go:292: [debug] creating upgraded release for xx-ui-dev
client.go:173: [debug] checking 7 resources for changes
client.go:432: [debug] Replaced "xx-ui-dev" with kind NetworkPolicy for kind NetworkPolicy
client.go:432: [debug] Replaced "xx-ui-dev" with kind ServiceAccount for kind ServiceAccount
client.go:432: [debug] Replaced "xx-ui-dev-auth" with kind Secret for kind Secret
client.go:432: [debug] Replaced "xx-ui-dev-config" with kind ConfigMap for kind ConfigMap
client.go:205: [debug] error updating the resource "xx-ui-dev":
failed to replace object: Service "xx-ui-dev" is invalid: spec.clusterIP: Invalid value: "": field is immutable
client.go:432: [debug] Replaced "xx-ui-dev" with kind Deployment for kind Deployment
client.go:432: [debug] Replaced "xx-ui-dev" with kind HorizontalPodAutoscaler for kind HorizontalPodAutoscaler
upgrade.go:351: [debug] warning: Upgrade "xx-ui-dev" failed: failed to replace object: Service "xx-ui-dev" is invalid: spec.clusterIP: Invalid value: "": field is immutable
Error: UPGRADE FAILED: failed to replace object: Service "xx-ui-dev" is invalid: spec.clusterIP: Invalid value: "": field is immutable
helm.go:84: [debug] failed to replace object: Service "xx-ui-dev" is invalid: spec.clusterIP: Invalid value: "": field is immutable
service.yaml
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: 50003
protocol: TCP
name: http
selector:
app.kubernetes.io/name: {{ include "xx-ui.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
tier: backend
values.dev.yaml
service:
type: ClusterIP
port: 80
When using --force
with helm upgrade
, helm is using replace strategy instead of patch.
Have a look at the following helm code:
if force {
var err error
obj, err = helper.Replace(target.Namespace, target.Name, true, target.Object)
...
} else {
patch, patchType, err := createPatch(target, currentObj)
...
// send patch to server
obj, err = helper.Patch(target.Namespace, target.Name, patchType, patch, nil)
}
Replace strategy is causing the errors you see. Have a look at this kubectl issue if you are wondering why this happens.
@matt is correct --force
use replacement strategy.
I have recently faced this issue while updating the service selectors using helm, so as a quick fix/hack I directly edit the service and make the desired changes(update the selectors), and then run the helm command to sync(helm upgrade --force release_name).
It will not show any change in the service. (Pure hack but helpful)