Eu uso o seguinte para instalar / atualizar um gráfico:
./helm upgrade --install
--set rbac.create = false
--set controller.replicaCount = 2
--set controller.service.loadBalancerIP = $ ip
--wait main-ingresso estável / nginx-ingress
(Onde $ ip é um IP, por exemplo, 10.0.0.1)
Isso é feito em um pipeline de CI / CD, então a ideia é instalar pela primeira vez, atualizar nas próximas vezes.
Ele instala bem. Na segunda execução, ele produz o seguinte:
_client.go: 339: Não é possível corrigir o serviço: "main-ingress-nginx-ingress-controller" (o serviço "main-ingress-nginx-ingress-controller" é inválido: spec.clusterIP: Valor inválido: "": o campo é imutável )
client.go: 358: Use --force para forçar a recriação do recurso
client.go: 339: Não é possível corrigir o serviço: "main-ingress-nginx-ingress-default-backend" (o serviço "main-ingress-nginx-ingress-default-backend" é inválido: spec.clusterIP: Valor inválido: "" : o campo é imutável)
client.go: 358: Use --force para forçar a recriação do recurso
Erro: FALHA NO ATUALIZAÇÃO: o serviço "main-ingress-nginx-ingress-controller" é inválido: spec.clusterIP: Valor inválido: "": o campo é imutável && O serviço "main-ingress-nginx-ingress-default-backend" é inválido : spec.clusterIP: Valor inválido: "": o campo é imutável_
Eu também pego isso na lista de leme:
NOME NOME DA REVISÃO TABELA DE STATUS ATUALIZADA
main-ingress default 1 2019-09-06 13: 17: 33.8463781 -0400 EDT implantado nginx-ingress-1.18.0
main-ingress default 2 2019-09-06 13: 21: 11.6428945 -0400 EDT falhou nginx-ingress-1.18.0
Portanto, o lançamento falhou.
Não tive esse problema com o Helm 2. É devido a uma mudança de comportamento no Helm 3 ou é um bug? Se for o primeiro, como eu poderia alterar o comando para não ter esse problema?
Resultado de helm version
: version.BuildInfo {Version: "v3.0.0-beta.2", GitCommit: "26c7338408f8db593f93cd7c963ad56f67f662d4", GitTreeState: "clean", GoVersion: "go1.12.9"}
Saída de kubectl version
: Versão do cliente: version.Info {Principal: "1", Secundária: "12", GitVersion: "v1.12.0", GitCommit: "0ed33881dc4355495f623c6f22e7dd0b7632b7c0", GitTreeState: "clean", BuildDate: "2018-09-27T17: 05: 32Z", GoVersion: "go1.10.4", Compilador: "gc", Plataforma: "linux / amd64"}
Versão do servidor: version.Info {Major: "1", Minor: "13", GitVersion: "v1.13.10", GitCommit: "37d169313237cb4ceb2cc4bef300f2ae3053c1a2", GitTreeState: "clean", BuildDate: "2019-08-19T10: 44: 49Z ", GoVersion:" go1.11.13 ", Compilador:" gc ", Plataforma:" linux / amd64 "}
Provedor / plataforma de nuvem (AKS, GKE, Minikube etc.): AKS
Isso provavelmente está relacionado a uma mudança recente no Helm 3, onde agora ele usa uma estratégia de patch de mesclagem de três vias semelhante ao kubectl. Veja # 6124
Se você puder fornecer etapas sobre como reproduzir isso, seria maravilhoso. Obrigado!
Certo!
Eu criei um cluster AKS.
Eu crio um IP público no grupo de recursos MC_ *.
Guardei o endereço IP desse IP público em $ ip.
Então, basicamente, executei esse comando duas vezes:
./helm upgrade --install
--set rbac.create = false
--set controller.replicaCount = 2
--set controller.service.loadBalancerIP = $ ip
--wait main-ingresso estável / nginx-ingress
Isso é semelhante ao que é feito em https://docs.microsoft.com/en-us/azure/aks/ingress-static-ip.
A diferença é que eu faço uma atualização do leme - instalar duas vezes. O objetivo disso é ter uma única linha de comando (incondicional) no meu CI / CD.
Avise-me se precisar de mais detalhes para reproduzir.
Isso foi o suficiente para reproduzir? Posso fornecer um script bash se ajudar.
Desculpe, estou fora do Helm Summit EU esta semana, então não tive tempo de responder ainda.
Ah ... não se preocupe. Aproveite o cume!
Também estou tendo esse problema
$ helm version --short
v3.0.0-beta.3+g5cb923e
O gráfico nginx-ingress pode ser instalado bem na primeira execução, no entanto, em uma atualização ...
$ helm upgrade --install first-chart stable/nginx-ingress --namespace infra
client.go:357: Cannot patch Service: "first-chart-nginx-ingress-controller" (Service "first-chart-nginx-ingress-controller" is invalid: spec.clusterIP: Invalid value: "": field is immutable)
client.go:376: Use --force to force recreation of the resource
client.go:357: Cannot patch Service: "first-chart-nginx-ingress-default-backend" (Service "first-chart-nginx-ingress-default-backend" is invalid: spec.clusterIP: Invalid value: "": field is immutable)
client.go:376: Use --force to force recreation of the resource
Error: UPGRADE FAILED: Service "first-chart-nginx-ingress-controller" is invalid: spec.clusterIP: Invalid value: "": field is immutable && Service "first-chart-nginx-ingress-default-backend" is invalid: spec.clusterIP: Invalid value: "": field is immutable
$ helm ls -n infra
NAME NAMESPACE REVISION UPDATED STATUS CHART
first-chart infra 1 2019-09-17 16:15:25.513997106 -0500 CDT deployed nginx-ingress-1.20.0
first-chart infra 2 2019-09-17 16:15:30.845249671 -0500 CDT failed nginx-ingress-1.20.0
Acredito que esse seja um problema com o gráfico nginx-ingress, não com o helm3. Por padrão, o gráfico sempre tentará passar controller.service.clusterIP = ""
e defaultBackend.service.clusterIP = ""
menos que você defina controller.service.omitClusterIP=true
e defaultBackend.service.omitClusterIP=true
.
link para fontes:
https://github.com/helm/charts/blob/master/stable/nginx-ingress/values.yaml#L321
https://github.com/helm/charts/blob/master/stable/nginx-ingress/templates/controller-service.yaml#L22
Gambiarra:
$ helm upgrade --install ingress-test stable/nginx-ingress --set controller.service.omitClusterIP=true --set defaultBackend.service.omitClusterIP=true
Já tentei, mas continuo recebendo o mesmo erro
helm upgrade --install ingx stable/nginx-ingress -f ingx-values.yaml 1 ↵
client.go:357: Cannot patch Service: "ingx-nginx-ingress-controller" (Service "ingx-nginx-ingress-controller" is invalid: spec.clusterIP: Invalid value: "": field is immutable)
client.go:376: Use --force to force recreation of the resource
client.go:357: Cannot patch Service: "ingx-nginx-ingress-default-backend" (Service "ingx-nginx-ingress-default-backend" is invalid: spec.clusterIP: Invalid value: "": field is immutable)
client.go:376: Use --force to force recreation of the resource
Error: UPGRADE FAILED: Service "ingx-nginx-ingress-controller" is invalid: spec.clusterIP: Invalid value: "": field is immutable && Service "ingx-nginx-ingress-default-backend" is invalid: spec.clusterIP: Invalid value: "": field is immutable
ingx-values.yaml
rbac:
create: true
controller:
service:
externalTrafficPolicy: Local
omitClusterIP: true
autoscaling:
enabled: true
minReplicas: 2
maxReplicas: 100
targetCPUUtilizationPercentage: "70"
targetMemoryUtilizationPercentage: "70"
defaultBackend:
service:
omitClusterIP: true
Como você pode ver abaixo, o modelo não tem clusterIP nele
template helm ingx stable / nginx-ingress -f ingx-values.yaml
---
# Source: nginx-ingress/templates/controller-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.20.0
heritage: Helm
release: ingx
name: ingx-nginx-ingress
---
# Source: nginx-ingress/templates/default-backend-serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.20.0
heritage: Helm
release: ingx
name: ingx-nginx-ingress-backend
---
# Source: nginx-ingress/templates/clusterrole.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRole
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.20.0
heritage: Helm
release: ingx
name: ingx-nginx-ingress
rules:
- apiGroups:
- ""
resources:
- configmaps
- endpoints
- nodes
- pods
- secrets
verbs:
- list
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- update
- watch
- apiGroups:
- extensions
- "networking.k8s.io" # k8s 1.14+
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
- apiGroups:
- extensions
- "networking.k8s.io" # k8s 1.14+
resources:
- ingresses/status
verbs:
- update
---
# Source: nginx-ingress/templates/clusterrolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.20.0
heritage: Helm
release: ingx
name: ingx-nginx-ingress
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: ingx-nginx-ingress
subjects:
- kind: ServiceAccount
name: ingx-nginx-ingress
namespace: default
---
# Source: nginx-ingress/templates/controller-role.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: Role
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.20.0
heritage: Helm
release: ingx
name: ingx-nginx-ingress
rules:
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
- endpoints
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- update
- watch
- apiGroups:
- extensions
- "networking.k8s.io" # k8s 1.14+
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
- "networking.k8s.io" # k8s 1.14+
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- ""
resources:
- configmaps
resourceNames:
- ingress-controller-leader-nginx
verbs:
- get
- update
- apiGroups:
- ""
resources:
- configmaps
verbs:
- create
- apiGroups:
- ""
resources:
- endpoints
verbs:
- create
- get
- update
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
---
# Source: nginx-ingress/templates/controller-rolebinding.yaml
apiVersion: rbac.authorization.k8s.io/v1beta1
kind: RoleBinding
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.20.0
heritage: Helm
release: ingx
name: ingx-nginx-ingress
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: ingx-nginx-ingress
subjects:
- kind: ServiceAccount
name: ingx-nginx-ingress
namespace: default
---
# Source: nginx-ingress/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.20.0
component: "controller"
heritage: Helm
release: ingx
name: ingx-nginx-ingress-controller
spec:
externalTrafficPolicy: "Local"
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
app: nginx-ingress
component: "controller"
release: ingx
type: "LoadBalancer"
---
# Source: nginx-ingress/templates/default-backend-service.yaml
apiVersion: v1
kind: Service
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.20.0
component: "default-backend"
heritage: Helm
release: ingx
name: ingx-nginx-ingress-default-backend
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
selector:
app: nginx-ingress
component: "default-backend"
release: ingx
type: "ClusterIP"
---
# Source: nginx-ingress/templates/controller-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.20.0
component: "controller"
heritage: Helm
release: ingx
name: ingx-nginx-ingress-controller
spec:
replicas: 1
revisionHistoryLimit: 10
strategy:
{}
minReadySeconds: 0
template:
metadata:
labels:
app: nginx-ingress
component: "controller"
release: ingx
spec:
dnsPolicy: ClusterFirst
containers:
- name: nginx-ingress-controller
image: "quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.25.1"
imagePullPolicy: "IfNotPresent"
args:
- /nginx-ingress-controller
- --default-backend-service=default/ingx-nginx-ingress-default-backend
- --election-id=ingress-controller-leader
- --ingress-class=nginx
- --configmap=default/ingx-nginx-ingress-controller
securityContext:
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
runAsUser: 33
allowPrivilegeEscalation: true
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
livenessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
readinessProbe:
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 1
successThreshold: 1
failureThreshold: 3
resources:
{}
hostNetwork: false
serviceAccountName: ingx-nginx-ingress
terminationGracePeriodSeconds: 60
---
# Source: nginx-ingress/templates/default-backend-deployment.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.20.0
component: "default-backend"
heritage: Helm
release: ingx
name: ingx-nginx-ingress-default-backend
spec:
replicas: 1
revisionHistoryLimit: 10
template:
metadata:
labels:
app: nginx-ingress
component: "default-backend"
release: ingx
spec:
containers:
- name: nginx-ingress-default-backend
image: "k8s.gcr.io/defaultbackend-amd64:1.5"
imagePullPolicy: "IfNotPresent"
args:
securityContext:
runAsUser: 65534
livenessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /healthz
port: 8080
scheme: HTTP
initialDelaySeconds: 0
periodSeconds: 5
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 6
ports:
- name: http
containerPort: 8080
protocol: TCP
resources:
{}
serviceAccountName: ingx-nginx-ingress-backend
terminationGracePeriodSeconds: 60
---
# Source: nginx-ingress/templates/controller-hpa.yaml
apiVersion: autoscaling/v2beta1
kind: HorizontalPodAutoscaler
metadata:
labels:
app: nginx-ingress
chart: nginx-ingress-1.20.0
component: "controller"
heritage: Helm
release: ingx
name: ingx-nginx-ingress-controller
spec:
scaleTargetRef:
apiVersion: apps/v1beta1
kind: Deployment
name: ingx-nginx-ingress-controller
minReplicas: 2
maxReplicas: 100
metrics:
- type: Resource
resource:
name: cpu
targetAverageUtilization: 70
- type: Resource
resource:
name: memory
targetAverageUtilization: 70
Eu suspeito que isso aconteceu porque eu o implantei originalmente sem os parâmetros omitClusterIP, e o helm v3 está tentando fazer uma fusão de 3 vias com o manifesto original, que tem clusterIP: ""
nele
helm get manifest ingx --revision 1 | grep "clusterIP"
clusterIP: ""
clusterIP: ""
Consegui consertar excluindo primeiro o gráfico existente e recriando-o com omitClusterIP
options. Resumindo, a solução alternativa sugerida de @bambash funcionará apenas se você instalar o gráfico com essas opções definidas como verdadeiras desde o início
$ helm upgrade --install ingress-test stable/nginx-ingress --set controller.service.omitClusterIP=true --set defaultBackend.service.omitClusterIP=true
Seria ótimo se houvesse uma maneira no helm v3 de pular a mesclagem com o manifesto existente
desculpe, eu deveria ter especificado que esses valores precisam ser definidos quando a versão é inicialmente instalada. Atualizar uma versão existente pode ser mais complicado ...
Estou tendo esse problema com metric-server-2.8.8, que não tem nenhum clusterIP em seus valores, e alguns outros gráficos, com helm v3.0.0-rc.2. algum conselho? Não tenho certeza de como proceder.
Meu problema parece ser com o helmfile v0.95.0. Vou persegui-lo lá :)
Eu tenho o mesmo problema, mesmo sem definir o tipo de serviço ou clusterIP com helm v3.0.0-rc.2 se eu usar a opção --force com o comando helm update --install. Sem o --force funciona bem
@johannges , eu estava prestes a postar o mesmo. : +1:
configuração omitClusterIP: true
parece funcionar para defaultBackend e serviços de controlador , mas não o de métricas .
Acho que esse é o problema do leme com a opção --force
durante a atualização.
O Helm está tentando recriar o serviço, mas também substitui spec.clusterIP para gerar um erro.
Posso confirmar isso usando meu próprio gráfico personalizado.
Error: UPGRADE FAILED: failed to replace object: Service "litespeed" is invalid: spec.clusterIP: Invalid value: "": field is immutable
Na verdade, foi um erro da minha parte, omitir a definição clusterIP na inicialização do serviço (ou do gráfico) funciona bem 👍
Eu estava encontrando esse erro também para lançamentos de gráficos _kafka_ e _redis_ implantados existentes. Remover --force
realmente resolveu isso.
Agora estou recebendo um novo erro da versão _redis_:
Error: UPGRADE FAILED: release redis failed, and has been rolled back due to atomic being set: cannot patch "redis-master" with kind StatefulSet: StatefulSet.apps "redis-master" is invalid: spec: Forbidden: updates to statefulset spec for fields other than 'replicas', 'template', and 'updateStrategy' are forbidden
Concordou com @bacongobbler que isso parece relacionado à estratégia de patch de mesclagem de três vias do Helm v3 que provavelmente resulta na passagem de campos (mesmo com os mesmos valores de antes) para a atualização / patch que o Kubernetes considera imutável / inalterável após a primeira criação.
No caso de alguém acabar aqui usando o helm v3 via terraform, já que você não pode dizer diretamente para não usar --force
i teve sucesso ao deletar manualmente o gráfico usando helm delete
depois executando novamente o terraform. isso é uma merda, mas funciona.
editar: todo o erro: ("nginx-ingress-singleton-controller" é o nome da versão que defini. Não tem significado específico)
Error: cannot patch "nginx-ingress-singleton-controller" with kind Service: Service "nginx-ingress-singleton-controller" is invalid: spec.clusterIP: Invalid value:
"": field is immutable && cannot patch "nginx-ingress-singleton-default-backend" with kind Service: Service "nginx-ingress-singleton-default-backend" is invalid: sp
ec.clusterIP: Invalid value: "": field is immutable
on .terraform/modules/app_dev/nginx-ingress.tf line 1, in resource "helm_release" "nginx_ingress":
1: resource "helm_release" "nginx_ingress" {
@ zen4ever encontrou o problema em https://github.com/helm/helm/issues/6378#issuecomment -532766512. Vou tentar explicar com mais detalhes ....
Como outros apontaram, o problema surge quando um gráfico define um clusterIP com uma string vazia. Quando o serviço é instalado, o Kubernetes preenche esse campo com o clusterIP atribuído ao serviço.
Quando helm upgrade
é invocado, o gráfico pede que clusterIP
seja removido, daí porque a mensagem de erro é spec.clusterIP: Invalid value: "": field is immutable
.
Isso acontece devido ao seguinte comportamento:
clusterIP
fosse uma string vaziaclusterIP
. Usaremos 172.17.0.1
para este exemplohelm upgrade
, o gráfico quer que clusterIP
seja uma string vazia (ou no caso de @ zen4ever acima , ela é omitida)Ao gerar o patch de três vias, ele vê que o estado antigo era ""
, o estado ativo está atualmente em "172.17.0.1"
e o estado proposto é ""
. O Helm detectou que o usuário solicitou a alteração de clusterIP
de "172.17.0.1" para "", por isso forneceu um patch.
No Helm 2, ele ignorou o estado ativo, portanto, não viu nenhuma mudança (estado antigo: clusterIP: ""
para o novo estado: clusterIP: ""
) e nenhum patch foi gerado, ignorando esse comportamento.
Minha recomendação seria alterar a saída do modelo. Se nenhum clusterIP
estiver sendo fornecido como valor, não defina o valor como uma string vazia ... Omita o campo inteiramente.
por exemplo, no caso de stable/nginx-ingress
:
spec:
{{- if not .Values.controller.service.omitClusterIP }}
clusterIP: "{{ .Values.controller.service.clusterIP }}"
{{- end }}
Deve ser alterado para:
spec:
{{- if not .Values.controller.service.omitClusterIP }}
{{ with .Values.controller.service.clusterIP }}clusterIP: {{ quote . }}{{ end }}
{{- end }}
É também por isso que --set controller.service.omitClusterIP=true
funciona neste caso.
TL; DR não faça isso em seus modelos de serviço:
clusterIP: ""
Caso contrário, o Helm tentará alterar o clusterIP do serviço de um endereço IP gerado automaticamente para a string vazia, daí a mensagem de erro.
Espero que isto ajude!
Como uma solução temporária, se você estiver tentando fazer isso funcionar por enquanto enquanto o problema é resolvido, descobri que, se fizesse o seguinte, consegui realizar uma atualização:
kubectl get svc | grep ingress
controller:
service:
clusterIP: <cluster-ip-address-for-controller>
defaultBackend:
service:
clusterIP: <cluster-ip-address-for-default-backend>
Eu testei isso para um cluster que estou executando e não exigiu nenhuma recriação.
Isso também funciona. Boa chamada, @treacher. definir o mesmo valor por meio de --set
ou em seu arquivo de valores não gera nenhum patch, pois a atualização não quer alterar o valor de clusterIP
.
Fechar funcionando intencionalmente de acordo com o comportamento do patch de mesclagem de três vias descrito acima. O item de ação é que esses gráficos sigam a recomendação fornecida acima em https://github.com/helm/helm/issues/6378#issuecomment-557746499. Nada a fazer aqui na ponta de Helm. :)
https://github.com/helm/charts/pull/19146/files created! Obrigado @bacongobbler
@ zen4ever acertou em cheio no problema em # 6378 (comentário) . Vou tentar explicar com mais detalhes ....
Como outros apontaram, o problema surge quando um gráfico define um clusterIP com uma string vazia. Quando o serviço é instalado, o Kubernetes preenche esse campo com o clusterIP atribuído ao serviço.
Quando
helm upgrade
é invocado, o gráfico pede queclusterIP
seja removido, daí porque a mensagem de erro éspec.clusterIP: Invalid value: "": field is immutable
.Isso acontece devido ao seguinte comportamento:
- Na instalação, o gráfico especificou que queria que
clusterIP
fosse uma string vazia- O Kubernetes atribuiu automaticamente ao serviço um
clusterIP
. Usaremos172.17.0.1
para este exemplo- Em
helm upgrade
, o gráfico quer queclusterIP
seja uma string vazia (ou no caso de @ zen4ever acima , ela é omitida)Ao gerar o patch de três vias, ele vê que o estado antigo era
""
, o estado ativo está atualmente em"172.17.0.1"
e o estado proposto é""
. O Helm detectou que o usuário solicitou a alteração declusterIP
de "172.17.0.1" para "", por isso forneceu um patch.No Helm 2, ele ignorou o estado ativo, portanto, não viu nenhuma mudança (estado antigo:
clusterIP: ""
para o novo estado:clusterIP: ""
) e nenhum patch foi gerado, ignorando esse comportamento.Minha recomendação seria alterar a saída do modelo. Se nenhum
clusterIP
estiver sendo fornecido como valor, não defina o valor como uma string vazia ... Omita o campo inteiramente.por exemplo, no caso de
stable/nginx-ingress
:spec: {{- if not .Values.controller.service.omitClusterIP }} clusterIP: "{{ .Values.controller.service.clusterIP }}" {{- end }}
Deve ser alterado para:
spec: {{- if not .Values.controller.service.omitClusterIP }} {{ with .Values.controller.service.clusterIP }}clusterIP: {{ quote . }}{{ end }} {{- end }}
Olá @bacongobbler , acho que, se nenhum valor for fornecido, ainda terminaremos com
clusterIP: ""
... melhor seria o valorclusterIP: ""
completamente comentado no arquivo de valores. Isso o omite dos manifestos renderizados quando definido e deve evitar dores de cabeça futuras. No entanto, se o uso de helm3 e o estado atual do leme tiverclusterIP: ""
definido, será necessário codificar os endereços IP do cluster nos arquivos de valores.
É também por isso que
--set controller.service.omitClusterIP=true
funciona neste caso.TL; DR não faça isso em seus modelos de serviço:
clusterIP: ""
Caso contrário, o Helm tentará alterar o clusterIP do serviço de um endereço IP gerado automaticamente para a string vazia, daí a mensagem de erro.
Espero que isto ajude!
Olá @bacongobbler , enfrentamos o mesmo problema durante a migração do helm v2 para o helm v3. Usamos type: ClusterIP
em Serviço, mas omitimos ClusterIP
todo e obtemos:
Error: UPGRADE FAILED: failed to replace object: Service "dummy" is invalid: spec.clusterIP: Invalid value: "": field is immutable
Não temos spec.clusterIP:
em nosso modelo de leme, mas recebemos este erro após migrar o lançamento via helm 2to3
Modelo de serviço:
apiVersion: v1
kind: Service
metadata:
name: {{ .Release.Name }}
labels:
app: {{ .Values.image.name }}
chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "-" }}
cluster: {{ default "unknown" .Values.cluster }}
region: {{ default "unknown" .Values.region }}
datacenter: {{ default "unknown" .Values.datacenter }}
release: {{ .Release.Name }}
heritage: {{ .Release.Service }}
spec:
type: ClusterIP
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.service.port }}
protocol: TCP
name: http
selector:
app: {{ .Values.image.name }}
release: {{ .Release.Name }}
Mesmo problema aqui. Acontece que não tocamos no Serviço. É o Ingress que foi alterado antes da atualização.
Ele afeta os recursos com campo imutável se excluir a bandeira --force
de helm upgrade --install
e não tocar no campo imutável, tudo funciona bem. Mas se você quiser aumentar a disponibilidade de recursos ??? Você precisa recriar recursos, mas o leme 3 não atualizará os recursos ....
@bacongobbler ^^^
tentei atualizar o hpa com o novo apiVersion do helm 3:
Error: UPGRADE FAILED: rendered manifests contain a new resource that already exists. Unable to continue with update: existing resource conflict: kind: HorizontalPodAutoscaler, namespace: stage, name: dummy-stage
O comentário negativo de @bacongobbler e @ kritcher722 foi atualizado se você desejar remover os polegares para baixo, no entanto, se ainda estiver em desacordo, explique por que é uma boa idéia ter clusterIP: ""
nos manifestos renderizados.
Parece que a Microsoft é a mentora do projeto. Eu vejo estilo. :)
Abra novamente. O problema não foi corrigido. Este "hack" sugerido por nasseemkullah não é apropriado. Não peça às pessoas para pularem em cabeças. Apenas conserte. Caminho de migração muito pobre. Helm é uma merda.
@antonakv que maneira de começar o ano :)
Acho que, em geral, estamos brincando com fogo ao fornecer clusterIP como um valor configurável em um gráfico e não podemos culpar totalmente uma ferramenta / pessoa / RP em particular.
Se clusterIP precisa ser um valor configurável, por padrão não deve estar no modelo renderizado, essa é a ideia de comentar nos arquivos de valores de acordo com https://github.com/helm/charts/blob/270172836fd8cf56d787cf7d04d938856de0c794/stable /nginx-ingress/values.yaml#L236
Isso, se não me engano, deve evitar uma futura dor de cabeça para quem instalar o gráfico a partir dessa mudança. Mas para aqueles de nós (inclusive eu) que o instalaram antes e depois migraram para o helm3, receio que gravar os valores atuais do clusterIP em nossos arquivos de valores OU desinstalar e reinstalar o gráfico (causa tempo de inatividade!) São as únicas opções . Vejo.
As opiniões são minhas, não sou pago para trabalhar no leme, apenas um usuário final como você. Aqueles que são pagos para trabalhar em tempo integral podem fornecer mais informações.
Feliz ano novo e boa sorte! Não desista do leme, juntos podemos torná-lo melhor.
Olá @bacongobbler , enfrentamos o mesmo problema durante a migração do helm v2 para o helm v3. Usamos
type: ClusterIP
em Serviço, mas omitimosClusterIP
todo e obtemos:
Error: UPGRADE FAILED: failed to replace object: Service "dummy" is invalid: spec.clusterIP: Invalid value: "": field is immutable
Não temos
spec.clusterIP:
em nosso modelo de leme, mas recebemos este erro após migrar o lançamento via helm 2to3Modelo de serviço:
apiVersion: v1 kind: Service metadata: name: {{ .Release.Name }} labels: app: {{ .Values.image.name }} chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "-" }} cluster: {{ default "unknown" .Values.cluster }} region: {{ default "unknown" .Values.region }} datacenter: {{ default "unknown" .Values.datacenter }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} spec: type: ClusterIP ports: - port: {{ .Values.service.port }} targetPort: {{ .Values.service.port }} protocol: TCP name: http selector: app: {{ .Values.image.name }} release: {{ .Release.Name }}
Nós temos o mesmo problema. Não definimos clusterIP
em nosso gráfico e não está presente no modelo final. No entanto, ainda obtemos o mesmo erro e apenas com a sinalização --force
.
Estamos tendo o mesmo problema:
apiVersion: v1
kind: Service
{{ include "mde.metadata" $ }}
spec:
ports:
- name: {{ include "mde.portName" $ | quote }}
port: {{ include "mde.port" $ }}
protocol: TCP
targetPort: {{ include "mde.port" $ }}
selector:
app: {{ include "mde.name" $ }}
sessionAffinity: None
type: ClusterIP
spec.clusterIP
não faz parte do modelo de serviço, mas com o Helm 3.0.2 e uma chamada de helm upgrade ... --force --install
, também estamos vendo:
Erro: UPGRADE FAILED: falha ao substituir o objeto: O serviço "dummy" é inválido: spec.clusterIP: Valor inválido: "": o campo é imutável
Por favor, reabra.
@ tomcruise81 consulte https://github.com/helm/helm/issues/7350 para o tópico em --force
. Isso resulta no mesmo erro, mas é devido a como kubectl replace
parece funcionar. É um problema separado do que foi descrito aqui, que pertence aos Service clusterIPs e à estratégia de patch de mesclagem de três vias ( helm upgrade
sem o sinalizador --force
).
@bacongobbler - obrigado pela resposta rápida e esclarecimento. Olhando para:
https://github.com/helm/helm/blob/a963736f6675e972448bf7a5fd141628fd0ae4df/pkg/kube/client.go#L405 -L411
que usam https://github.com/kubernetes/cli-runtime/blob/master/pkg/resource/helper.go#L155 -L181, não parece que a chamada para helper.Replace
sim a mesma coisa que kubectl replace -f ... --force
(observe a --force no final).
Suponho que é aqui que está grande parte da confusão.
Eu sei que minha expectativa de helm upgrade ... --force
e ele está usando uma estratégia de substituição era que faria a mesma coisa que kubectl replace -f ... --force
.
Olá @bacongobbler , enfrentamos o mesmo problema durante a migração do helm v2 para o helm v3. Usamos
type: ClusterIP
em Serviço, mas omitimosClusterIP
todo e obtemos:
Error: UPGRADE FAILED: failed to replace object: Service "dummy" is invalid: spec.clusterIP: Invalid value: "": field is immutable
Não temosspec.clusterIP:
em nosso modelo de leme, mas recebemos este erro após migrar o lançamento via helm 2to3
Modelo de serviço:apiVersion: v1 kind: Service metadata: name: {{ .Release.Name }} labels: app: {{ .Values.image.name }} chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "-" }} cluster: {{ default "unknown" .Values.cluster }} region: {{ default "unknown" .Values.region }} datacenter: {{ default "unknown" .Values.datacenter }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} spec: type: ClusterIP ports: - port: {{ .Values.service.port }} targetPort: {{ .Values.service.port }} protocol: TCP name: http selector: app: {{ .Values.image.name }} release: {{ .Release.Name }}
Nós temos o mesmo problema. Não definimos
clusterIP
em nosso gráfico e não está presente no modelo final. No entanto, ainda obtemos o mesmo erro e apenas com a sinalização--force
.
Também verifiquei se não há clusterIP
no manifesto de lançamento:
$ helm get manifest paywall-api-ee | grep clusterIP
$
mesmo aqui - não definimos ClusterIP
nenhum lugar, mas ainda vemos o erro
Brincando mais com isso, observei que:
helm upgrade ... --force --install
- resulta em _O serviço "dummy" é inválido: spec.clusterIP : Valor inválido: "": o campo é imutável_helm template ... | kubectl apply -f -
- funcionahelm template ... | kubectl replace -f -
- resulta em _O serviço "dummy" é inválido: spec.clusterIP : Valor inválido: "": o campo é imutável_helm template ... | kubectl replace --force -f -
- funcionaversão kubectl - 1.14.6
versão do leme - 3.0.2
@ tomcruise81 você pode tentar usar o plugin helm 2to3 e migrar de helm2 para helm3 release e deletar --force
se você já o usou.
É um trabalho para nós.
Quanto a mim e parece que para outros caras --force
tem erro de comportamento e deve lidar com este caso com campo imutável quanto a mim
@alexandrsemak - obrigado pela recomendação. No meu caso, estou vendo isso em um gráfico que só foi instalado ou atualizado usando o helm 3.
O mesmo problema para mim! Usando
$ helm install my-release xxxxx
$ helm upgrade --install --force my-release xxxxx
No meu caso, não estou definindo ClusterIP em nenhum dos serviços usados em meu gráfico, mas enfrento o mesmo problema (consulte as especificações abaixo):
spec:
type: {{ .Values.service.type }}
{{- if and (eq .Values.service.type "LoadBalancer") (not (empty .Values.service.loadBalancerIP)) }}
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
{{- end }}
ports:
- name: htttp-XXX
port: {{ .Values.service.port }}
targetPort: XXX
{{- if and (or (eq .Values.service.type "NodePort") (eq .Values.service.type "LoadBalancer")) (not (empty .Values.service.nodePort)) }}
nodePort: {{ .Values.service.nodePort }}
{{- else if eq .Values.service.type "ClusterIP" }}
nodePort: null
{{- end }}
selector:
app.kubernetes.io/name: XXX
app.kubernetes.io/instance: {{ .Release.Name }}
Como outros usuários disseram antes, o motivo é que o Kubernetes atribui automaticamente ao serviço um clusterIP pela primeira vez (por exemplo, clusterIP: 10.96.26.65
) e ele entra em conflito com clusterIP: ""
quando você tenta atualizar. Observe que não estou gerando isso em meus modelos: clusterIP: ""
Por favor, reabra este @bacongobbler
Eu tenho o mesmo problema.
@ juan131 @Ronsevet : remove --force O significado mudou.
enfrentando o mesmo problema, em gráficos personalizados.
Não definimos clusterip em qualquer lugar.
Helm v3.0.2
kubectl 1.14.8
O problema é que às vezes um gráfico permanece em estado de falha, mesmo que os pods sejam criados e em execução. Se tentarmos atualizar a mesma versão, ela não funcionará sem força.
Como os pods estão em execução, a versão não pode ser excluída e recriada.
Tem que haver alguma maneira de usar "força"
o mesmo para mim - acabei de adicionar uma etiqueta adicional ao serviço e enfrentei este erro. Além disso, não defino o ClusterIP em nenhum lugar - reabra o problema
@bacongobbler Estamos implantando StorageClasses como parte de nosso gráfico e os parâmetros do StorageClass são imutáveis. Portanto, na próxima versão, quando atualizarmos o valor de algum parâmetro StorageClass, também helm upgrade --force
está falhando.
Não tenho certeza de como lidar com esse caso para atualização de StorageClasses. Alguma sugestão?
Error: UPGRADE FAILED: failed to replace object: StorageClass.storage.k8s.io "ibmc-s3fs-standard-cross-region" is invalid: parameters: Forbidden: updates to parameters are forbidden.
Estava funcionando bem no helm v2, pois helm upgrade --force
usado para forçar a exclusão e recriar o StorageClass .
Se alguém estiver apresentando sintomas que não sejam resultado da explicação fornecida em https://github.com/helm/helm/issues/6378#issuecomment -557746499, abra um novo problema com suas descobertas e como podemos reproduzi-lo é do nosso lado?
O problema levantado pelo OP foi devido ao cenário fornecido acima, em que um gráfico definia o ClusterIP como uma string vazia na instalação. É perfeitamente possível que existam outros cenários em que este caso específico possa surgir, como outros mencionaram com o uso da sinalização --force
. Esses casos devem ser discutidos separadamente, pois o diagnóstico e a solução podem ser diferentes do conselho fornecido anteriormente.
Obrigada!
@mssachan veja # 7082 e o rascunho da proposta em # 7431 para seu caso de uso. Essa proposta visa implementar kubectl replace —force
, que seria semelhante ao comportamento de helm install —force
Helm 2.
@mssachan veja # 7082 e o rascunho da proposta em # 7431 para seu caso de uso. Essa proposta visa implementar
kubectl replace —force
, que seria semelhante ao comportamento dehelm install —force
Helm 2.
É bom que isso esteja acontecendo. Mesmo omitindo a sinalização --force
, ainda recebo o erro ao atualizar os gráficos. Por exemplo, com cert-manager
:
2020-03-05 12:15:19 CRITICAL: Command returned [ 1 ] exit code and error message [ Error: UPGRADE FAILED: cannot patch "cert-manager-cainjector" with kind Deployment: Deployment.apps "cert-manager-cainjector" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"cainjector", "app.kubernetes.io/instance":"cert-manager", "app.kubernetes.io/managed-by":"Helm", "app.kubernetes.io/name":"cainjector"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable && cannot patch "cert-manager" with kind Deployment: Deployment.apps "cert-manager" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"cert-manager", "app.kubernetes.io/instance":"cert-manager", "app.kubernetes.io/managed-by":"Helm", "app.kubernetes.io/name":"cert-manager"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable && cannot patch "cert-manager-webhook" with kind Deployment: Deployment.apps "cert-manager-webhook" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"webhook", "app.kubernetes.io/instance":"cert-manager", "app.kubernetes.io/managed-by":"Helm", "app.kubernetes.io/name":"webhook"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable
@mssachan veja # 7082 e o rascunho da proposta em # 7431 para seu caso de uso. Essa proposta visa implementar
kubectl replace —force
, que seria semelhante ao comportamento dehelm install —force
Helm 2.É bom que isso esteja acontecendo. Mesmo omitindo a sinalização
--force
, ainda recebo o erro ao atualizar os gráficos. Por exemplo, comcert-manager
:
2020-03-05 12:15:19 CRITICAL: Command returned [ 1 ] exit code and error message [ Error: UPGRADE FAILED: cannot patch "cert-manager-cainjector" with kind Deployment: Deployment.apps "cert-manager-cainjector" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"cainjector", "app.kubernetes.io/instance":"cert-manager", "app.kubernetes.io/managed-by":"Helm", "app.kubernetes.io/name":"cainjector"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable && cannot patch "cert-manager" with kind Deployment: Deployment.apps "cert-manager" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"cert-manager", "app.kubernetes.io/instance":"cert-manager", "app.kubernetes.io/managed-by":"Helm", "app.kubernetes.io/name":"cert-manager"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable && cannot patch "cert-manager-webhook" with kind Deployment: Deployment.apps "cert-manager-webhook" is invalid: spec.selector: Invalid value: v1.LabelSelector{MatchLabels:map[string]string{"app":"webhook", "app.kubernetes.io/instance":"cert-manager", "app.kubernetes.io/managed-by":"Helm", "app.kubernetes.io/name":"webhook"}, MatchExpressions:[]v1.LabelSelectorRequirement(nil)}: field is immutable
@ sc250024 Tenho exatamente o mesmo problema depois de atualizar o helm v2 para v3. O progresso da atualização foi suave e sem erros, então eu tento atualizar o cert-manager do leme, falhou com a mesma saída.
# helm upgrade cert-manager jetstack/cert-manager --namespace cert-manager --atomic --cleanup-on-fail
# helm version
version.BuildInfo{Version:"v3.1.1", GitCommit:"afe70585407b420d0097d07b21c47dc511525ac8", GitTreeState:"clean", GoVersion:"go1.13.8"}
Quaisquer soluções alternativas para quando --force não for usado ou nenhuma opção em torno de clusterIP
sendo definida. Este é o meu manifesto de serviço:
apiVersion: v1
kind: Service
metadata:
name: "{{ .Values.deploymentBaseName }}-{{ .Values.skaffoldUser }}"
labels:
name: "{{ .Values.deploymentBaseName }}-{{ .Values.skaffoldUser }}"
spec:
ports:
- port: {{ .Values.servicePort }}
targetPort: {{ .Values.containerPort }}
protocol: TCP
name: http
- name: debugger-http
port: {{ .Values.debuggerPort }}
targetPort: {{ .Values.debuggerPort }}
protocol: TCP
selector:
app: "{{ .Values.deploymentBaseName }}-{{ .Values.skaffoldUser }}"
type: ClusterIP
@davidfernandezm , você já encontrou uma solução para isso? Estou vendo o mesmo do meu lado e meus serviços são definidos exatamente como os seus. Nenhuma opção para clusterIP
está sendo definida, mas o Helm ainda falha em uma atualização.
Mesmo aqui
Também entendendo isso, re: os dois comentários acima.
Forneça mais informações. Não podemos ajudá-lo sem entender a causa ou como esse problema surge no seu caso. Obrigado.
@antonakv este problema é duplicado de 7956
@bacongobbler mais informações
Eu tenho o mesmo problema, mesmo sem definir o tipo de serviço ou clusterIP com helm v3.0.0-rc.2 se eu usar a opção --force com o comando helm update --install. Sem o --force funciona bem
Legal! Eu me inspirei em sua resposta, que devo comentar a linha force: ..
no helmfile yaml:
helmDefaults:
tillerless: true
verify: false
wait: true
timeout: 600
# force: true <---- THI ONE IS COMMENTED
Funciona 🎉
Eu tentei todos os itens acima, nenhum funcionou para mim. Tive que desabilitar nginx-ingress
do meu gráfico, fazer uma atualização, habilitá-lo novamente e atualizar novamente. Isso levou a uma mudança no endereço IP atribuído pelo provedor de nuvem, mas nenhum dano causado.
Eu tenho o mesmo problema, mesmo sem definir o tipo de serviço ou clusterIP com helm v3.0.0-rc.2 se eu usar a opção --force com o comando helm update --install. Sem o --force funciona bem
Melhor solução, funciona para mim, obrigado!
Estamos tendo o mesmo problema e não foi possível encontrar uma solução alternativa.
É muito simples de reproduzir
helm install in stable/inbucket
helm upgrade in stable/inbucket
Error: UPGRADE FAILED: cannot patch "in-inbucket" with kind Service: Service "in-inbucket" is invalid: spec.clusterIP: Invalid value: "": field is immutable
Eu estava me perguntando por que --force
não funciona aqui, não deveria force resource updates through a replacement strategy
se esta for uma estratégia de substituição, então o serviço deve ser removido e substituído?
@bacongobbler Cheguei a esta discussão depois de verificar https://github.com/helm/helm/issues/7956
Como acontece com todos os comentadores anteriores: não temos "clusterIP" nos modelos, mas o erro ainda está presente no Helm mais recente se o sinalizador --force for usado.
Versão do Helm: 3.4.1
"helm -n kube-system obter manifesto CHART_NAME | grep clusterIP" não mostra resultados.
Erro:
field is immutable && failed to replace object: Service "SERVICE_NAME" is invalid: spec.clusterIP: Invalid value: "": field is immutable
A mesma explicação fornecida em https://github.com/helm/helm/issues/6378#issuecomment -557746499 também se aplica aqui no seu caso @ nick4fake. A diferença é que, com --force
, você está pedindo ao Kubernetes para pegar seu manifesto totalmente renderizado e substituir à força o objeto ativo atual. Como seu manifesto não contém um campo clusterIP
, o Kubernetes pega isso e presume que você está tentando remover o campo clusterIP
do objeto ativo, daí o erro Invalid value: "": field is immutable
.
@bacongobbler Eu realmente sinto muito se perdi algo aqui, talvez eu simplesmente não saiba o suficiente sobre os componentes internos do Helm.
"Minha recomendação seria alterar a saída do modelo. Se nenhum clusterIP estiver sendo fornecido como um valor, não defina o valor como uma string vazia ... Omita o campo inteiramente."
Então qual é a solução? Isso significa que a sinalização "--force" não pode ser usada se o campo clusterIP não estiver definido com algum valor estático?
No que diz respeito ao Kubernetes: sim.
De acordo com meu entendimento, isso é um problema com o Kubernetes, porque "substituir à força" não se comporta da mesma maneira que "excluir e recriar novamente". Existe algum bug upstream?
Por outro lado, o Helm também é enganoso, porque --force
é descrito como "forçar atualizações de recursos por meio de uma estratégia de substituição". Embora na realidade ele não faça nenhuma substituição, ele apenas tenta sobrescrever os recursos à força (seria melhor nomear o sinalizador --force-overwrite
). A substituição forçada pareceria excluir e recriar novamente (pode haver um sinalizador --force-recreate
). Claro, --force-recreate
pode ser um pouco perigoso para alguns recursos, mas sempre terá sucesso.
De qualquer forma, o Helm poderia implementar uma solução alternativa para esse tipo de problema. Se o comportamento atual (descrito como --force-overwrite
) falhar e detectar um erro de campo imutável, ele deve excluir e recriar o recurso (como --force-recreate
).
Comentários muito úteis
Eu tenho o mesmo problema, mesmo sem definir o tipo de serviço ou clusterIP com helm v3.0.0-rc.2 se eu usar a opção --force com o comando helm update --install. Sem o --force funciona bem