Продолжаем знакомство с Kubernetes.
Предыдущие части:
- Kubernetes: знакомство, часть 1 — архитектура и основные компоненты, обзор
- Kubernetes: знакомство, часть 2 — создание кластера с AWS cloud-provider и AWS LoadBalancer
Следующие:
В этой части перейдём уже непосредственно к EKS – кратко его рассмотрим, потом создадим Kubernetes Control Plane, CloudFormation стек с Worker Nodes, запустим веб-сервис в новом кластере, и добавим LoadBalancer.
Содержание
Elastic Kubernetes Service – обзор
AWS EKS (Elastic Kubernetes Service) представляет собой Kubernetes-сервис, где пользователю не надо заниматься созданием и управлением ядра Kubernetes – его Control Plane.
- Control Plane: управляется самим Амазоном, состоит из трёх EC2 в различных Availability Zones, управляются самим AWS
- Worker Nodes: обычные ЕС2 в пользовательской VPC, управляются пользователем
Архитектура сети:
Для сети используется плагин amazon-vpc-cni-k8s, который позволяет подам кластера использовать ENI (Elastic Network Interface) и сетевое пространство VPC и подсетей в AWS.
Для авториазации используется плагин aws-iam-authenticator, который позволяет выполнять авторизацию кластера через AWS IAM роли и политики (см. Managing Users or IAM Roles for your Cluster)
AWS также сам выполняется минорные обновления, например с 1.11.5 to 1.11.8, но мажорные апгрейды на совести пользователя.
Подготовка AWS
Для создания кластера нам нужно поднять свою VPC, создать сети, настроить роутинг, и добавить IAM роль, которая будет использоваться кластером для авторизации.
IAM роль
Переходим в IAM, создаём новую роль, тип EKS:
Permissions AWS выберет сам:
Сохраняем:
VPC
Далее потребуется создать VPC и 4 подсети – две публичные, для Load Balancer, и две приватные – для Worker-нод.
Создаём VPC:
SecurityGroup
Переходим в SecurityGroups, создаём SG для кластера:
Добавляем правила:
Internet Gateway
Создаём IGW, через который будет ходить трафик из публичных подсетей:
Подключаем его к VPC:
Subnets
Pod-ы будут получать IP из подсетей (см. amazon-vpc-cni-k8s) – сделайте достаточно адресов.
Создаём первую публичную сеть с блоком 10.0.0.0/18 (всего-то 16384 адресов):
Вторую публичную – 10.0.64.0/18:
В публичных адреса – включаем добавление публичного IP инстансам:
И аналогично добавляем две приватные подсети:
NAT Gateway
В публичной подсети создаём NAT Gateway – через него будет ходить трафик из приватных подсетей:
(раньше не было кнопки Create EIP 😐 )
Сразу настраиваем маршрутизацию:
Route tables
Тут требуется создать две таблицы маршрутизации – одна для публичных подсетей, и вторую – для приватных.
Public route table
Создаём для публичной:
Редактируем маршруты – задаём 0.0.0.0/0 через IGW:
Переключаемся во вкладку Subnet association – подключаем две публичные подсети:
Private route table
Аналогично создаём вторую таблицу, для приватных подсетей:
Добавляем маршрут к 0.0.0.0/0 через NAT GW:
Возвращаемся к подсетям, подключаем к ним созданные таблицы маршрутизации – Edit route table association:
К приватным подсетям подключаем, соответственно, приватную RTB, с маршрутами через NAT:
К публичным – RTB с маршрутом через IGW:
Проверка
Для проверки – запустим две ЕС2, сначала в публичной подсети:
Указываем SG:
Проверяем сеть:
[simterm]
[setevoy@setevoy-arch-work ~] $ ssh -i setevoy-testing-eu-west-2.pem [email protected] 'ping -c 1 8.8.8.8' PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data. 64 bytes from 8.8.8.8: icmp_seq=1 ttl=51 time=1.33 ms --- 8.8.8.8 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 1.331/1.331/1.331/0.000 ms
[/simterm]
Добавляем ещё один ЕС2, в приватной подсети:
Не забываем SG.
И пингуем его с первого инстанса:
[simterm]
[setevoy@setevoy-arch-work ~] $ ssh -i setevoy-testing-eu-west-2.pem [email protected] 'ping -c 1 10.0.184.21' PING 10.0.184.21 (10.0.184.21) 56(84) bytes of data. 64 bytes from 10.0.184.21: icmp_seq=1 ttl=64 time=0.357 ms --- 10.0.184.21 ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.357/0.357/0.357/0.000 ms
[/simterm]
Если пинг не проходит – проверьте настройки Security Group, подключенной к инстансу.
На этом с подготовкой закончили – переходим к самому EKS.
EKS
Создание Control Plane
Создаём мастер-ноды – кликаем Create cluster:
Задаём имя, выбираем IAM-роль, созданную в самом начале:
В подсетях – выбираем только приватные и указываем нашу SecurityGroup:
Примечание: На самом деле, хотя EKS пишет про “подсети для ваших Worker Nodes – эти же подсети будут использоваться в случае использования, например, AWS Load Balancer, для которого нужны публичные сети. Поэтому – можно выбрать все: EKS будет исопльзовать приватные для ЕС2, и публичные – для ALB.
Можно сразу тут включить и логи:
Запускаем создание:
Создание Worker Nodes
Пока создаётся Control Plane – создадим CloudFormation стек для Worker Nodes.
Можно взять уже готовый шаблон, например – https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2019-02-11/amazon-eks-nodegroup.yaml.
Переходим в CloudFormation > Create stack:
Т.к. наши рабочие ноды будут в приватных подсетях – открываем файл в редакторе:
Находим AssociatePublicIpAddress
, меняем значеине с true на false:
Кликаем Create stack:
Задаём имя стека – любое, имя кластера – как мы задали выше, в данном примере eks-cluster-manual, выбираем нашу SecurityGroup, заполняем настройки AutoScale-группы:
Выбираем NodeImageId
, а зависимости от зоны (см. актуальные AM ID в документации):
Region | Amazon EKS-optimized AMI | with GPU support |
---|---|---|
US East (Ohio) (us-east-2 ) |
ami-0485258c2d1c3608f |
ami-0ccac9d9b57864000 |
US East (N. Virginia) (us-east-1 ) |
ami-0f2e8e5663e16b436 |
ami-0017d945a10387606 |
US West (Oregon) (us-west-2 ) |
ami-03a55127c613349a7 |
ami-08335952e837d087b |
Asia Pacific (Hong Kong) (ap-east-1 ) |
ami-032850771ac6f8ae2 |
N/A* |
Asia Pacific (Mumbai) (ap-south-1 ) |
ami-0a9b1c1807b1a40ab |
ami-005b754faac73f0cc |
Asia Pacific (Tokyo) (ap-northeast-1 ) |
ami-0fde798d17145fae1 |
ami-04cf69bbd6c0fae0b |
Asia Pacific (Seoul) (ap-northeast-2 ) |
ami-07fd7609df6c8e39b |
ami-0730e699ed0118737 |
Asia Pacific (Singapore) (ap-southeast-1 ) |
ami-0361e14efd56a71c7 |
ami-07be5e97a529cd146 |
Asia Pacific (Sydney) (ap-southeast-2 ) |
ami-0237d87bc27daba65 |
ami-0a2f4c3aeb596aa7e |
EU (Frankfurt) (eu-central-1 ) |
ami-0b7127e7a2a38802a |
ami-0fbbd205f797ecccd |
EU (Ireland) (eu-west-1 ) |
ami-00ac2e6b3cb38a9b9 |
ami-0f9571a3e65dc4e20 |
EU (London) (eu-west-2 ) |
ami-0147919d2ff9a6ad5 |
ami-032348bd69c5dd665 |
EU (Paris) (eu-west-3 ) |
ami-0537ee9329c1628a2 |
ami-053962359d6859fec |
EU (Stockholm) (eu-north-1 ) |
ami-0fd05922165907b85 |
ami-0641def7f02a4cac5 |
В данном случае регион London/eu-west-2, GPU не нужен, значит – ami-0147919d2ff9a6ad5 (Amazon Linux).
Указываем этот AMI, выбираем нашу VPC, и в ней – две приватные подсети:
Кликаем Next, на следующей странице можно ничего не менять, и запускаем создание стека:
После создания стека – проверяем AutoScaling groups:
Установка kubectl
Тем временем – сам EKS-кластер поднялся, можно установить kubectl
.
На рабочую машину загружаем исполняемый файл:
[simterm]
[setevoy@setevoy-arch-work ~] $ curl -o kubectl https://amazon-eks.s3-us-west-2.amazonaws.com/1.13.7/2019-06-11/bin/linux/amd64/kubectl [setevoy@setevoy-arch-work ~] $ chmod +x kubectl [setevoy@setevoy-arch-work ~] $ sudo mv kubectl /usr/local/bin/
[/simterm]
Проверяем:
[simterm]
[setevoy@setevoy-arch-work ~] $ kubectl version --short --client Client Version: v1.13.7-eks-fa4c70
[/simterm]
Для создания файла его настроек – используем AWS CLI:
[simterm]
[setevoy@setevoy-arch-work ~] $ aws eks --region eu-west-2 --profile arseniy update-kubeconfig --name eks-cluster-manual Added new context arn:aws:eks:eu-west-2:534***385:cluster/eks-cluster-manual to /home/setevoy/.kube/config
[/simterm]
Добавляем алиас для удобства:
[simterm]
[setevoy@setevoy-arch-work ~] $ echo "alias kk=\"kubectl\"" >> ~/.bashrc [setevoy@setevoy-arch-work ~] $ bash
[/simterm]
Проверяем:
[simterm]
[setevoy@setevoy-arch-work ~] $ kk get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 20m
[/simterm]
AWS authenticator
Хотя CloudFormation стек создан, и ЕС2 подняты – но Worker Nodes ещё не добавлены в сам Kubernetes -кластер:
[simterm]
[setevoy@setevoy-arch-work ~] $ kk get node No resources found.
Загружаем AWS authenticator:
[simterm]
[setevoy@setevoy-arch-work ~] $ cd Temp/ [setevoy@setevoy-arch-work ~] $ curl -so aws-auth-cm.yaml https://amazon-eks.s3-us-west-2.amazonaws.com/cloudformation/2019-02-11/aws-auth-cm.yaml
[/simterm]
Переходим в IAM > Roles, находим ARN (Amazon Resource Name) роли (NodeInstanceRole) (или находим в Outputs CloudFormation стека для worker nodes):
Редактируем aws-auth-cm.yaml
, задаём rolearn
:
Создаём ConfigMap
:
[simterm]
[setevoy@setevoy-arch-work ~/Temp] $ kk apply -f aws-auth-cm.yaml configmap/aws-auth created
[/simterm]
Проверяем:
[simterm]
[setevoy@setevoy-arch-work ~/Temp] $ kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME ip-10-0-153-7.eu-west-2.compute.internal Ready <none> 47s v1.13.7-eks-c57ff8 10.0.153.7 <none> Amazon Linux 2 4.14.128-112.105.amzn2.x86_64 docker://18.6.1 ip-10-0-196-123.eu-west-2.compute.internal Ready <none> 50s v1.13.7-eks-c57ff8 10.0.196.123 <none> Amazon Linux 2 4.14.128-112.105.amzn2.x86_64 docker://18.6.1 ip-10-0-204-190.eu-west-2.compute.internal Ready <none> 52s v1.13.7-eks-c57ff8 10.0.204.190 <none> Amazon Linux 2 4.14.128-112.105.amzn2.x86_64 docker://18.6.1
[/simterm]
Ноды появились, всё отлично.
Web-app && LoadBalancer
И для проверки – создадим простой веб-сервис, пусть будет просто NGINX, как в предыдущем примере.
Для доступа к NGINX – добавим AWS и Kubernetes LoadBalancer, который будет проксировать запросы к рабочим нодам:
kind: Service apiVersion: v1 metadata: name: eks-cluster-manual-elb spec: type: LoadBalancer selector: app: eks-cluster-manual-pod ports: - name: http protocol: TCP # ELB's port port: 80 # container's port targetPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: eks-cluster-manual-deploy spec: # ReplicaSet pods config replicas: 1 # pods selector selector: matchLabels: app: eks-cluster-manual-pod # Pod template template: metadata: # a pod's labeles labels: app: eks-cluster-manual-pod spec: containers: - name: eks-cluster-manual-app image: nginx
Применяем их:
[simterm]
[setevoy@setevoy-arch-work ~/Temp] $ kk apply -f eks-cluster-manual-elb-nginx.yml service/eks-cluster-manual-elb created deployment.apps/eks-cluster-manual-deploy created
[/simterm]
Проверяем сервисы:
[simterm]
[setevoy@setevoy-arch-work ~/Temp] $ kk get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE eks-cluster-manual-elb LoadBalancer 172.20.17.42 a05***405.eu-west-2.elb.amazonaws.com 80:32680/TCP 5m23s
[/simterm]
Под:
[simterm]
$ kk get po -o wide -l app=eks-cluster-manual-pod NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES eks-cluster-manual-deploy-698b8f6df7-jg55x 1/1 Running 0 6m17s 10.0.130.54 ip-10-0-153-7.eu-west-2.compute.internal <none> <none>
[/simterm]
И ConfigMap
:
[simterm]
$ kubectl describe configmap -n kube-system aws-auth Name: aws-auth Namespace: kube-system Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"v1","data":{"mapRoles":"- rolearn: arn:aws:iam::534***385:role/eks-cluster-manual-workers-stack-NodeInstanceRole-12DRN98... Data ==== mapRoles: ---- - rolearn: arn:aws:iam::534***385:role/eks-cluster-manual-workers-stack-NodeInstanceRole-12DRN987QYB34 username: system:node:{{EC2PrivateDNSName}} groups: - system:bootstrappers - system:nodes Events: <none>
[/simterm]
LoadBalancer в самом AWS (потребуется минут 5, что бы завелись поды и инстансы подключились к ELB):
Его теги:
Проверяем URL:
[simterm]
[setevoy@setevoy-arch-work ~/Temp] $ curl a05***405.eu-west-2.elb.amazonaws.com <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...
[/simterm]
Готово.
Ссылки по теме
- What Is Amazon EKS?
- Getting Started with Amazon EKS
- Managing Users or IAM Roles for your Cluster
- Kubernetes ConfigMap
- Amazon EKS Workshop
- Ten things to know about Kubernetes on Amazon (EKS)
- EKS Review
- My First Kubernetes Cluster: A Review of Amazon EKS
- Troubleshoot Kubernetes Deployments
- matchLabels, labels, and selectors explained in detail, for beginners