从Kubernetes Pod /容器内部识别节点的区域

时间:2018-09-20 07:58:21

标签: kubernetes google-kubernetes-engine

我有一个用例,可以灵活地搜索机架信息,这需要我确定已安排Pod的区域。

我已经在SO之外看到了许多对此的请求,例如:

https://github.com/kubernetes/kubernetes/issues/40610

该区域未在向下的API中公开,因为它是节点标签,而不是Pod标签。

我想出的两个“答案”是:

a)向Google元数据终结点发出卷曲请求,以从计算引擎元数据中检索节点

b)通过向下的API识别节点名称,并使用节点名称调用Kube API以检索节点对象,并使用JQ之类的工具过滤JSON响应以获取区域。

我不喜欢选项B,因为它或多或少地针对API调用进行了硬编码,因此我需要提供一个包含JQ和curl的自定义docker映像。由于不是Kube原生,选项A感觉有点“ hacky”。​​

我错过了更好的解决方案吗?

预先感谢

4 个答案:

答案 0 :(得分:2)

我不是特别喜欢这种方式,但是我还没有找到一个更好的答案,github上的功能请求或错误报告似乎都没有。

我选择将配置映射与bash脚本一起使用,该脚本将执行curl请求和一些字符串操作,然后将其安装到具有volume / volumeMounts的容器中,并设置自定义入口点以执行脚本;将值注入elasticsearch.yml,然后执行ES本身:

apiVersion: v1
kind: ConfigMap
metadata:
  name: elastic
data:
  elastic.sh: |-
    set -e
    elasticConfig="/usr/share/elasticsearch/config/elasticsearch.yml"

    #this gives the us the node zone in the format projects/{projectnumber}/zones/{zone}
    zone=$(curl -sS http://metadata.google.internal/computeMetadata/v1/instance/zone -H 'Metadata-Flavor: Google')

    #Split and retain the text after the last /
    zone=${zone##*/}

    #Append it to elasticsearch.yml

    echo "\nnode.attr.zone: ${zone}" >> $elasticConfig
    echo "\ncluster.routing.allocation.awareness.attributes: zone" >> $elasticConfig

    echo "\ncluster.routing.allocation.awareness.force.zone.values: {{ .Values.elastic.shardAwareness.zones }}" >> $elasticConfig

我并不特别喜欢这种解决方案,因为它增加了不必要的开销,并且不是原生的。可以查询kube API,但有其自身的复杂性和技巧。我希望有一天向下的API会公开区域/区域标签,或者我可能会丢失某些东西,毕竟还有比这更好的方法。

如果没有别的,也许这会帮助别人,并阻止他们浪费时间在寻找似乎不存在的答案上进行搜索!

答案 1 :(得分:0)

我认为您可以使用pod anti-affinity做到这一点,这是一个示例:

spec:
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: security
              operator: In
              values:
              - S2
          topologyKey: failure-domain.beta.kubernetes.io/zone

更多详细信息,请参见kubernetes docs

答案 2 :(得分:0)

我的案例是Google Kubernetes Engine,我需要在pod上贴上区域/区域标签。

https://stackoverflow.com/a/52428782/8547463中,通过

获得区域的方法是@ dwillams782方法
curl -sS http://metadata.google.internal/computeMetadata/v1/instance/zone -H 'Metadata-Flavor: Google'`

,并通过https://github.com/devth/k8s-labeler中的方法将其设置为吊舱标签。基本上,我从pod的initContainer中调用了区域检测API。

答案 3 :(得分:0)

我深入了解了 init 容器等的常见答案,但后来意识到我正在云环境中工作,并且区域可通过内置端点使用。因此,只需使用您的云提供商的端点,例如

export RACK=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone`

AWS:https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html