Amazon EKS Windows в GA з багами, зате найшвидше

Amazon EKS Windows в GA з багами, зате найшвидше

Доброго дня, хочу поділитися з вами своїм досвідом з налаштування та використання сервісу AWS EKS (Elastic Kubernetes Service) для Windows контейнерів, а точніше про неможливість його використання, та знайденого бага в системному контейнері AWS, тим кому цікавий цей сервіс для Windows контейнерів, прохання під кат.

Знаю що windows контейнери не популярна тема, і мало хто користується ними, але все ж таки вирішив написати цю статтю, тому що на Хабре було пару статей по kubernetes і windows і такі люди все-таки є.

Початок

Все почалося з того що сервіси у нашій компанії вирішено було мігрувати у kubernetes, це 70% windows та 30% linux. Для цього як один із можливих варіантів розглядався хмарний сервіс AWS EKS. До 8 жовтня 2019 року AWS EKS Windows був у Public Preview, я почав з нього, версія kubernetes там використовувалася стара 1.11, але я вирішив перевірити його все одно і подивитися на якому етапі даний хмарний сервіс, чи працездатний взагалі, як виявилося ні, там був Баг з додаванням видаленням подів, при цьому старі переставали відгукуватися по внутрішньому ip з тієї ж підмережі, де і windows worker node.

Тому було прийнято рішення відмовитися від використання AWS EKS на користь власного кластера на kubernetes на тих же EC2, тільки все балансування і HA довелося б описувати самому через CloudFormation.

Amazon EKS Windows Container Support now Generally Available

by Martin Beeby | on 08 OCT 2019

Не встиг я дописати template у CloudFormation для власного кластера, як побачив цю новину Amazon EKS Windows Container Support now Generally Available

Я звичайно ж відклав всі свої напрацювання, і почав вивчати, що вони зробили для GA, і як все змінилося з Public Preview. Так AWS молодці оновили образи для windows worker node до версії 1.14 і кластер версії 1.14 в EKS тепер з підтримкою windows nodes. Проект з Public Preview на гітхабе вони прикрили і сказали користуйтесь тепер офіційною документацією ось тут: EKS Windows Support

Інтеграція кластера EKS у поточний VPC та підмережі

У всіх джерелах, в посиланні вище за анонсом і в документації, пропонувалося деплоїти кластер або через фірмову утиліту eksctl або через CloudFormation + kubectl після, тільки з використанням public підмереж в Амазоні, а також зі створенням окремого VPC під новий кластер.

Такий варіант підходить не багатьом, по-перше, окремий VPC це додаткові витрати на його вартість + пірінг трафік до вашого поточного VPC. Що робити тим, у кого вже є готова інфраструктура в AWS зі своїми Multiple AWS accounts, VPC, subnets, route tables, transit gateway і так далі? Звичайно ж не хочеться все це ламати або переробляти, і треба інтегрувати новий кластер EKS в поточну мережну інфраструктуру, використовуючи наявний VPC ну і для розділення максимум створити нові підмережі для кластера.

У моєму випадку і був обраний цей шлях, я використав наявний VPC додав тільки по 2 public підмережі та по 2 private підмережі для нового кластера, звичайно ж всі правила були враховані згідно з документацією Create your Amazon EKS Cluster VPC.

Так само була одна умова жодних worker node в public subnets з використанням EIP.

eksctl vs CloudFormation

Обмовлюся відразу, що я пробував обидва методи деплою кластера, в обох випадках була картина однакова.

Покажу приклад лише з використанням eksctl, оскільки код, тут коротше вийде. За допомогою eksctl кластер деплоїти в 3 кроки:

1.Створюємо сам кластер + Linux worker node, на якому пізніше розмістяться системні контейнери і той самий злощасний vpc-controller.

eksctl create cluster 
--name yyy 
--region www 
--version 1.14 
--vpc-private-subnets=subnet-xxxxx,subnet-xxxxx 
--vpc-public-subnets=subnet-xxxxx,subnet-xxxxx 
--asg-access 
--nodegroup-name linux-workers 
--node-type t3.small 
--node-volume-size 20 
--ssh-public-key wwwwwwww 
--nodes 1 
--nodes-min 1 
--nodes-max 2 
--node-ami auto 
--node-private-networking

Для того щоб деплоїтися до існуючого VPC, достатньо вказати id ваших підмереж, і eksctl сам визначить VPC.

Щоб ваші worker node деплоїлися тільки в private підсіті, потрібно вказати node-private-networking для nodegroup.

2. Встановлюємо vpc-controller в наш кластер, який буде потім обробляти наші worker nodes вважаючи кількість вільних ip адрес, а також кількість ENI на інстансі, додаючи і видаляючи їх.

eksctl utils install-vpc-controllers --name yyy --approve

3.Після того як ваші системні контейнери успішно запустилися на вашому linux worker node у тому числі vpc-controller, залишилося тільки створити ще одну nodegroup з windows workers.

eksctl create nodegroup 
--region www 
--cluster yyy 
--version 1.14 
--name windows-workers 
--node-type t3.small 
--ssh-public-key wwwwwwwwww 
--nodes 1 
--nodes-min 1 
--nodes-max 2 
--node-ami-family WindowsServer2019CoreContainer 
--node-ami ami-0573336fc96252d05 
--node-private-networking

Після того, як ваша нода успішно зачепилася до вашого кластера і все начебто добре вона в статусі Ready, але ні.

Помилка у vpc-controller

Якщо спробувати запустити pods на windows worker node, то ми отримаємо помилку:

NetworkPlugin cni failed to teardown pod "windows-server-iis-7dcfc7c79b-4z4v7_default" network: failed to parse Kubernetes args: pod does not have label vpc.amazonaws.com/PrivateIPv4Address]

Якщо дивитися глибше, то ми бачимо, що наш інстанс в AWS виглядає ось так:

Amazon EKS Windows в GA з багами, зате найшвидше

А має бути так:

Amazon EKS Windows в GA з багами, зате найшвидше

З цього зрозуміло, що vpc-controller не відпрацював свою частину з якоїсь причини і не зміг додати нових ip-адрес на інстанс, щоб їх могли використовувати pod-и.

Ліземо дивитися логи pod-а vpc-controller і ось що ми бачимо:

kubectl log -n kube-system

I1011 06:32:03.910140       1 watcher.go:178] Node watcher processing node ip-10-xxx.ap-xxx.compute.internal.
I1011 06:32:03.910162       1 manager.go:109] Node manager adding node ip-10-xxx.ap-xxx.compute.internal with instanceID i-088xxxxx.
I1011 06:32:03.915238       1 watcher.go:238] Node watcher processing update on node ip-10-xxx.ap-xxx.compute.internal.
E1011 06:32:08.200423       1 manager.go:126] Node manager failed to get resource vpc.amazonaws.com/CIDRBlock  pool on node ip-10-xxx.ap-xxx.compute.internal: failed to find the route table for subnet subnet-0xxxx
E1011 06:32:08.201211       1 watcher.go:183] Node watcher failed to add node ip-10-xxx.ap-xxx.compute.internal: failed to find the route table for subnet subnet-0xxx
I1011 06:32:08.201229       1 watcher.go:259] Node watcher adding key ip-10-xxx.ap-xxx.compute.internal (0): failed to find the route table for subnet subnet-0xxxx
I1011 06:32:08.201302       1 manager.go:173] Node manager updating node ip-10-xxx.ap-xxx.compute.internal.
E1011 06:32:08.201313       1 watcher.go:242] Node watcher failed to update node ip-10-xxx.ap-xxx.compute.internal: node manager: failed to find node ip-10-xxx.ap-xxx.compute.internal.

Пошуки в гугле ні до чого не привели, тому що такий баг мабуть ні хто не зловив ще, ну або не застиг issue по ньому, довелося думати спочатку варіанти самому. Перше що спало на думку так це можливо vpc-controller не може відрізати ip-10-xxx.ap-xxx.compute.internal і достукатися до нього і тому помилки валяться.

Так, дійсно у нас використовуються кастомні dns сервери в VPC і амазонівські ми в принципі не використовуємо тому навіть forwarding не був налаштований на цей домен ap-xxx.compute.internal. Я перевірив цей варіант, і він не приніс результатів, можливо, тест був не чистим, і тому далі при спілкуванні з техпідтримкою я піддався на їхню ідею.

Так як ідей особливо не було, всі security group створювалися самим eksctl, тому вірити в їх справність не було сумніву, таблиці маршрутів теж були правильними, nat, dns, доступ в інтернет з worker nodes теж був.

При цьому якщо задеплоїти worker node в public підсіти без використання - node-private-networking, ця нода відразу оновлювалася vpc-controller-ом і все працювало як годинник.

Варіантів було два:

  1. Забити і почекати поки хтось опише баг цей в AWS і вони його виправлять і потім можна спокійно користуватися AWS EKS Windows, адже вони тільки зарелізувалися в GA (пройшло 8 днів на момент написання статті), напевно багато хто піде тим же шляхом що і я .
  2. Написати в AWS Support і викласти їм суть проблеми з усією пачкою логів звідусіль і довести їм, що їхній сервіс не працює при використанні свого VPC та підмереж, не дарма у нас була Business підтримка, треба ж її хоч раз використовувати 🙂

Спілкування з інженерами AWS

Створивши тикет, на порталі, я помилково вибрав відповісти мені через Web - email or support center, через цей варіант вони можуть вам відповісти через кілька днів взагалі, при тому що мій тикет мав Severity - System impaired, що мало на увазі відповідь на протязі <12 годин, а так як у Business support plan 24/7 підтримка, я сподівався на краще, але вийшло як завжди.

Мій тикет провалявся в Unassigned з п'ятниці до понеділка, потім я вирішив написати їм ще раз і вибрав варіант відповіді Chat. Недовго чекаючи до мене призначився Harshad Madhav, і тут почалося…

Ми розмовляли з ним в режимі онлайн години 3 поспіль, передача логів, деплой такого ж кластера в лабораторії AWS для емуляції проблеми, перестворення кластера з мого боку і так далі, тільки до чого ми прийшли це те, що по логах було видно що не працює резол внутрішніх імен AWS про що я писав вище, і Harshad Madhav попросив мене створити forwarding нібито ми використовуємо кастомний днс і це може бути проблемою.

Пересилання

ap-xxx.compute.internal  -> 10.x.x.2 (VPC CIDRBlock)
amazonaws.com -> 10.x.x.2 (VPC CIDRBlock)

Що і було зроблено, день закінчився Harshad Madhav відписався що перевір і має працювати, але ні, резолв ні чим не допоміг.

Далі було спілкування ще з 2 інженерами один просто відвалився від чату, мабуть злякався складного кейсу, другий витратив мій день на знову повний цикл дебагу, пересилання логів, створення кластерів з обох сторін, в результаті він просто сказав ну у мене працює, ось я по офіційної документації все роблю покроково зроби, і ти і в тебе все вийде.

На що я ввічливо попросив його піти і призначити на мій тикет іншого, якщо ти не знаєш де шукати проблему.

Фінал

На третій день, до мене призначився новий інженер Arun B., і з самого початку спілкування з ним було відразу зрозуміло, що це не 3 попередні інженери. Він прочитав усю історію відразу попросив зібрати логи його самописним скриптом на ps1 який лежав у нього на гітхабі. Далі було знову всі ітерації створення кластерів, виведення результатів команд, збирання логів, але Arun B. рухався в правильному напрямку судячи з питань, що задаються мені.

Коли ми дійшли до того, щоб увімкнути -stderrthreshold=debug в їхньому vpc-controller, і що сталося далі? він звичайно не працює) pod просто не запускається з такою опцією, працює тільки -stderrthreshold = info.

На цьому ми закінчили та Arun B. сказав що буде намагатися відтворювати мої кроки щоб отримати таку саму помилку. Наступного дня я отримую відповідь від Arun B. він не кинув цей кейс, а взявся за review code їхнього vpc-controller і знайшов місце де воно і чому не працює:

Amazon EKS Windows в GA з багами, зате найшвидше

Таким чином, якщо ви використовуєте main route table у вашому VPC, то по дефолту у нього немає асоціацій з потрібними підмережами, так необхідні vpc-controller-у, у випадку з public підмережею, у неї кастомна route table яка має асоціацію.

Додавши вручну асоціації для main route table з потрібними підмережами, і перестворивши nodegroup, все працює ідеально.

Я сподіваюся що Arun B. дійсно повідомить про цей баг розробникам EKS і ми побачимо нову версію vpc-controller-а де буде працювати все з коробки. На даний момент остання версія: 602401143452.dkr.ecr.ap-southeast-1.amazonaws.com/eks/vpc-resource-controller:0.2.1
має цю проблему.

Дякуємо всім хто дочитав до кінця, тестуйте все, що збираєтеся використовувати в production, перед впровадженням.

Джерело: habr.com

Додати коментар або відгук