- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有 k8s 运算符,它按预期工作,我需要向其他运算符 CRD(不是我的)添加一个“监视”,为了简单起见,我们将其称为 extCR
,我们的运算符 cr 称为inCR
,
我尝试了以下方法,但有一个问题是它如何触发协调。
func (r *Insiconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&Inv1alpha1.Iget{}}).
Watches(&source.Kind{Type: &ext.Se{}}, handler.EnqueueRequestsFromMapFunc(r.FWatch)).
Complete(r)
}
func (r *Insiconciler) FWatch(c client.Object) []reconcile.Request {
val := c.(*ivi.Srv)
req := reconcile.Request{NamespacedName: types.NamespacedName{Name: val.Name, Namespace: val.Namespace}}
return []reconcile.Request{req}
}
这里的问题是我触发了与 extCR
的协调,我想在 FWatch
内部更新 inCR
并开始协调inCR 而不是 extCR,我该怎么做?
我的意思是,为了避免像下面的代码这样的事情,因为有时协调是针对 inCR
完成的,有时是针对 extCR
并且我可以得到一些丑陋的 if's
func (r *Insiconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
var inCR FOO
var extCR BAR
if err := r.Get(ctx, req.NamespacedName, &inCR); err != nil {
return ctrl.Result{}, err
}
if err := r.Get(ctx, req.NamespacedName, &extCR); err != nil {
return ctrl.Result{}, err
}
我想知道处理这种情况的正确/干净的方法是什么
当您需要收听外部 CR(不是 Controller 的一部分)和内部 CR(来自您的 Controller )时的情况。
还有一件事——CR 是不同的 GVK,但是 exteranlCR 包含很多不需要的字段,只是其中的一些。但必填字段在两个 cr 上具有相同的名称
更新
type inCR struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec inSpec `json:"spec,omitempty"` / / ————————here is the difference
Status InsightTargetStatus `json:"status,omitempty"`
}
//—————— 这是在不属于我们的其他程序上定义的,因此不能“重用”
type Bar struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec extSpec `json:"spec,omitempty"` // ———————here is the difference
Status ServiceStatus `json:"status,omitempty"`
}
inSpec
具有以下字段(extSpec 的子集)
type inSpec struct {
name string
age int
}
和 extSpec
有那些字段以及更多不相关的字段
type extSpec struct {
name string
age int
foo string // not relevant
bar string // not relevant
bazz string // not relevant
}
最后,在 reconcile 中 我需要将 相关
字段移动到某些函数。 完全根据发生的事件(例如用户更新 extCR 或更新 inCR),完全y 有时需要 extCR 的字段,有时需要 inCR 的字段
更新2
func sharedLogic(r reconciler, ctx context.Context, c client.Object) (ctrl.Result, error) {
in := c.(*inCR)
vPass , e := vps.Get(ctx, r.Client, in.Spec.foo, in.Spec.bar)
return ctrl.Result{}, nil
}
But for extCR I should do the following
func sharedLogic(r reconciler, ctx context.Context, c client.Object) (ctrl.Result, error) {
ext := c.(*extCR)
vPass , e := vps.Get(ctx, r.Client, ext.Spec.val.foo, ext.Spec.val.bar)
return ctrl.Result{}, nil
}
最佳答案
需要注意的几点:
您可以在没有资源定义的情况下创建第二个 Controller 。在您的主文件中,两个 Controller 都将被注册。
如果 CRD 根本不相关,或者如果外部资源引用内部资源,这可能很有用,因此您可以在外部协调器中更改内部资源。
kubebuilder create api --group other --version v2 --kind External \
--resource=false --controller=true
这为您提供了一个带有 SetupWithManager
方法的 Controller ,如下所示。
func (r *ExternalReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
// Uncomment the following line adding a pointer to an instance of the controlled resource as an argument
// For().
Complete(r)
}
请注意 For 方法是如何被注释掉的,因为您需要从其他地方导入要观看的资源并引用它。
import (
...
otherv2 "other.io/external/api/v2"
)
...
func (r *ExternalReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&otherv2.External{}).
Complete(r)
}
如果您无法导入外部资源,您可以回过头来自己模拟它,但这可能不是一种非常干净的方法。您真的应该尝试从其他 Controller 项目中导入它。
kubebuilder edit --multigroup=true
kubebuilder create api --group=other --version v2 --kind External \
--resource --controller
另一种方式是当资源相互关联时,内部资源在其规范中引用了外部资源,并且在协调时知道如何在其规范中获取外部资源。可以在此处找到这方面的示例 https://book.kubebuilder.io/reference/watching-resources/externally-managed.html
type InternalSpec struct {
// Name of an external resource
ExternalResource string `json:"externalResource,omitempty"`
}
这意味着在每个协调循环中, Controller 将查找外部资源并使用它来管理内部资源。
func (r *InternalReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
_ = log.FromContext(ctx)
internal := examplev1.Internal{}
if err := r.Get(context.TODO(), types.NamespacedName{
Name: req.Name,
Namespace: req.Namespace,
}, &internal); err != nil {
return ctrl.Result{}, err
}
external := otherv2.External{}
if err := r.Get(context.TODO(), types.NamespacedName{
// note how the name is taken from the internal spec
Name: internal.Spec.ExternalResource,
Namespace: req.Namespace,
}, &internal); err != nil {
return ctrl.Result{}, err
}
// do something with internal and external here
return ctrl.Result{}, nil
}
问题在于,当内部资源没有变化时,即使外部资源发生变化,也不会触发协调事件。为了解决这个问题,我们可以通过观察外部资源来触发协调。注意 Watches
方法:
func (r *InternalReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
For(&examplev1.Main{}).
Watches(
&source.Kind{Type: &otherv2.ExternalResource{}},
handler.EnqueueRequestsFromMapFunc(r.triggerReconcileBecauseExternalHasChanged),
builder.WithPredicates(predicate.ResourceVersionChangedPredicate{}),
).
Complete(r)
}
为了知道我们应该为哪个内部对象触发事件,我们使用映射函数来查找所有引用了外部资源的内部对象。
func (r *InternalReconciler) triggerReconcileBecauseExternalHasChanged(o client.Object) []reconcile.Request {
usedByInternals := &examplev1.InternalList{}
listOps := &client.ListOptions{
FieldSelector: fields.OneTermEqualSelector(".spec.ExternalResource", o.GetName()),
Namespace: o.GetNamespace(),
}
err := r.List(context.TODO(), usedByInternals, listOps)
if err != nil {
return []reconcile.Request{}
}
requests := make([]reconcile.Request, len(usedByInternals.Items))
for i, item := range usedByInternals.Items {
requests[i] = reconcile.Request{
NamespacedName: types.NamespacedName{
Name: item.GetName(),
Namespace: item.GetNamespace(),
},
}
}
return requests
}
由于您更新了问题,我建议您执行以下操作。
我正在创建一个新项目和 2 个 Controller 。注意第二个 Controller 命令没有资源与 Controller 一起创建。这是因为 Controller 将观看外部资源。
mkdir demo && cd demo
go mod init example.io/demo
kubebuilder init --domain example.io --repo example.io/demo --plugins=go/v4-alpha
kubebuilder create api --group=demo --version v1 --kind Internal --controller --resource
kubebuilder create api --group=other --version v2 --kind External --controller --resource=false
$ tree controllers
controllers
├── external_controller.go
├── internal_controller.go
└── suite_test.go
现在我们需要一些共享逻辑,例如将其添加到 Controller 包中。我们将从两个调解器中调用它。
// the interface may need tweaking
// depending on what you want to do with
// the reconiler
type reconciler interface {
client.Reader
client.Writer
client.StatusClient
}
func sharedLogic(r reconciler, kobj *demov1.Internal) (ctrl.Result, error) {
// do your shared logic here operating on the internal object struct
// this works out because the external controller will call this passing the
// internal object
return ctrl.Result{}, nil
}
这是内部协调器的示例。
func (r *InternalReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
_ = log.FromContext(ctx)
obj := demov1.Internal{}
if err := r.Get(ctx, req.NamespacedName, &obj); err != nil {
return ctrl.Result{}, err
}
return sharedLogic(r, &obj)
}
在外部调节器中,我们也这样做。
func (r *ExternalReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
_ = log.FromContext(ctx)
// note, we can use the internal object here as long as the external object
// does contain the same fields we want. That means when unmarshalling the extra
// fields are dropped. If this cannot be done, you could first unmarshal into the external
// resource and then assign the fields you need to the internal one, before passing it down
obj := demov1.Internal{}
if err := r.Get(ctx, req.NamespacedName, &obj); err != nil {
return ctrl.Result{}, err
}
return sharedLogic(r, &obj)
}
func (r *ExternalReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
// note the external resource is imported from another project
// you may be able to watch this without import by creating a minimal
// type with the right GKV
For(otherv2.External{}).
Complete(r)
}
关于amazon-web-services - k8s controller watch other controller CR,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74261141/
我正在使用 Ubuntu 15.04 和 vim-gnome 7.4。 当我运行时: vim --version | grep -i +ruby 它返回: +ruby 基于:Vim Ruby Supp
我正在编写一个测试脚本,它将简单地运行带有几个参数的 *.EXE 文件,然后将结果输出到一个文件。我有一个 *.sh 测试脚本可以正确运行测试(但需要手动更新更多测试)。此脚本中的行如下所示: bla
我想知道之间的区别(如果可能的话提供示例)CR LF (Windows)、LF (Unix) 和 CR (Macintosh) 换行符类型。 最佳答案 CR和LF是控制字符,分别编码为0x0D(十进制
我正在尝试使用 PHP 正则表达式来查找 CR 3492161 或 cr 3492161。我尝试使用以下正则表达式,但它不起作用。请求你的帮助。 :-) 'CR\s/^\d{7}$/' 'CR\h/^
交换换行符(例如通过某些文本编辑器)是否会破坏 javascript 代码? 最佳答案 两个控制字符都是valid line breaks .事实上你甚至不需要换行符。这只是为了更好的可读性。除了在字
这个问题已经有答案了: How to correct variable overwriting misbehavior when parsing output? (3 个回答) 已关闭 5 年前。 我
好的,我计划创建一个文件来存储我将导入到程序中的数据。该程序将为 Linux、Windows 和可能的 Mac 编译。 现在我真正想知道的是,由于这些文件中的换行符,我是否需要这些数据文件略有不同,或
建议以下计划: import java.io.StringReader; import javax.xml.transform.OutputKeys; import javax
我正在尝试将“,”和“\n”放入文件中。所有值都是 0 ,除了 4, 9, 14, 19, 23...我放置 ',' 和 '\n' 但是输出即将到来: 0000,0000,0000,0000,0000
我一直在尝试通过 Python 学习 Open ERP 模块开发。我想出了一个我认为我不理解的源代码。我在浏览时尝试了几个互联网链接,但找不到有用的链接。我非常需要理解这一点。 cr.execute(
我目前正在使用 JSP 生成一些 vCard。我发现一些平台无法识别这些生成的 vCard,除非它们的行由回车符 (CR) 分隔,而 JSP 似乎默认只使用换行符 (LF) 来分隔行。 你们知道有什么
验证用户时出现以下错误:purchase_user@purchase 失败。 MongoDB-CR 身份验证失败。当我通过浏览器访问网络服务时,用户文档中缺少凭据。 但我能够从 mongo 验证 pu
首先我想说我已经阅读了 this post但是我仍然对 CR line terminators 有问题. 有一个文件叫build_test.sh , 我编辑在 leafpad它可以直接显示在 Vim
我最近才开始使用 vim,并且在添加大量有用的插件时玩得很开心。问题是,在设置所有插件期间的某个时候,我没有注意到 enter 键的映射停止正常工作。在插入模式下,当我按下 Enter 键时,如果当前
我正在寻找一种在 vim 中突出显示 ^M(CR) 的方法。 最佳答案 确保文件格式设置为 unix 或 mac 我的是: set fileformats=unix,mac 如果是 DOS,您将看不到
假设我有一个程序(例如在Perl中),将这样的内容写入STDOUT: print "123\t- 456"; print "\r+\n"; 在我的屏幕上,我看到以下结果: 123 + 456
我正在编写一个在特定条件下自动插入一些文本的函数。当我尝试模拟 Enter press 时,我卡在了某个部分。我想出了这个(显而易见的)代码: execute "normal! a\" 问题是它破坏了
我有一个 HTML 页面中的元素。我正在用 JavaScript 向其中写入数据,并想稍后检查用户是否更改了文本。但是,如果数据包含任何回车符,它们似乎会被悄悄删除,因此将从文本区域读取的文本与应该存
各位正则表达式专家, 我有一个充满表达式的平面文件,例如: SELECT * FROM CONVENIENT_ONE_LINE_QUERY "SELECT * FROM THIS_QUERY WHER
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 6 年前。 Improve th
我是一名优秀的程序员,十分优秀!