Я провел несколько тестов с Helm и получил ту же проблему при попытке изменить тип службы с NodePort/ClusterIP
на LoadBalancer
.
Вот как я воспроизвел вашу проблему:
Kubernetes 1.15.3 (GKE) Шлем 3.1.1
Диаграмма руля, используемая для теста: stable / nginx -ingress
Как я воспроизвел:
- Получить и распаковать файл:
helm fetch stable/nginx-ingress
tar xzvf nginx-ingress-1.33.0.tgz
Изменить тип службы с
type: LoadBalancer
на
type: NodePort
в файле
values.yaml
(строка 271):
sed -i '271s/LoadBalancer/NodePort/' values.yaml
Установить схему:
helm install nginx-ingress ./
Проверьте тип услуги, должно быть
NodePort
:
kubectl get svc -l app=nginx-ingress,component=controller
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx-ingress-controller NodePort 10.0.3.137 <none> 80:30117/TCP,443:30003/TCP 1m
Теперь измените тип сервиса снова на
LoadBalancer
в
values.yaml
:
sed -i '271s/NodePort/LoadBalancer/' values.yaml
Наконец, попробуйте обновить диаграмму, используя флаг
--force
:
helm upgrade nginx-ingress ./ --force
А затем:
Error: UPGRADE FAILED: failed to replace object: Service "nginx-ingress-controller" is invalid: spec.clusterIP: Invalid value: "": field is immutable
Объяснение
Копаться вокруг I нашел это в исходном коде HELM :
// if --force is applied, attempt to replace the existing resource with the new object.
if force {
obj, err = helper.Replace(target.Namespace, target.Name, true, target.Object)
if err != nil {
return errors.Wrap(err, "failed to replace object")
}
c.Log("Replaced %q with kind %s for kind %s\n", target.Name, currentObj.GetObjectKind().GroupVersionKind().Kind, kind)
} else {
// send patch to server
obj, err = helper.Patch(target.Namespace, target.Name, patchType, patch, nil)
if err != nil {
return errors.Wrapf(err, "cannot patch %q with kind %s", target.Name, kind)
}
}
При анализе кода выше Helm будет использовать аналогичный kubectl replace
API-запрос (вместо kubectl replace --force
, как мы могли ожидать) ... когда установлен флаг helm --force
.
Если нет, тогда Helm будет использовать kubectl patch
API-запрос для обновления.
Давайте проверим, имеет ли это смысл:
Po C с использованием kubectl
- Создать простой сервис как
NodePort
:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
labels:
app: test-svc
name: test-svc
spec:
selector:
app: test-app
ports:
- port: 80
protocol: TCP
targetPort: 80
type: NodePort
EOF
Сделать сервис создан:
kubectl get svc -l app=test-svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
test-svc NodePort 10.0.7.37 <none> 80:31523/TCP 25
Теперь давайте попробуем использовать kubectl replace
для обновления службы до LoadBalancer
, например helm upgrade --force
:
kubectl replace -f - <<EOF
apiVersion: v1
kind: Service
metadata:
labels:
app: test-svc
name: test-svc
spec:
selector:
app: test-app
ports:
- port: 80
protocol: TCP
targetPort: 80
type: LoadBalancer
EOF
Это показывает ошибку:
The Service "test-svc" is invalid: spec.clusterIP: Invalid value: "": field is immutable
Теперь, позволяет использовать kubectl patch
для изменения NodePort на LoadBalancer, имитируя команду обновления helm без --force
flag:
Здесь - документация патча kubectl если хочешь увидеть хо w для использования.
kubectl patch svc test-svc -p '{"spec":{"type":"LoadBalancer"}}'
Тогда вы увидите: service/test-svc patched
Обходной путь
Вам следует использовать helm upgrade
без --force
, это будет работа.
Если вам действительно нужно использовать --force
для воссоздания некоторых ресурсов, например, таких как pods, для получения последнего обновления configMap
, тогда я предлагаю вам сначала вручную изменить спецификации сервиса перед обновлением Helm.
Если вы пытаетесь изменить тип сервиса, вы можете сделать это, экспортируя сервис yaml
, изменив тип и применив его снова (потому что я испытывал это поведение только тогда, когда пытался применить тот же шаблон из первый раз):
kubectl get svc test-svc -o yaml | sed 's/NodePort/LoadBalancer/g' | kubectl replace --force -f -
Вывод:
service "test-svc" deleted
service/test-svc replaced
Теперь, если вы попытаетесь использовать helm upgrade --force
и не будете делать никаких изменений в сервисе, он будет работать и будет воссоздавать ваши стручки и другие ресурсы.
Я надеюсь, что это поможет вам!