在 Kubernetes 资源的主体中使用字段路径访问属性。

huangapple go评论81阅读模式
英文:

Access a property in the body of a kubernetes resource using a field path

问题

我可以帮你翻译这段代码。以下是翻译的结果:

我想获取在PoddownwardAPI部分声明的字段的值。

apiVersion: v1
kind: Pod
metadata:
  name: sample
  namespace: default
spec:
  containers:
  - image: rpa
    imagePullPolicy: Always
    name: testbot
    volumeMounts:
    - mountPath: /etc/pod-info
      name: pod-info
  volumes:
  - downwardAPI:
      items:
      - fieldRef:
          apiVersion: v1
          fieldPath: metadata.labels
        path: labels
      - fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
        path: pod-name
      - fieldRef:
          apiVersion: v1
          fieldPath: metadata.namespace
        path: pod-namespace
    name: pod-info

使用client-go,我可以使用pod.Spec.Volumes[0].DownwardAPI.Items来获取包含fieldPath的项切片。但是,我现在需要动态地获取在fieldPath中声明的任何值。所以,从第一个项开始,我想要访问metadata.labels的值。我可以使用pod.ObjectMeta.Labels,但我想要动态地访问该字段。在JavaScript中,可以这样做:

var foo = "metadata.labels";
var fooarr = foo.split(".");
var bar = {
  metadata: {
    labels: "foobar"
  }
};
var temp = bar;
for (lm of fooarr) {
  temp = temp[lm];
}
console.log(temp);

我该如何在client-go中实现类似的功能呢?

英文:

I want to get the values of the fields declared in the downwardAPI section of a Pod.

apiVersion: v1
kind: Pod
metadata:
  name: sample
  namespace: default
spec:
  containers:
  - image: rpa
    imagePullPolicy: Always
    name: testbot
    volumeMounts:
    - mountPath: /etc/pod-info
      name: pod-info
  volumes:
  - downwardAPI:
      items:
      - fieldRef:
          apiVersion: v1
          fieldPath: metadata.labels
        path: labels
      - fieldRef:
          apiVersion: v1
          fieldPath: metadata.name
        path: pod-name
      - fieldRef:
          apiVersion: v1
          fieldPath: metadata.namespace
        path: pod-namespace
    name: pod-info

Using client-go, I can use pod.Spec.Volumes[0].DownwardAPI.Items to get the item slice including the fieldPath. But I would now need to dynamically able to fetch whatever values has been declared in the fieldPath. So, from the first item, I would like to access the value of metadata.labels. I could do pod.ObjectMeta.Labels but I would like to access the field dynamically. In terms of Javascript it would have been something like

var foo="metadata.labels"
var fooarr = foo.split(".")
var bar={
  metadata:{
    labels: "foobar"
  }
}
var temp = oof
for(lm of lmaoarr){
  temp = temp[lm]
}
console.log(temp)

How do I do something similar using client-go?

答案1

得分: 1

标准的kubelet代码具有将下行API字段转换为环境变量的逻辑。然而,这并不简单也不通用:在堆栈的底部,只支持Kubernetes文档中列出的特定字段。只匹配这些特定字段可能是不完整的,但与标准的Kubernetes不一致也不是错误的。

实际的代码如下:

  1. 调用pods.ConvertDownwardAPIFieldLabel函数,它对字段进行了一些轻量级的规范化和验证:只允许在metadata.annotationsmetadata.labels上使用下标,只允许使用十几个特定的字段名,并且将spec.host重写为spec.nodeName
  2. 处理依赖于Pod规范或运行时数据中的非元数据字段的spec.*status.*变量。
  3. 委托给fieldpath.ExtractFieldPathAsString函数,它知道如何处理metadata.*变量。

k8s.io/kubernetes/pkg/fieldpath包中包含了一些在处理下行API时使用的辅助函数。对于你的具体问题,一个非常简短的答案可能就是调用fieldpath.ExtractFieldPathAsString函数,并将Pod对象作为参数传递给它,它将处理元数据字段但不处理其他字段。

英文:

The standard kubelet code has logic to translate the downward API fields into environment variables. It is neither simple nor generic, though: at the bottom of the stack, only the specific fields listed in the Kubernetes documentation are supported. It would be incomplete, but not wrong or inconsistent with standard Kubernetes, to just match on these specific fields:

for _, item := range downwardApiObject.Items {
        switch item.FieldPath.FieldRef {
        case "metadata.name":
                return pod.ObjectMeta.Name
        }
}

The actual code:

  1. Calls pods.ConvertDownwardAPIFieldLabel which does some very lightweight normalization and validation: subscripts are only allowed on metadata.annotations and metadata.labels, only the dozen or so specific field names are allowed, and spec.host is rewritten to spec.nodeName.
  2. Handles the spec.* and status.* variables that depend on non-metadata fields in the pod spec or runtime data.
  3. Delegates to fieldpath.ExtractFieldPathAsString which knows how to handle the metadata.* variables.

The k8s.io/kubernetes/pkg/fieldpath package contains a couple of helpers that are used in processing the downward API, and a really short answer to your specific question could be just to call fieldpath.ExtractFieldPathAsString passing it the Pod object, which will handle the metadata fields but nothing else.

huangapple
  • 本文由 发表于 2022年2月27日 21:16:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/71285074.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定