我有以下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
我希望在部署后修补它。
所以我使用它,尝试用be-srvc
替换some-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
任何见解都将受到赞赏!
答案 0 :(得分:2)
你的补丁有很多问题;例如"- 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 -
以上内容会将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"}]'
上述两个命令会将sample.domain.com/api
和sample2.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"}]'
这具有相同的效果,并且作为额外的奖励,这里没有竞争条件;补丁保证是原子的。