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

Kos*_*ris 6 kubernetes kubectl kubernetes-ingress

我有以下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
Run Code Online (Sandbox Code Playgroud)

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

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

kubectl patch ing/main-ingress --patch '{ "spec" : { "rules": [{"http":{"paths":[ {"- path":"/"},{"backend":{"serviceName":"other-srvc"}},{"servicePort":"80"} ] }}]}}'
Run Code Online (Sandbox Code Playgroud)

我得到这个错误:

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
Run Code Online (Sandbox Code Playgroud)

任何见识将不胜感激!

Jan*_*art 5

您的补丁程序有很多问题;例如,"- path"代替"path"但又不正确地引用对象级别。但是,即使您纠正了错误,也无法按预期进行。让我们看看为什么。

kubectl patch是对战略合并补丁的要求。在.spec.rules和阵列打补丁时,如和,.spec.rules.http.paths在这种情况下,战略性合并补丁程序可以使用定义的补丁程序类型和对象的合并补丁程序合并键执行正确的操作。但是,对于Ingress对象,没有人愿意定义它们。这意味着任何补丁都将覆盖整个对象。它不会是一个人们希望的很好的合并。

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

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

以上将所有出现的be-srvc服务更改为some-srvc。请记住,这里存在一个短暂的竞争条件:如果在kubectl get运行后修改了Ingress ,更改将失败并显示错误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"}]'
Run Code Online (Sandbox Code Playgroud)

以上两个命令将改变为后端sample.domain.com/apisample2.domain.com/apisome-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"}]'
Run Code Online (Sandbox Code Playgroud)

这具有相同的效果,并且作为额外的奖励,此处没有比赛条件。该补丁保证是原子的。

  • 在[RFC 6902](https://tools.ietf.org/html/rfc6902)中进行了详细说明。还有一个[有关Kubernetes的特定修补程序文档](https://kubernetes.io/docs/tasks/run-application/update-api-object-kubectl-patch/)。希望能有所帮助。 (2认同)
  • 来自未来的评论 - 如果您使用较新的 API 并收到“请求无效”错误,您可能需要指定 Ingress 资源的完全限定名称,如下所示:“kubectl patch ingresses.v1.networking.k8s” .io 入口名称 --type=json (...)`。否则,Kubernetes 服务器可能会将“补丁入口”解释为来自具有不同 YAML 结构的旧 API 的资源。另请参阅此答案:/sf/ask/4625663661/ (2认同)