Недавно я начал обновлять один из наших инструментов развертывания, чтобы он использовал helm3. Текущий инструмент - это приложение golang, которое, учитывая путь к диаграмме управления и kubeconfig, будет развернуто во всех наших производственных пространствах имен (в этом кластере) одновременно с помощью helm (позже мы напишем об этом отдельный блог).
Как мы сейчас выполняем развертывание в кластере k8s
Нынешний инструмент, который мы используем, использует библиотеки helm2 вроде ... когда Обама еще был президентом. Библиотеки go были не очень удобны в использовании, а документации было довольно мало ... не говоря уже о головной боли размера Шакила О’Нила, которую я получил от попыток заставить библиотеки 4-летней давности с различными зависимостями играть хорошо. Чтобы использовать helm, нам пришлось использовать метод переадресации портов из Kubernetes для привязки локального порта к сервисному порту tiller (44134).
func getHelmClient(kcfg string) *helm.Client { config, _ := clientcmd.BuildConfigFromFlags(“”, kcfg) client, _ := kubernetes.NewForConfig(config) // port forward tiller tillerTunnel, _ := portforwarder.New(“kube-system”, client, config) // new helm client host := fmt.Sprintf(“127.0.0.1:%d”, tillerTunnel.Local) helmClient := helm.NewClient(helm.Host(host)) return helmClient }
Переход на Helm3
Я не собираюсь вдаваться в дискуссию «я люблю штурвал, но ненавижу румпель», но, разумеется, переходить к helm3 было большим удовольствием. Появилось множество новых функций, одна из которых - исчезновение Tiller, а helm будет напрямую взаимодействовать с Kubernetes API.
В разгар исследования того, как загрузить kubeconfig из кластера EKS, я наткнулся на эту жемчужину вопроса в StackOverflow. Как и любой хороший разработчик, я скопировал и вставил этот код без всяких сожалений по поводу человеческой жизни.
Суть сообщения в том, что «aws eks update-kubeconfig» - это удобная функция. Общий процесс программного доступа к вашему кластеру EKS заключается в использовании серии библиотек и вызовов API для генерации токена для создания клиентского набора K8s для взаимодействия с вашим кластером. С появлением возможности передавать токен-носитель для аутентификации в helm3 cli я надеялся увидеть, смогу ли я программно усовершенствовать библиотеки go, чтобы они делали то же самое.
Получите токен авторизации k8s
Вот где я копирую / прошиваю ... err написал код для получения клиента kubernetes (и для возврата токена аутентификации)
func NewClientset(cluster *eks.Cluster) (*kubernetes.Clientset, *rest.Config, error) { gen, err := token.NewGenerator(true, false) if err != nil { return nil, nil, err } opts := &token.GetTokenOptions{ ClusterID: aws.StringValue(cluster.Name), } tok, err := gen.GetWithOptions(opts) if err != nil { return nil, nil, err } ca, err := base64.StdEncoding.DecodeString(aws.StringValue(cluster.CertificateAuthority.Data)) if err != nil { return nil, nil, err } restConfigs := &rest.Config{ Host: aws.StringValue(cluster.Endpoint), BearerToken: tok.Token, TLSClientConfig: rest.TLSClientConfig{ CAData: ca, }, } clientset, err := kubernetes.NewForConfig(restConfigs) if err != nil { return nil, nil, err } return clientset, restConfigs, nil }
Создать собственный ActionConfig
В helm3 pkg/action
содержит клиента, который обрабатывает большинство / все действия Helm. Теперь цель состоит в том, чтобы найти способ определить конфигурацию настраиваемого действия (я считаю, что по умолчанию установлено чтение kubeconfig). Используя приведенный ниже код, вы можете установить токен в качестве входных данных с предыдущего шага.
func GetActionConfig(namespace string, config *rest.Config) (*action.Configuration, error) { actionConfig := new(action.Configuration) var kubeConfig *genericclioptions.ConfigFlags insecure := true kubeConfig = genericclioptions.NewConfigFlags(false) kubeConfig.APIServer = &config.Host kubeConfig.BearerToken = &config.BearerToken kubeConfig.Namespace = &namespace kubeConfig.Insecure = &insecure if err := actionConfig.Init(kubeConfig, namespace, os.Getenv("HELM_DRIVER"), log.Printf); err != nil { return nil, err } return actionConfig, nil }
Собираем все вместе
Вот функция для вывода списка ваших релизов в Helm после аутентификации на вашем EKScluster
func main() { name := "name-of-your-cluster" region := "your-region" sess := session.Must(session.NewSession(&aws.Config{ Region: aws.String(region), })) eksSvc := eks.New(sess) input := &eks.DescribeClusterInput{ Name: aws.String(name), } result, err := eksSvc.DescribeCluster(input) if err != nil { log.Fatalf("Error calling DescribeCluster: %v", err) }
// pass cluster results to generate token and k8s client clientset, cfg, err := newClientset(result.Cluster) if err != nil { log.Fatalf("Error creating clientset: %v", err) }
// initalize actionconfig actionConfig, err := getActionConfig("your-namespace", cfg) if err != nil { log.Println(err) } client := action.NewList(actionConfig) releases, err := client.Run() if err != nil { log.Println(err) } for _, release := range releases { log.Println("Release: " + release.Name + " Status: " + release.Info.Status.String()) }}
В целом это был довольно интересный проект, чтобы исследовать и опробовать его. Многие из сложных вопросов задавали и отвечали на них гораздо более умные и талантливые разработчики. Я сопоставляю это, поскольку мне еще не приходилось видеть какую-либо документацию по этому поводу в Интернете. Кроме того, это было бесценно для меня в моем пути разработки с Kubernetes и Helm.