Как получить метаданные AWS при создании узла с помощью client-go

Я работаю над написанием пользовательского контроллера для нашего кластера kubernetes, который будет прослушивать события узла и выполнять некоторые операции на узле. Я использую библиотеку kubernetes client-go и могу захватывать события kubernetes всякий раз, когда узел подключен или удален из кластера. Но возможно ли получить подробности об экземпляре AWS узла kubernetes, который был создан, например, идентификатор экземпляра, теги и т. Д.? Заранее спасибо.

PS: я установил кластер kubernetes, используя Kops

2 ответа

Решение

Получив событие для создания узла, это атрибут объекта object. Имя object.Name имеет частные dns экземпляра aws, который был создан. Используя приватные днс экземпляра, мы можем запросить идентификатор экземпляра, используя aws-sdk-go

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
        }
}

С помощью идентификатора экземпляра мы можем выполнять любые операции с экземпляром ec2 с помощью API-интерфейсов aws-sdk-go.

На узле Kubernetes в AWS некоторые элементы будут заполнены как часть меток узла и различных других частей метаданных узла:

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"
}

Информация об узле находится в 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)
  }

Однако на самом деле это, вероятно, не тот способ, которым вы хотите. Если вы выполняете это в кластере kops в AWS, узел, на котором работает ваша рабочая нагрузка, уже имеет доступ к API-интерфейсу AWS, а также роли IAM, необходимой для запроса данных узла.

Учитывая это, рассмотрите возможность использования AWS Go SDK. Вы можете легко запросить EC2, вот адаптированный пример:

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)
    }
}
Другие вопросы по тегам