gpt4 book ai didi

Kubernetes:为什么修补自定义资源的/状态子资源会更新父资源?

转载 作者:行者123 更新时间:2023-12-05 02:47:02 25 4
gpt4 key购买 nike

我正在尝试了解 Kubernetes 行为,因为它与自定义资源及其子资源有关——特别是 status 子资源。

具体来说,我想在不修改父自定义资源的情况下更新status 子资源。

据我所知,这应该是可能的。我已经查看了 [此处][1] 的文档,但我似乎无法让它按预期工作。

我正在使用 Docker Desktop 的 Kubernetes 1.19.3 进行测试。

这是场景......

  1. 创建这个简单的 CRD:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: greetings.k8s.test.io
spec:
group: k8s.test.io
versions:
- name: v1alpha1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
description: Greeting is the Schema for the Greetings Operator
type: object
properties:
message:
description: A friendly greeting
type: string
default: Hello World!
status:
type: object
properties:
ready:
description: The resource's readiness
type: boolean
additionalPrinterColumns:
- name: ready
type: boolean
description: Readiness of the created resource
jsonPath: .status.ready
subresources:
status: {}
scope: Namespaced
names:
plural: greetings
singular: greeting
kind: Greeting
shortNames:
- grt
  1. 创建演示资源:
apiVersion: k8s.test.io/v1alpha1
kind: Greeting
metadata:
name: demo
spec:
message: Hi there!
  1. 启动代理:
kubectl proxy &
  1. 在自定义资源上建立监视:
curl -L -s -X GET -H "Content-Type: application/json" \
-H "Accept: application/json, */*" \
127.0.0.1:8001/apis//k8s.test.io/v1alpha1/watch/namespaces/default/greetings

此时,您应该会看到类似于以下内容的输出:

{"type":"ADDED","object":{"apiVersion":"k8s.test.io/v1alpha1","kind":"Greeting","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"k8s.test.io/v1alpha1\",\"kind\":\"Greeting\",\"metadata\":{\"annotations\":{},\"name\":\"demo\",\"namespace\":\"default\"},\"spec\":{\"message\":\"Hi there!\"}}\n"},"creationTimestamp":"2020-12-10T04:02:55Z","generation":1,"managedFields":[{"apiVersion":"k8s.test.io/v1alpha1","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}}},"f:spec":{".":{},"f:message":{}}},"manager":"kubectl-client-side-apply","operation":"Update","time":"2020-12-10T04:02:55Z"}],"name":"demo","namespace":"default","resourceVersion":"532930","selfLink":"/apis/k8s.test.io/v1alpha1/namespaces/default/greetings/demo","uid":"40f3a618-74e5-4b14-9bd4-2eb47366d804"},"spec":{"message":"Hi there!"}}}
  1. PATCH /status 子资源
curl -k -s -X PATCH -H "Accept: application/json, */*" \
-H "Content-Type: application/merge-patch+json" \
127.0.0.1:8001/apis/k8s.test.io/v1alpha1/namespaces/default/greetings/demo/status \
--data '{"status":{"ready":true}}'

令人困惑的是,在提交 PATCH 之后,我们在父资源上的观察产生了......

{"type":"MODIFIED","object":{"apiVersion":"k8s.test.io/v1alpha1","kind":"Greeting","metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"k8s.test.io/v1alpha1\",\"kind\":\"Greeting\",\"metadata\":{\"annotations\":{},\"name\":\"demo\",\"namespace\":\"default\"},\"spec\":{\"message\":\"Hi there!\"}}\n"},"creationTimestamp":"2020-12-10T04:02:55Z","generation":1,"managedFields":[{"apiVersion":"k8s.test.io/v1alpha1","fieldsType":"FieldsV1","fieldsV1":{"f:metadata":{"f:annotations":{".":{},"f:kubectl.kubernetes.io/last-applied-configuration":{}}},"f:spec":{".":{},"f:message":{}}},"manager":"kubectl-client-side-apply","operation":"Update","time":"2020-12-10T04:02:55Z"},{"apiVersion":"k8s.test.io/v1alpha1","fieldsType":"FieldsV1","fieldsV1":{"f:status":{".":{},"f:ready":{}}},"manager":"curl","operation":"Update","time":"2020-12-10T04:05:22Z"}],"name":"demo","namespace":"default","resourceVersion":"533184","selfLink":"/apis/k8s.test.io/v1alpha1/namespaces/default/greetings/demo","uid":"40f3a618-74e5-4b14-9bd4-2eb47366d804"},"spec":{"message":"Hi there!"},"status":{"ready":true}}}

为什么要修改父资源?

如果我们检查资源,我们可以看到子资源的 status 确实已更新:

$ k get grt demo
NAME READY
demo true

我不知道这种行为是否符合预期以及我的理解有误,或者我的PATCH 方法是否有缺陷。

希望有人能帮帮忙。谢谢。

更新:

除了 PATCH 之外,我还可以确认 PUT(虽然操作更复杂)表现出完全相同的行为。

例子:

curl -k -s -X PUT -H "Accept: application/json, */*" \
-H "Content-Type: application/json" \
127.0.0.1:8001/apis/k8s.test.io/v1alpha1/namespaces/default/greetings/demo/status \
--data '{"apiVersion":"k8s.test.io/v1alpha1","kind":"Greeting","metadata":{"name":"demo","resourceVersion":"533184"},"status":{"ready":false}}'

¯\(ツ)

最佳答案

status 子资源实际上并不是一个不同的对象;它只是一个单独的 API 路径,只能修改对象中的顶级 status: block 。这很有用,因为您可以 set up an RBAC policy让您的 Controller 允许读取整个对象,但只允许写入对象的状态。

特别是,您在上一个命令中看到了这一点。如果您 kubectl get grt demo -o yaml,扩展的 YAML 语法将包含 status: 子 block 。更新状态的 Controller 将导致 status: 发生可见变化:因此您应该合理地期望 watch 会将此视为变化。

关于Kubernetes:为什么修补自定义资源的/状态子资源会更新父资源?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65228444/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com