我有下面的yaml文件,我在其中创建了一个kubernetes CRD和一个自定义资源,作为该CRD的实例。
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: mycrds.example.com
spec:
group: example.com
version: v1
names:
kind: MyCrd
plural: mycrds
singular: mycrd
scope: Namespaced
---
apiVersion: example.com/v1
kind: MyCrd
metadata:
name: example-instance
namespace: default
spec:
selectors:
cluster:
matchName:
- '*'
如果我在此文件上执行kubectl apply
或kubectl create
,有时会得到一个错误no matches for kind "MyCrd" in version "example.com/v1"
,因为CRD注册尚未完成。这种情况并不总是发生。
示例错误消息:
$ kubectl apply -f crd-and-instance.yaml
customresourcedefinition.apiextensions.k8s.io/mycrds.example.com created
error: unable to recognize "/home/psankar/Downloads/crd-and-instance.yaml": no matches for kind "MyCrd" in version "example.com/v1"
$ # Same command executed after 2-3 seconds
$ kubectl apply -f crd-and-instance.yaml
customresourcedefinition.apiextensions.k8s.io/mycrds.example.com unchanged
mycrd.example.com/example-instance created
这种情况并不总是发生。有时,CRD会很快注册,并且kubectl create/apply命令在第一次尝试时运行良好。
我知道我可以通过shell脚本来实现这一点,比如:
kubectl create crd.yaml
kubectl wait until crd is published
kubectl create crdInstance.yaml
但我不想这样做,并且想要一个没有任何附带shell脚本的yaml文件。这可能吗?
kubectl apply -f
只是对k8s-API-server的API调用,它在k8s-etcd存储中创建资源。它既不能保证所需资源实际创建,也不能检查其状态。由于缺少外部依赖项、进入崩溃循环等原因,资源可能会在推出时卡住。
为了使序列同步工作,您需要注入某种健康检查(例如查询创建的资源的HTTP端点(。另一种方法是通过在调用之间包含sleep X
秒来延迟创建,让k8s完成创建。当然,这不会检查资源是否真的创建或失败。