Для установки / обновления графика я использую следующее:
./helm upgrade --install
--set rbac.create = false
--set controller.replicaCount = 2
--set controller.service.loadBalancerIP = $ ip
--wait main-ingress стабильный / nginx-ingress
(Где $ ip - это IP, например 10.0.0.1)
Это делается в конвейере CI / CD, поэтому идея состоит в том, чтобы установить в первый раз и обновить в следующий раз.
Устанавливается нормально. При втором запуске он выводит следующее:
_client.go: 339: Невозможно исправить службу: "main-ingress-nginx-ingress-controller" (служба "main-ingress-nginx-ingress-controller" недействительна: spec.clusterIP: недопустимое значение: "": поле является неизменным )
client.go: 358: Используйте --force для принудительного воссоздания ресурса
client.go: 339: Невозможно исправить службу: "main-ingress-nginx-ingress-default-backend" (Служба "main-ingress-nginx-ingress-default-backend" недействительна: spec.clusterIP: Invalid value: "" : field неизменяемо)
client.go: 358: Используйте --force для принудительного воссоздания ресурса
Ошибка: ОБНОВЛЕНИЕ НЕ выполнено: служба «main-ingress-nginx-ingress-controller» недействительна: spec.clusterIP: недопустимое значение: «»: поле неизменяемо && Служба «main-ingress-nginx-ingress-default-backend» недействительна : spec.clusterIP: Недействительное значение: "": поле неизменяемое_
Я также получил это в списке руля:
ОБНОВЛЕНИЕ ОБНОВЛЕННОГО СОСТОЯНИЯ ИМЕНИ NAMESPACE REVISION
main-ingress по умолчанию 1 2019-09-06 13: 17: 33.8463781 -0400 EDT развернут nginx-ingress-1.18.0
main-ingress по умолчанию 2 2019-09-06 13: 21: 11.6428945 -0400 Ошибка EDT nginx-ingress-1.18.0
Итак, релиз не удался.
У меня не было этой проблемы с Helm 2. Это связано с изменением поведения в Helm 3 или это ошибка? Если это первое, как я могу изменить команду, чтобы не было этой проблемы?
Вывод helm version
: version.BuildInfo {Версия: "v3.0.0-beta.2", GitCommit: "26c7338408f8db593f93cd7c963ad56f67f662d4", GitTreeState: "clean", GoVersion: "go1.12.9"}
Вывод kubectl version
: Версия клиента: version.Info {Major: "1", Minor: "12", GitVersion: "v1.12.0", GitCommit: "0ed33881dc4355495f623c6f22e7dd0b7632b7c0", GitTreeState: "clean", BuildDate: «2018-09-27T17: 05: 32Z», GoVersion: «go1.10.4», компилятор: «gc», платформа: «linux / amd64»}
Версия сервера: version.Info {Major: «1», Minor: «13», GitVersion: «v1.13.10», GitCommit: «37d169313237cb4ceb2cc4bef300f2ae3053c1a2», GitTreeState: «clean», BuildDate: «2019-08-19T10: 44: 49Z ", GoVersion:" go1.11.13 ", компилятор:" gc ", платформа:" linux / amd64 "}
Облачный провайдер / платформа (AKS, GKE, Minikube и т. Д.): AKS
Вероятно, это связано с недавним изменением в Helm 3, где теперь используется трехсторонняя стратегия слияния патчей, аналогичная kubectl. См. № 6124
Если вы можете предоставить инструкции, как это воспроизвести, это было бы замечательно. Спасибо!
Конечно!
Я создал кластер AKS.
Я создаю публичный IP в группе ресурсов MC_ *.
Я сохранил IP-адрес этого общедоступного IP-адреса в $ ip.
Затем в основном запускал эту команду дважды:
./helm upgrade --install
--set rbac.create = false
--set controller.replicaCount = 2
--set controller.service.loadBalancerIP = $ ip
--wait main-ingress стабильный / nginx-ingress
Это похоже на то, что сделано на https://docs.microsoft.com/en-us/azure/aks/ingress-static-ip.
Разница в том, что я делаю апгрейд руля - устанавливаю дважды. Цель этого - иметь единственную командную строку (безусловную) в моем CI / CD.
Дайте мне знать, если вам понадобится больше деталей для воспроизведения.
Этого было достаточно для воспроизведения? Я могу предоставить сценарий bash, если он поможет.
Извините, я на неделю на Helm Summit EU, поэтому у меня еще не было времени ответить.
Ах ... не беспокойтесь. Наслаждайтесь вершиной!
У меня тоже возникла эта проблема
$ helm version --short
v3.0.0-beta.3+g5cb923e
Диаграмма nginx-ingress устанавливается нормально при первом запуске, однако при обновлении ...
$ 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
Я считаю, что это проблема с диаграммой nginx-ingress, а не с helm3. По умолчанию диаграмма всегда будет пытаться передать controller.service.clusterIP = ""
и defaultBackend.service.clusterIP = ""
если вы не установите controller.service.omitClusterIP=true
и defaultBackend.service.omitClusterIP=true
.
ссылка на источники:
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
обходной путь:
$ helm upgrade --install ingress-test stable/nginx-ingress --set controller.service.omitClusterIP=true --set defaultBackend.service.omitClusterIP=true
Я пробовал это сделать, но все равно получаю ту же ошибку
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
Как вы можете видеть ниже, в шаблоне нет clusterIP.
шаблон helm, стабильный Ingx / 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
Я подозреваю, что это произошло потому, что я изначально развернул его без параметров omitClusterIP, а helm v3 пытается выполнить трехстороннее слияние с исходным манифестом, в котором есть clusterIP: ""
helm get manifest ingx --revision 1 | grep "clusterIP"
clusterIP: ""
clusterIP: ""
Я смог исправить это, сначала удалив существующую диаграмму и воссоздав ее с параметрами omitClusterIP
. Итог, предлагаемый обходной путь от @bambash будет работать, только если вы установите диаграмму с этими параметрами, установленными на true с самого начала.
$ helm upgrade --install ingress-test stable/nginx-ingress --set controller.service.omitClusterIP=true --set defaultBackend.service.omitClusterIP=true
Было бы здорово, если бы в helm v3 был способ пропустить слияние с существующим манифестом
извините, я должен был указать, что эти значения должны быть установлены при первоначальной установке выпуска. Обновление существующей версии может оказаться сложнее ...
Я столкнулся с этой проблемой с metric-server-2.8.8, в значениях которой нет clusterIP, и некоторыми другими диаграммами с helm v3.0.0-rc.2. любой совет? Я не знаю, что делать дальше.
Моя проблема, похоже, связана с helmfile v0.95.0. Я поищу там :)
У меня та же проблема, даже без установки типа службы или clusterIP с помощью helm v3.0.0-rc.2, если я использую параметр --force с командой helm update --install. Без --force он отлично работает
@johannges , я как раз собирался опубликовать то же самое. : +1:
установка omitClusterIP: true
похоже, работает для служб defaultBackend и контроллера, но не для метрик .
Я думаю, что это проблема с Helm с опцией --force
во время обновления.
Helm пытается воссоздать сервис, но он также заменяет spec.clusterIP, поэтому выдает ошибку.
Я могу подтвердить это, используя свою собственную диаграмму.
Error: UPGRADE FAILED: failed to replace object: Service "litespeed" is invalid: spec.clusterIP: Invalid value: "": field is immutable
На самом деле это была ошибка с моей стороны, пропуск определения clusterIP при инициализации службы (или диаграммы) работает нормально 👍
Я столкнулся с этой ошибкой также для существующих развернутых выпусков диаграмм _kafka_ и _redis_. Удаление --force
действительно решило эту проблему.
Теперь я получаю новую ошибку в выпуске _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
Согласен с @bacongobbler, что это похоже на стратегию трехстороннего слияния Helm v3, которая, вероятно, приведет к передаче полей (даже с теми же значениями, что и раньше) в обновление / патч, которые Kubernetes считает неизменными / неизменяемыми после первого создания.
На случай, если кто-то окажется здесь, используя helm v3 через terraform, поскольку вы не можете напрямую сказать ему не использовать --force
мне удалось вручную удалить диаграмму с помощью helm delete
затем повторно запустить terraform. это отстой, но это работает.
edit: вся ошибка: ("nginx-ingress-singleton-controller" - это имя выпуска, которое я установил. Это не имеет конкретного значения)
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 решил проблему в https://github.com/helm/helm/issues/6378#issuecomment -532766512. Попробую подробнее объяснить ....
Как указывали другие, проблема возникает, когда диаграмма определяет clusterIP с пустой строкой. Когда Служба установлена, Kubernetes заполняет это поле IP-адресом кластера, назначенным Службе.
Когда вызывается helm upgrade
, диаграмма запрашивает удаление clusterIP
, поэтому появляется сообщение об ошибке spec.clusterIP: Invalid value: "": field is immutable
.
Это происходит из-за следующего поведения:
clusterIP
должна быть пустой строкой.clusterIP
. В этом примере мы будем использовать 172.17.0.1
helm upgrade
диаграмма хочет, чтобы clusterIP
была пустой строкой (или в случае @ zen4ever выше , она опущена)При создании трехстороннего патча он видит, что старое состояние было ""
, текущее состояние в настоящее время - "172.17.0.1"
, а предлагаемое состояние - ""
. Helm обнаружил, что пользователь запросил изменить clusterIP
с «172.17.0.1» на «», поэтому он предоставил патч.
В Helm 2 он игнорировал текущее состояние, поэтому не видел никаких изменений (старое состояние: clusterIP: ""
до нового состояния: clusterIP: ""
), и патч не был сгенерирован в обход этого поведения.
Я бы порекомендовал изменить вывод шаблона. Если в качестве значения не указано clusterIP
, тогда не устанавливайте значение в пустую строку ... Полностью опустите поле.
например, в случае stable/nginx-ingress
:
spec:
{{- if not .Values.controller.service.omitClusterIP }}
clusterIP: "{{ .Values.controller.service.clusterIP }}"
{{- end }}
Следует изменить на:
spec:
{{- if not .Values.controller.service.omitClusterIP }}
{{ with .Values.controller.service.clusterIP }}clusterIP: {{ quote . }}{{ end }}
{{- end }}
Вот почему в этом случае работает --set controller.service.omitClusterIP=true
.
TL; DR не делайте этого в своих шаблонах услуг:
clusterIP: ""
В противном случае Helm попытается изменить clusterIP службы с автоматически сгенерированного IP-адреса на пустую строку, отсюда и сообщение об ошибке.
Надеюсь это поможет!
В качестве временного решения, если вы пытаетесь заставить это работать, пока эта проблема не будет решена, я обнаружил, что если я сделаю следующее, я смогу выполнить обновление:
kubectl get svc | grep ingress
controller:
service:
clusterIP: <cluster-ip-address-for-controller>
defaultBackend:
service:
clusterIP: <cluster-ip-address-for-default-backend>
Я тестировал это на своем кластере, и это не требовало никакого отдыха.
Это тоже работает. Хороший звонок @treacher. установка того же значения с помощью --set
или в вашем файле значений не создает патча, так как обновление не хочет изменять значение clusterIP
.
Закрытие как работающее намеренно в соответствии с поведением патча трехстороннего слияния, описанным выше. Действие заключается в том, чтобы эти диаграммы следовали рекомендациям, приведенным выше в https://github.com/helm/helm/issues/6378#issuecomment-557746499. Здесь, на стороне Хельма, делать нечего. :)
https://github.com/helm/charts/pull/19146/files created! Спасибо @bacongobbler
@ zen4ever решил проблему в # 6378 (комментарий) . Попробую подробнее объяснить ....
Как указывали другие, проблема возникает, когда диаграмма определяет clusterIP с пустой строкой. Когда Служба установлена, Kubernetes заполняет это поле IP-адресом кластера, назначенным Службе.
Когда вызывается
helm upgrade
, диаграмма запрашивает удалениеclusterIP
, поэтому появляется сообщение об ошибкеspec.clusterIP: Invalid value: "": field is immutable
.Это происходит из-за следующего поведения:
- При установке в диаграмме указано, что
clusterIP
должна быть пустой строкой.- Kubernetes автоматически присвоил Сервису
clusterIP
. В этом примере мы будем использовать172.17.0.1
- На
helm upgrade
диаграмма хочет, чтобыclusterIP
была пустой строкой (или в случае @ zen4ever выше , она опущена)При создании трехстороннего патча он видит, что старое состояние было
""
, текущее состояние в настоящее время -"172.17.0.1"
, а предлагаемое состояние -""
. Helm обнаружил, что пользователь запросил изменитьclusterIP
с «172.17.0.1» на «», поэтому он предоставил патч.В Helm 2 он игнорировал текущее состояние, поэтому не видел никаких изменений (старое состояние:
clusterIP: ""
до нового состояния:clusterIP: ""
), и патч не был сгенерирован в обход этого поведения.Я бы порекомендовал изменить вывод шаблона. Если в качестве значения не указано
clusterIP
, тогда не устанавливайте значение в пустую строку ... Полностью опустите поле.например, в случае
stable/nginx-ingress
:spec: {{- if not .Values.controller.service.omitClusterIP }} clusterIP: "{{ .Values.controller.service.clusterIP }}" {{- end }}
Следует изменить на:
spec: {{- if not .Values.controller.service.omitClusterIP }} {{ with .Values.controller.service.clusterIP }}clusterIP: {{ quote . }}{{ end }} {{- end }}
Привет @bacongobbler , я думаю, поскольку, если значение не указано, мы все равно закончим с
clusterIP: ""
... лучше было бы значениеclusterIP: ""
полностью закомментированное в файле значений. Это исключает его из отображаемых манифестов при установке и должно избавить от головной боли в будущем. Однако, если используется helm3 и в текущем состоянии helm установленоclusterIP: ""
, необходимо жестко закодировать IP-адреса кластера в файлах значений.
Вот почему в этом случае работает
--set controller.service.omitClusterIP=true
.TL; DR не делайте этого в своих шаблонах услуг:
clusterIP: ""
В противном случае Helm попытается изменить clusterIP службы с автоматически сгенерированного IP-адреса на пустую строку, отсюда и сообщение об ошибке.
Надеюсь это поможет!
Привет, @bacongobbler , мы столкнулись с той же проблемой при type: ClusterIP
в Service, но опускаем ClusterIP
вообще, и получаем:
Error: UPGRADE FAILED: failed to replace object: Service "dummy" is invalid: spec.clusterIP: Invalid value: "": field is immutable
У нас нет spec.clusterIP:
в нашем шаблоне helm, но мы получили эту ошибку после переноса выпуска через helm 2to3
Шаблон услуги:
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 }}
Здесь та же проблема. Дело в том, что мы не трогали Сервис. Это Ingress, который был изменен перед обновлением.
Это влияет на ресурсы с неизменяемым полем, если удалить флаг --force
из helm upgrade --install
и не трогать неизменяемое поле, все работает нормально. Но если вы хотите перебросить ресурсы ??? Вам нужно воссоздать ресурсы, но helm 3 не обновляет ресурсы ....
@bacongobbler ^^^
попробовал обновить hpa с новым apiVersion от 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
@bacongobbler и @ kritcher722 пальцы сбит комментарий был обновлен , если вы так хочет , чтобы удалить большие пальцы вниз, однако если еще в несогласии любезно уточнить, почему это хорошая идея , чтобы иметь clusterIP: ""
в оказанных манифестах.
Похоже, что Microsoft является наставником проекта. Я вижу стиль. :)
Пожалуйста, откройте снова. Проблема не устранена. Этот "хакерский прием", предложенный Насимкуллахом, неуместен. Не просите людей прыгать на головы. Просто исправь это. Очень плохой путь миграции. Шлем отстой.
@antonakv какой способ начать год :)
Я думаю, что в целом мы играем с огнем, предоставляя clusterIP в качестве настраиваемого значения на диаграмме, и не можем полностью винить в этом один инструмент / человека / PR в частности.
Если clusterIP должно быть настраиваемым значением, по умолчанию его не должно быть в отображаемом шаблоне, это идея моего комментария в файлах значений в соответствии с https://github.com/helm/charts/blob/270172836fd8cf56d787cf7d04d938856de0c794/stable /nginx-ingress/values.yaml#L236
Это, если я не ошибаюсь, должно предотвратить будущие головные боли для тех, кто устанавливает диаграмму после этого изменения. Но для тех из нас (включая меня), кто установил его ранее, а затем перешел на helm3, я боюсь жестко записать текущие значения clusterIP в наших файлах значений ИЛИ удалить и переустановить диаграмму (вызывает простои!) - единственные варианты, которые я могу видеть.
Мнение мое собственное, мне не платят за работу на штурвале, я просто конечный пользователь вроде вас. Те, кому платят за работу на полную ставку, могут предоставить больше информации.
С Новым годом и удачи! Не отказывайтесь от руля, вместе мы можем сделать его лучше.
Привет, @bacongobbler , мы столкнулись с той же проблемой при
type: ClusterIP
в Service, но опускаемClusterIP
вообще, и получаем:
Error: UPGRADE FAILED: failed to replace object: Service "dummy" is invalid: spec.clusterIP: Invalid value: "": field is immutable
У нас нет
spec.clusterIP:
в нашем шаблоне helm, но мы получили эту ошибку после переноса выпуска через helm 2to3Шаблон услуги:
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 }}
У нас такая же проблема. Мы вообще не определяем clusterIP
в нашей диаграмме, и его нет в окончательном шаблоне. Однако мы по-прежнему получаем ту же ошибку, но только с флагом --force
.
Мы сталкиваемся с той же проблемой:
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
не является частью шаблона службы, но с Helm 3.0.2 и вызовом helm upgrade ... --force --install
мы также видим:
Ошибка: СБОЙ ОБНОВЛЕНИЯ: не удалось заменить объект: служба "пустышка" недействительна: spec.clusterIP: недопустимое значение: "": поле неизменяемо
Пожалуйста, откройте заново.
@ tomcruise81, пожалуйста, перейдите по ссылке https://github.com/helm/helm/issues/7350, чтобы узнать о --force
. Это приводит к той же ошибке, но это связано с тем, как работает kubectl replace
. Это отдельная проблема, отличная от описанной здесь, которая относится к IP-адресам кластера служб и стратегии трехстороннего исправления слияния ( helm upgrade
без флага --force
).
@bacongobbler - спасибо за быстрый ответ и разъяснения. Смотря на:
https://github.com/helm/helm/blob/a963736f6675e972448bf7a5fd141628fd0ae4df/pkg/kube/client.go#L405 -L411
которые используют https://github.com/kubernetes/cli-runtime/blob/master/pkg/resource/helper.go#L155 -L181, не похоже, что вызов helper.Replace
делает то же самое, что и kubectl replace -f ... --force
(обратите внимание на --force в конце).
Я предполагаю, что здесь большая путаница.
Я знаю, что ожидал helm upgrade ... --force
и при использовании стратегии замены он будет делать то же самое, что и kubectl replace -f ... --force
.
Привет, @bacongobbler , мы столкнулись с той же проблемой при
type: ClusterIP
в Service, но опускаемClusterIP
вообще, и получаем:
Error: UPGRADE FAILED: failed to replace object: Service "dummy" is invalid: spec.clusterIP: Invalid value: "": field is immutable
У нас нетspec.clusterIP:
в нашем шаблоне helm, но мы получили эту ошибку после переноса выпуска через helm 2to3
Шаблон услуги: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 }}
У нас такая же проблема. Мы вообще не определяем
clusterIP
в нашей диаграмме, и его нет в окончательном шаблоне. Однако мы по-прежнему получаем ту же ошибку, но только с флагом--force
.
Я также проверил, что в манифесте выпуска нет clusterIP
:
$ helm get manifest paywall-api-ee | grep clusterIP
$
то же самое здесь - мы нигде не определяем ClusterIP
но все равно видим ошибку
Еще немного повозившись с этим, я заметил следующее:
helm upgrade ... --force --install
- приводит к _The Service "dummy" недействителен: spec.clusterIP : Invalid value: "": field is immutable_helm template ... | kubectl apply -f -
- работаетhelm template ... | kubectl replace -f -
- приводит к _The Service "dummy" недействителен: spec.clusterIP : Invalid value: "": field is immutable_helm template ... | kubectl replace --force -f -
- работаетверсия kubectl - 1.14.6
версия helm - 3.0.2
@ tomcruise81, вы можете попробовать использовать плагин helm 2to3 и перейти с helm2 на выпуск helm3 и удалить --force
если вы его использовали ранее.
Это работа для нас.
Что касается меня, и похоже, что для других парней --force
имеет неправильное поведение и должен обрабатывать этот случай с неизменяемым полем, как для меня
@alexandrsemak - спасибо за рекомендацию. В моем случае я вижу это на диаграмме, которая была установлена или обновлена только с помощью helm 3.
То же самое для меня! С использованием
$ helm install my-release xxxxx
$ helm upgrade --install --force my-release xxxxx
В моем случае я не определяю ClusterIP ни для одной из служб, используемых на моем графике, но я сталкиваюсь с той же проблемой (см. Спецификации ниже):
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 }}
Как уже говорили другие пользователи, причина в том, что Kubernetes автоматически назначает Сервису IP-адрес кластера в первый раз (например, clusterIP: 10.96.26.65
), и это конфликтует с clusterIP: ""
при попытке обновления. Обратите внимание, что я не создаю это в своих шаблонах: clusterIP: ""
Пожалуйста, снова откройте этот
У меня такая же проблема.
@ juan131 @Ronsevet : remove --force Значение изменилось.
сталкиваются с той же проблемой на пользовательских диаграммах.
Мы нигде не определяем clusterip.
Шлем v3.0.2
kubectl 1.14.8
Проблема в том, что иногда диаграмма остается в состоянии сбоя, даже если модули созданы и запущены. Если мы попытаемся обновить тот же выпуск, это не сработает без применения силы.
Поскольку модули работают, выпуск не может быть удален и создан заново.
Должен быть способ применить "силу"
То же самое для меня - я просто добавил дополнительную метку к услуге и столкнулся с этой ошибкой. Также я нигде не определяю ClusterIP - пожалуйста, снова откройте проблему
@bacongobbler. Мы развертываем StorageClass как часть нашей диаграммы, и параметры StorageClass неизменны. Итак, в следующем выпуске, когда мы обновим значение некоторого параметра StorageClass, также произойдет сбой helm upgrade --force
.
Не знаю, как справиться с этим случаем для обновления StorageClasses. Какие-либо предложения?
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.
Он отлично работал в helm v2, поскольку helm upgrade --force
использовался для принудительного удаления и воссоздания StorageClass .
Если у кого-то возникают симптомы, которые не являются результатом объяснения, приведенного в https://github.com/helm/helm/issues/6378#issuecomment -557746499, не могли бы вы открыть новую проблему с вашими выводами и тем, как мы можем воспроизвести это с нашей стороны?
Проблема, поднятая OP, была связана с приведенным выше сценарием, где диаграмма устанавливает для ClusterIP пустую строку при установке. Вполне возможно, что существуют другие сценарии, в которых может возникнуть этот конкретный случай, например, о которых упоминалось в других случаях, с использованием флага --force
. Эти случаи следует обсуждать отдельно, так как диагноз и решение могут отличаться от советов, предоставленных ранее.
Спасибо!
@mssachan см. # 7082 и черновик предложения в # 7431 для вашего варианта использования. Это предложение направлено на реализацию kubectl replace —force
, которая будет аналогична поведению helm install —force
в Helm 2.
@mssachan см. # 7082 и черновик предложения в # 7431 для вашего варианта использования. Это предложение направлено на реализацию
kubectl replace —force
, которая будет аналогична поведениюhelm install —force
в Helm 2.
Хорошо, что это происходит. Даже если опустить флаг --force
, я все равно получаю сообщение об ошибке при обновлении диаграмм. Например, с 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 см. # 7082 и черновик предложения в # 7431 для вашего варианта использования. Это предложение направлено на реализацию
kubectl replace —force
, которая будет аналогична поведениюhelm install —force
в Helm 2.Хорошо, что это происходит. Даже если опустить флаг
--force
, я все равно получаю сообщение об ошибке при обновлении диаграмм. Например, с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
@ sc250024 У меня точно такая же проблема после того, как я обновил helm v2 до v3. Процесс обновления прошел гладко и без ошибок, затем я пытаюсь обновить cert-manager из helm, но с тем же результатом не удалось.
# 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"}
Любые обходные пути, когда --force не используется, или вообще не установлен параметр clusterIP
. Это мой манифест службы:
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 Вы когда-нибудь находили решение этой проблемы? Я вижу то же самое со своей стороны, и мои услуги определены точно так же, как и ваши. Вариант для clusterIP
не устанавливается, но Helm по-прежнему терпит неудачу при обновлении.
То же самое
Получив это также, повторно: два вышеупомянутых комментария.
Пожалуйста, предоставьте дополнительную информацию. Мы не можем помочь вам, не понимая причины или того, как эта проблема возникает в вашем случае. Спасибо.
У меня та же проблема, даже без установки типа службы или clusterIP с помощью helm v3.0.0-rc.2, если я использую параметр --force с командой helm update --install. Без --force он отлично работает
Прохладный! Я вдохновился вашим ответом, что мне нужно прокомментировать строку force: ..
в helmfile yaml:
helmDefaults:
tillerless: true
verify: false
wait: true
timeout: 600
# force: true <---- THI ONE IS COMMENTED
Работает 🎉
Я пробовал все вышеперечисленное, у меня ничего не работало. Мне пришлось отключить nginx-ingress
моем графике, выполнить обновление, снова включить его и снова обновить. Это привело к изменению IP-адреса, присвоенного облачным провайдером, но никакого вреда не было.
У меня та же проблема, даже без установки типа службы или clusterIP с помощью helm v3.0.0-rc.2, если я использую параметр --force с командой helm update --install. Без --force он отлично работает
Лучшее решение, у меня работает, спасибо!
У нас возникла та же проблема, и мы не можем найти ее решение.
Воспроизвести довольно просто
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
Мне было интересно, почему --force
здесь не работает, разве это не должно force resource updates through a replacement strategy
если это стратегия замены, тогда служба должна быть удалена, а затем заменена?
@bacongobbler Я попал в эту https://github.com/helm/helm/issues/7956
Как и все предыдущие комментаторы: у нас вообще нет «clusterIP» в шаблонах, но ошибка все еще присутствует в последней версии Helm, если используется флаг --force.
Версия Helm: 3.4.1
"helm -n kube-system get manifest CHART_NAME | grep clusterIP" не дает результатов.
Ошибка:
field is immutable && failed to replace object: Service "SERVICE_NAME" is invalid: spec.clusterIP: Invalid value: "": field is immutable
То же объяснение, приведенное в https://github.com/helm/helm/issues/6378#issuecomment -557746499, также применимо к вашему случаю @ nick4fake. Разница в том, что с --force
вы просите Kubernetes взять ваш полностью отрисованный манифест и принудительно перезаписать текущий живой объект. Поскольку ваш манифест не содержит поля clusterIP
, Kubernetes принимает это и предполагает, что вы пытаетесь удалить поле clusterIP
из живого объекта, отсюда и ошибка Invalid value: "": field is immutable
.
@bacongobbler Мне очень жаль, если я что-то здесь пропущу, может быть, я просто недостаточно знаю о внутренностях Helm.
«Я бы порекомендовал изменить вывод шаблона. Если в качестве значения не указан clusterIP, то не устанавливайте значение пустой строки ... Полностью опустите это поле».
Так какое же решение? Означает ли это, что флаг «--force» вообще нельзя использовать, если в поле clusterIP не установлено какое-то статическое значение?
Что касается Kubernetes: да.
Насколько я понимаю, это проблема Kubernetes, потому что «принудительная перезапись» не ведет себя так же, как «удаление и повторное создание». Есть ли ошибка апстрима?
С другой стороны, Helm также вводит в заблуждение, потому что --force
описывается как «принудительное обновление ресурсов с помощью стратегии замены». Хотя на самом деле он не выполняет никакой замены, он просто пытается принудительно перезаписать ресурсы (было бы лучше назвать флаг --force-overwrite
). Принудительная замена будет выглядеть как удаление и повторное создание (может быть флаг --force-recreate
). Конечно, --force-recreate
может быть немного опасно использовать для некоторых ресурсов, но это всегда будет успешным.
В любом случае, Helm мог бы реализовать запасной обходной путь для такого типа проблем. Если текущее поведение (описанное как --force-overwrite
) дает сбой и обнаруживает ошибку неизменяемого поля, он должен удалить и воссоздать ресурс (как --force-recreate
).
Самый полезный комментарий
У меня та же проблема, даже без установки типа службы или clusterIP с помощью helm v3.0.0-rc.2, если я использую параметр --force с командой helm update --install. Без --force он отлично работает