在寫 k8s的CRD controller的時候遇到需要用到subresources的情況
首先編寫CRD文件的時候生命subresource
這里用kube-batch舉例子
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: podgroups.scheduling.sigs.dev
spec:
group: scheduling.sigs.dev
names:
kind: PodGroup
plural: podgroups
scope: Namespaced
validation:
openAPIV3Schema:
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
properties:
minMember:
format: int32
type: integer
queue:
type: string
priorityClassName:
type: string
type: object
status:
properties:
succeeded:
format: int32
type: integer
failed:
format: int32
type: integer
running:
format: int32
type: integer
type: object
type: object
version: v1alpha2
subresources:
status: {}
所使用的types.go
// +genclient
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// PodGroup is a collection of Pod; used for batch workload.
type PodGroup struct {
metav1.TypeMeta `json:",inline"`
// Standard object's metadata.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata
// +optional
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"`
// Specification of the desired behavior of the pod group.
// More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#spec-and-status
// +optional
Spec PodGroupSpec `json:"spec,omitempty" protobuf:"bytes,2,opt,name=spec"`
// Status represents the current information about a pod group.
// This data may not be up to date.
// +optional
Status PodGroupStatus `json:"status,omitempty" protobuf:"bytes,3,opt,name=status"`
}
// PodGroupSpec represents the template of a pod group.
type PodGroupSpec struct {
// MinMember defines the minimal number of members/tasks to run the pod group;
// if there's not enough resources to start all tasks, the scheduler
// will not start anyone.
MinMember int32 `json:"minMember,omitempty" protobuf:"bytes,1,opt,name=minMember"`
// Queue defines the queue to allocate resource for PodGroup; if queue does not exist,
// the PodGroup will not be scheduled.
Queue string `json:"queue,omitempty" protobuf:"bytes,2,opt,name=queue"`
// If specified, indicates the PodGroup's priority. "system-node-critical" and
// "system-cluster-critical" are two special keywords which indicate the
// highest priorities with the former being the highest priority. Any other
// name must be defined by creating a PriorityClass object with that name.
// If not specified, the PodGroup priority will be default or zero if there is no
// default.
// +optional
PriorityClassName string `json:"priorityClassName,omitempty" protobuf:"bytes,3,opt,name=priorityClassName"`
}
// PodGroupStatus represents the current state of a pod group.
type PodGroupStatus struct {
// Current phase of PodGroup.
Phase PodGroupPhase `json:"phase,omitempty" protobuf:"bytes,1,opt,name=phase"`
// The conditions of PodGroup.
// +optional
Conditions []PodGroupCondition `json:"conditions,omitempty" protobuf:"bytes,2,opt,name=conditions"`
// The number of actively running pods.
// +optional
Running int32 `json:"running,omitempty" protobuf:"bytes,3,opt,name=running"`
// The number of pods which reached phase Succeeded.
// +optional
Succeeded int32 `json:"succeeded,omitempty" protobuf:"bytes,4,opt,name=succeeded"`
// The number of pods which reached phase Failed.
// +optional
Failed int32 `json:"failed,omitempty" protobuf:"bytes,5,opt,name=failed"`
}
注意的幾個地方。
1. 當用yaml文件提交的時候,設置了status屬性是沒用的,因為默認提交的地址是資源的路徑 也就是 /apis/{groupname}/{version}/namespaces/{ns}/{resourcesname}/{name}
所以這個subresources的狀態設置不上去
例如我提交一個
apiVersion: scheduling.incubator.k8s.io/v1alpha1 kind: PodGroup metadata: name: qj-1 spec: minMember: 6
# 這個屬性不會被kubectl命令設置上去 status succeeded: 1
來看下 CRD subresouces在k8s中的定義
// CustomResourceSubresources defines the status and scale subresources for CustomResources.
type CustomResourceSubresources struct {
// Status denotes the status subresource for CustomResources
Status *CustomResourceSubresourceStatus
// Scale denotes the scale subresource for CustomResources
Scale *CustomResourceSubresourceScale
}
// CustomResourceSubresourceStatus defines how to serve the status subresource for CustomResources.
// Status is represented by the `.status` JSON path inside of a CustomResource. When set,
// * exposes a /status subresource for the custom resource
// * PUT requests to the /status subresource take a custom resource object, and ignore changes to anything except the status stanza
// * PUT/POST/PATCH requests to the custom resource ignore changes to the status stanza
type CustomResourceSubresourceStatus struct{}
// CustomResourceSubresourceScale defines how to serve the scale subresource for CustomResources.
type CustomResourceSubresourceScale struct {
// SpecReplicasPath defines the JSON path inside of a CustomResource that corresponds to Scale.Spec.Replicas.
// Only JSON paths without the array notation are allowed.
// Must be a JSON Path under .spec.
// If there is no value under the given path in the CustomResource, the /scale subresource will return an error on GET.
SpecReplicasPath string
// StatusReplicasPath defines the JSON path inside of a CustomResource that corresponds to Scale.Status.Replicas.
// Only JSON paths without the array notation are allowed.
// Must be a JSON Path under .status.
// If there is no value under the given path in the CustomResource, the status replica value in the /scale subresource
// will default to 0.
StatusReplicasPath string
// LabelSelectorPath defines the JSON path inside of a CustomResource that corresponds to Scale.Status.Selector.
// Only JSON paths without the array notation are allowed.
// Must be a JSON Path under .status or .spec.
// Must be set to work with HPA.
// The field pointed by this JSON path must be a string field (not a complex selector struct)
// which contains a serialized label selector in string form.
// More info: https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions#scale-subresource
// If there is no value under the given path in the CustomResource, the status label selector value in the /scale
// subresource will default to the empty string.
// +optional
LabelSelectorPath *string
}
支持 Status, Scale 兩種,
// * PUT requests to the /status subresource take a custom resource object, and ignore changes to anything except the status stanza
// * PUT/POST/PATCH requests to the custom resource ignore changes to the status stanza
當請求為 /status 的時會忽略對象的其他字段只修改 status
也就是說:如果想用命令行方式修改status字段,需要提交到 /apis/{groupname}/{version}/namespaces/{ns}/{resourcesname}/{name}/status
2. 在測試的時候如果想手動修改狀態怎么辦
要修改狀態必須先獲取當前對象,因為有reversion的限制,提交的對象會進行嚴重,所以先get
隨后在get出來的對象中加入status字段
curl --cacert {ca.pen} -H "Authorization: Bearer {token}" APISERVER/apis/{groupname}/{version}/namespaces/{ns}/{resourcesname}/{name}
假如返回結果為
{
...
"spec":{...}
}
修改添加status
{
...
"spec":{...},
"status":{"success":1}
}
隨后用這個body去請求
curl --cacert {ca.pen} -H "Authorization: Bearer {token}" -H "Content-Type: application/json" --request PUT APISERVER/apis/{groupname}/{version}/namespaces/{ns}/{resourcesname}/{name}/status --data '上邊body'
記得一定要先去請求最新的對象,因為會驗證resourceVersion
