【问题标题】:How to get AWS metdata on node creation using client-go如何使用 client-go 获取有关节点创建的 AWS 元数据
【发布时间】:2018-07-26 21:15:49
【问题描述】:

我正在为我们的 kubernetes 集群编写自定义控制器,它将监听节点事件并在节点上执行一些操作。我正在使用 kubernetes client-go 库,并且能够在节点运行时捕获 kubernetes 事件附加或从集群中删除。但是是否可以获得已创建的 Kubernetes 节点的 AWS 实例详细信息,例如实例 ID、标签等?提前致谢。

PS:我已经使用 kops 安装了 kubernetes 集群

【问题讨论】:

    标签: kubernetes kops aws-sdk-go client-go


    【解决方案1】:

    在 AWS 中的 Kubernetes 节点上,您将填充一些内容作为节点标签的一部分和节点元数据的各种其他部分:

    kubectl get nodes -o json | jq '.items[].metadata.labels'
    
    {
      "beta.kubernetes.io/arch": "amd64",
      "beta.kubernetes.io/instance-type": "c5.large",
      "beta.kubernetes.io/os": "linux",
      "failure-domain.beta.kubernetes.io/region": "us-east-1",
      "failure-domain.beta.kubernetes.io/zone": "us-east-1b",
      "kubernetes.io/hostname": "<hostname>",
      "kubernetes.io/role": "master",
      "manufacturer": "amazon_ec2",
      "node-role.kubernetes.io/master": "",
      "operatingsystem": "centos",
      "tier": "production",
      "virtual": "kvm"
    }
    

    节点信息在node package here中的client-go中使用Get方法。这是一个例子:

      client := kubernetes.NewForConfigOrDie(config)
    
      list, err := client.CoreV1().Nodes().List(metav1.ListOptions{})
      if err != nil {
        fmt.Fprintf(os.Stderr, "error listing nodes: %v", err)
        os.Exit(1)
      }
    
      for _, node := range list.Items {
        fmt.Printf("Node: %s\n", node.Name)
        node, err := client.CoreV1().Nodes().Get(node.Name, metav1.GetOptions{})
        if err != nil {
          fmt.Fprintf(os.Stderr, "error getting node: %v", err)
          os.Exit(1)
        }
        fmt.Println(node)
      }
    

    然而这真的可能不是你想要的方式。如果您在 AWS 的 kops 集群上运行此程序,则运行工作负载的节点已经可以访问 AWS API 以及查询节点数据所需的 IAM role

    考虑到这一点,请考虑改用AWS Go SDK。你可以很容易地查询 EC2,这是一个adapted example

    package main
    
    import (
        "fmt"
    
        "github.com/aws/aws-sdk-go/aws"
        "github.com/aws/aws-sdk-go/aws/session"
        "github.com/aws/aws-sdk-go/service/ec2"
    )
    
    func main() {
        // Load session from shared config
        sess := session.Must(session.NewSessionWithOptions(session.Options{
            SharedConfigState: session.SharedConfigEnable,
        }))
    
        // Create new EC2 client
        ec2Svc := ec2.New(sess)
    
        // Call to get detailed information on each instance
        result, err := ec2Svc.DescribeInstances(nil)
        if err != nil {
            fmt.Println("Error", err)
        } else {
            fmt.Println("Success", result)
        }
    }
    

    【讨论】:

    • 感谢您的回答 :) 它在一定程度上帮助了我。使用 kubernetes 元数据我无法检索 ec2 元数据。而且只是通过 aws-sdk-go,我将无法映射相应的节点。使用私有 DNS 过滤实例(来自节点的主机名)提供了实例 ID,我可以通过该 ID 执行其他操作
    【解决方案2】:

    收到节点创建事件后,对象object的属性名object.Name有创建的 aws 实例的私有 dns。使用实例的私有 dns,我们可以使用 aws-sdk-go 查询 instance-id

    hostName := object.Name
    sess := session.Must(session.NewSessionWithOptions(session.Options{
        SharedConfigState: session.SharedConfigEnable,
    }))
    
    // Create new EC2 client
    ec2Svc := ec2.New(sess)
    var instanceId string
    params := &ec2.DescribeInstancesInput{
    Filters: []*ec2.Filter{
                    {
                            Name:   aws.String("private-dns-name"),
                            Values: []*string{aws.String(hostName)},
                    },
            },
    }
    // Call to get detailed information on each instance
    result, err := ec2Svc.DescribeInstances(params)
    if err != nil {
            fmt.Println("there was an error listing instances in", err.Error())
            log.Fatal(err.Error())
    }
    for idx, res := range result.Reservations {
            fmt.Println("  > Reservation Id", *res.ReservationId, " Num Instances: ", len(res.Instances))
            for _, inst := range result.Reservations[idx].Instances {
                    // result[idx].SetDisableApiTermination(true);
                    instanceId = *inst.InstanceId
                    fmt.Println("    - Instance ID: ", *inst.InstanceId)
                    break // Only one instance will match the private dns
            }
    }
    

    有了实例 ID,我们可以使用 aws-sdk-go API 对 ec2 实例执行任何操作。

    【讨论】:

      猜你喜欢
      • 2017-11-03
      • 2021-02-21
      • 2012-12-20
      • 1970-01-01
      • 2021-08-10
      • 2018-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多