我正在使用 Kubernetes golang Operator sdk 来实现管理 RabbitMQ 队列的 Operator。我想知道 k8s 是否有办法在我的自定义资源上强制执行特定规范字段的不变性。我有以下 golang 结构,它表示一个rabbitMQ队列和一些参数以将其绑定到rabbitMQ交换:
type RmqQueueSpec struct {
VHost string `json:"vhost,required"`
Exchange string `json:"exchange,required"`
RoutingKey string `json:"routingKey"`
SecretConfig map[string]string `json:"secretConfig"`
}
我想要不变性的原因,特别是
VHost
字段,是因为它是一个用于在rabbitMQ中命名队列的参数。如果对现有部署的队列进行更改,k8s 协调器将无法查询rabbitMQ 的预期队列,因为它将使用不同的虚拟主机(实际上是不同的命名空间)进行查询,这可能会导致创建新队列或更新错误的队列。
我正在考虑一些替代方案,例如使用必需的 ObjectMeta.Name 字段来包含连接的虚拟主机和队列名称,以确保它们对于已部署的队列是不可变的。或者以某种方式在操作员中缓存较旧的规格(尚未弄清楚如何执行此操作),并在协调器中对旧规格和当前规格进行比较,如果
VHost
发生变化,则返回错误。然而,这两种方法似乎都不理想。理想情况下,如果运算符框架可以在 VHost
字段上强制执行不变性,那么这将是处理此问题的简单方法。
可以通过使用 ValidatingAdmissionWebhook 来实现此验证,未来将通过 CRD 的 OpenAPI 验证提供支持。
据我所知,CRD 尚无法使用此功能。我们的方法通常是使用对象名称作为被控制对象的默认名称(在本例中为虚拟主机名称),因此它自然就可以了。
现在即使没有使用 CEL 转换规则的 ValidationAdmissionWebhook,这也是可能的。
如果您使用的是controller-gen,您可以这样做:
type RmqQueueSpec struct {
// +kubebuilder:validation:XValidation:rule="self == oldSelf",message="VHost is immutable"
VHost string `json:"vhost,required"`
Exchange string `json:"exchange,required"`
RoutingKey string `json:"routingKey"`
SecretConfig map[string]string `json:"secretConfig"`
}