如何在 Kubernetes 上修补已部署的 Ingress 资源?

How to patch a deployed Ingress resource on Kubernetes?

我有以下 Ingress 资源:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: main-ingress
  annotations:
    kubernetes.io/ingress.class: nginx
    nginx.ingress.kubernetes.io/ssl-redirect: "false"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "86400"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "86400"

spec:
  tls:
  - secretName: the-secret
    hosts:
      - sample.domain.com
      - sample2.domain.com
      - rabbit.domain.com
      - hub.domain.com
      - grafana.domain.com

  rules:

  - host: sample.domain.com
    http:
      paths:
      - path: /
        backend:
          serviceName: fe-srvc
          servicePort: 80
      - path: /api
        backend:
          serviceName: be-srvc
          servicePort: 80

  - host: sample2.domain.com
    http:
      paths:
      - path: /
        backend:
          serviceName: fe2-srvc
          servicePort: 80
      - path: /api
        backend:
          serviceName: be-srvc
          servicePort: 80

## The Extra Services ###
  - host: rabbit.domain.com
    http:
      paths:
      - path: /
        backend:
          serviceName: rabbitmq-srvc
          servicePort: 80

我想在部署后对其进行修补。

所以我用它来尝试用 some-srvc 替换 be-srvc 值:

kubectl patch ing/main-ingress --patch '{ "spec" : { "rules": [{"http":{"paths":[ {"- path":"/"},{"backend":{"serviceName":"other-srvc"}},{"servicePort":"80"} ] }}]}}'

我得到这个错误:

The Ingress "main-ingress" is invalid:
* spec.rules[0].http.backend.serviceName: Required value
* spec.rules[0].http.backend.servicePort: Invalid value: 0: must be between 1 and 65535, inclusive

如有任何见解,我们将不胜感激!

你的补丁有很多问题;例如 "- path" 而不是 "path",但对象级别的引用也不正确。但是,即使您修复了错误,这也不会按预期工作。让我们看看为什么。

kubectl patch 是对 战略合并补丁 的请求。修补阵列时,如本例中的 .spec.rules.spec.rules.http.paths 战略合并补丁 可以使用定义的 补丁类型 merge patch merge key 为对象做正确的事。然而,在 Ingress 对象的情况下,没有人费心去定义这些。这意味着任何补丁都会覆盖整个对象;这不会是人们所希望的完美合并。

要完成问题中提到的特定更改,您可以执行以下操作:

kubectl get ing/main-ingress -o json \ 
  | jq '(.spec.rules[].http.paths[].backend.serviceName | select(. == "be-srvc")) |= "some-srvc"' \
  | kubectl apply -f -

以上将把所有出现的 be-srvc 服务更改为 some-srvc。请记住,这里有一个短暂的竞争条件:如果 Ingress 在 kubectl get 运行 之后修改,则更改将失败并显示错误 Operation cannot be fulfilled on ingresses.extensions "xx": the object has been modified;要处理这种情况,您需要实施重试逻辑。

如果上面提到的数组中的索引是已知的,则可以直接完成补丁:

kubectl patch ing/main-ingress --type=json \
  -p='[{"op": "replace", "path": "/spec/rules/0/http/paths/1/backend/serviceName", "value":"some-srvc"}]'
kubectl patch ing/main-ingress --type=json \
  -p='[{"op": "replace", "path": "/spec/rules/1/http/paths/1/backend/serviceName", "value":"some-srvc"}]'

上面的两个命令会将 sample.domain.com/apisample2.domain.com/api 的后端更改为 some-srvc

这两个命令也可以这样组合:

kubectl patch ing/main-ingress --type=json \
  -p='[{"op": "replace", "path": "/spec/rules/0/http/paths/1/backend/serviceName", "value":"some-srvc"}, {"op": "replace", "path": "/spec/rules/1/http/paths/1/backend/serviceName", "value":"some-srvc"}]'

这具有相同的效果,作为额外的好处,这里没有竞争条件;补丁 gua运行teed 是原子的。