AWS Elastic Kubernetes Service: автоматизация создания кластера, часть 2 — Anisible, eksctl
Первая часть — AWS Elastic Kubernetes Service: автоматизация создания кластера, часть 1 — облачность Отказ
Напомнить всю идею состоит в том, чтобы создать процесс автоматизации для создания кластера EKS:
- Anisible использует Модуль CloudFormation создать инфраструктуру
- Используя выходы создания стека CloudFormation — Anisible из шаблона будет генерировать файл Cluster-Config для eksctl
- Аналимые вызовы eksctl с этим конфигурацией для создания кластера EKS
Все это будет сделано с работы Jenkins с использованием документа докера с AWS CLI, Anbible и eksctl. Может быть, это будет третья часть этой серии.
Все приведенные файлы после написания этого поста доступны в eksctl-cf-ansible Репозиторий GitHub. Ссылка здесь состоит в отделении с точной копией кода ниже.
Содержание
- Аутентификация AWS.
- Обязательная облачность
- Параметры облака и аналимыми переменными
- Роль облака
- Обязательный Эккт
- Cluster Config — eks-cluster-config.yml
- Eksctl Создать VS обновление
- Тест: CloudFormation && EKS Пользовательские параметры
- Слияние AWS-AUTH CONFIGMAP
- Полезные ссылки
- Кубернеты
- Неизбежный
- Aws
- Екс
- Облачность
Аутентификация AWS.
Стоит задуматься о аутентификации заранее, чтобы не переделать все с нуля (я сделал).
Кроме того, настоятельно рекомендуется читать Kubernetes: Часть 4 — Аутентификация AWS EKS, AWS-IAM-Authenticator, а AWS IAM Пост, так как в этом текущем посте будет использоваться много вещей, описанных там.
Итак, нам нужно иметь некоторый механизм аутентификации AWS, потому что нам нужно аутентифицировать:
- Обязательный для его облачность роль
- Обязательный для его Экктл роль
- Anbible для выполнения команд AWS CLI
Наиболее неочевидной проблемой вот тот факт, что пользователь IAM используется для создания кластера EKS, становится его «Super-admin», и вы не можете его изменить.
Например, в предыдущей части мы создали кластер с помощью следующей команды:
$ eksctl --profile arseniy create cluster -f eks-cluster-config.yml
Теперь вы можете проверить журналы Authenticator в CloudWatch, самые первые записи там — и вы увидите корневицу из системы: Masters Group с разрешениями Kubernetes-Admin:
Ну — что мы можем использовать для аутентификации AWS ??
- Ключи доступа — AWS_ACCESS_KEY_ID и AWS_SECRET_ACCESS_KEY
- AWS CLI по имени профили
- AWS IAM EC2 Профили экземпляра (См. Также AWS: IAM Присётчик — Описание, Примеры , Рус Несомненно
Но, как мы будем использовать Jenkins здесь — мы можем использовать свою роль экземпляра IAM EC2 с необходимыми разрешениями.
На данный момент я понял следующую схему:
- Вручную создать IAM пользователь под названием Eks-root С политикой администратора EKS
- Jenkins создаст необходимые ресурсы, используя свою роль экземпляра IAM с помощью политики администратора EKS и станут «Super-admin» для всех кластеров EKS в учетной записи AWS
- И в Anisible мы добавим eksctl create iamidentitymapping (см. Управление IAM пользователей и ролей ) добавить дополнительные пользователи.
Проверьте aws-auth. Configmap сейчас:
$ eksctl --profile arseniy --region eu-west-2 get iamidentitymapping --cluster eks-dev ARN USERNAME GROUPS arn:aws:iam::534***385:role/eksctl-eks-dev-nodegroup-worker-n-NodeInstanceRole-UNGXZXVBL3ZP system:node:{{EC2PrivateDNSName}} system:bootstrappers,system:nodes
Или с этим:
$ kubectl -n kube-system get cm aws-auth -o yaml apiVersion: v1 data: mapRoles: | - groups: - system:bootstrappers - system:nodes rolearn: arn:aws:iam::534***385:role/eksctl-eks-dev-nodegroup-worker-n-NodeInstanceRole-UNGXZXVBL3ZP username: system:node:{{EC2PrivateDNSName}} mapUsers: | [] kind: ConfigMap …
Давайте сделаем все вручную сейчас, чтобы избежать удивления во время создания автоматизации:
- Создайте пользователь IAM
- Создайте политику «EKS Admin»
- Прикрепите эту политику этого пользователя
- Настройте локальный профиль AWS CLI с этим пользователем
- Настроить локальный Kubectl для этого профиля AWS CLI
- Выполнить eksctl Создать iAmidentitymapping
- Выполнить kubectl Получить узлы для проверки доступа
Продолжай — создайте пользователя:
$ aws --profile arseniy --region eu-west-2 iam create-user --user-name eks-root { "User": { "Path": "/", "UserName": "eks-root", "UserId": "AID***PSA", "Arn": "arn:aws:iam::534***385:user/eks-root", "CreateDate": "2020–03–30T12:24:28Z" } }
Его ключи доступа:
$ aws --profile arseniy --region eu-west-2 iam create-access-key --user-name eks-root { "AccessKey": { "UserName": "eks-root", "AccessKeyId": "AKI****45Y", "Status": "Active", "SecretAccessKey": "Qrr***xIT", "CreateDate": "2020–03–30T12:27:28Z" } }
Настроить локальный профиль AWS CLI:
$ aws configure --profile eks-root AWS Access Key ID [None]: AKI***45Y AWS Secret Access Key [None]: Qrr***xIT Default region name [None]: eu-west-2 Default output format [None]: json
Попробуйте доступ сейчас — должно быть отклонено:
$ aws --profile eks-roo eks list-clusters An error occurred (AccessDeniedException) when calling the ListClusters operation […]
Создать политику, вот некоторые Примеры >>> (Позже его можно добавить в стопку облака в виде вложенного стека, таким же образом, безопасные группы будут управляться), сохраните его в выделенном файле ../../CloudFormation/files/eks-root-policy.json:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "eks:*" ], "Resource": "*" } ] }
Добавьте эту политику в AWS IAM:
$ aws --profile arseniy --region eu-west-2 iam create-policy --policy-name eks-root-policy --policy-document file://../../cloudformation/files/eks-root-policy.json { "Policy": { "PolicyName": "eks-root-policy", "PolicyId": "ANPAXY5JMBMEROIOD22GM", "Arn": "arn:aws:iam::534***385:policy/eks-root-policy", "Path": "/", "DefaultVersionId": "v1", "AttachmentCount": 0, "PermissionsBoundaryUsageCount": 0, "IsAttachable": true, "CreateDate": "2020–03–30T12:44:58Z", "UpdateDate": "2020–03–30T12:44:58Z" } }
Прикрепите политику пользователю, созданному выше:
$ aws --profile arseniy --region eu-west-2 iam attach-user-policy --user-name eks-root --policy-arn arn:aws:iam::534***385:policy/eks-root-policy
Проверять:
$ aws --profile arseniy --region eu-west-2 iam list-attached-user-policies --user-name eks-root --output text ATTACHEDPOLICIES arn:aws:iam::534***385:policy/eks-root-policy eks-root-policy
Попробуйте получить доступ снова:
$ aws --profile eks-root --region eu-west-2 eks list-clusters --output text CLUSTERS eks-dev
И в другом регионе:
$ aws --profile eks-root --region us-east-2 eks list-clusters --output text CLUSTERS eksctl-bttrm-eks-production-1 CLUSTERS mobilebackend-dev-eks-0-cluster
Следующие задачи будут лучше сделать из коробки без сконфигурированного доступа вообще, например — с сервера блога RTFM:-)
Установите AWS CLI:
root@rtfm-do-production:/home/setevoy# pip install awscli
Настройте профиль по умолчанию:
root@rtfm-do-production:/home/setevoy# aws configure
Проверьте доступ к AWS EKS в целом — в нашей политике IAM мы предоставили разрешения на EKS: ListClusters API-call, поэтому он должен работать:
root@rtfm-do-production:/home/setevoy# aws eks list-clusters — output text CLUSTERS eks-dev
Хорошо.
Установите eksctl:
root@rtfm-do-production:/home/setevoy# curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp root@rtfm-do-production:/home/setevoy# mv /tmp/eksctl /usr/local/bin
Повторите EKS: ListClusters — также должен работать, так как Eksctl будет использовать по умолчанию Профиль AWS CLI настроен выше:
root@rtfm-do-production:/home/setevoy# eksctl get cluster NAME REGION eks-dev eu-west-2
Установите Kubectl:
root@rtfm-do-production:/home/setevoy# curl -LO [https://storage.googleapis.com/kubernetes-release/release/`curl](https://storage.googleapis.com/kubernetes-release/release/%60curl) -s [https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl](https://storage.googleapis.com/kubernetes-release/release/stable.txt%60/bin/linux/amd64/kubectl) root@rtfm-do-production:/home/setevoy# chmod +x ./kubectl root@rtfm-do-production:/home/setevoy# mv ./kubectl /usr/local/bin/kubectl
Установите AWS-IAM-Authenticator, чтобы позволить Kubectl выполнять аутентификацию в AWS:
root@rtfm-do-production:/home/setevoy# curl -o aws-iam-authenticator [https://amazon-eks.s3.us-west-2.amazonaws.com/1.15.10/2020-02-22/bin/linux/amd64/aws-iam-authenticator](https://amazon-eks.s3.us-west-2.amazonaws.com/1.15.10/2020-02-22/bin/linux/amd64/aws-iam-authenticator) root@rtfm-do-production:/home/setevoy# chmod +x ./aws-iam-authenticator root@rtfm-do-production:/home/setevoy# mv aws-iam-authenticator /usr/local/bin/
Настроить kubectl:
root@rtfm-do-production:/home/setevoy# aws eks update-kubeconfig --name eks-dev Updated context arn:aws:eks:eu-west-2:534***385:cluster/eks-dev in /root/.kube/config
Попробуйте выполнить команду в кластере — должна быть ошибка авторизации:
root@rtfm-do-production:/home/setevoy# kubectl get nodes error: You must be logged in to the server (Unauthorized) root@rtfm-do-production:/home/setevoy# kubectl get pod error: You must be logged in to the server (Unauthorized)
Вернитесь на рабочий компьютер и добавьте Eks-root Пользователь к AWS-AUTH Configmap:
$ eksctl --profile arseniy --region eu-west-2 create iamidentitymapping --cluster eks-dev --arn arn:aws:iam::534***385:user/eks-root --group system:masters --username eks-root [ℹ] eksctl version 0.16.0 [ℹ] using region eu-west-2 [ℹ] adding identity "arn:aws:iam::534***385:user/eks-root" to auth ConfigMap
Проверь это:
$ eksctl --profile arseniy --region eu-west-2 get iamidentitymapping --cluster eks-dev ARN USERNAME GROUPS arn:aws:iam::534***385:role/eksctl-eks-dev-nodegroup-worker-n-NodeInstanceRole-UNGXZXVBL3ZP system:node:{{EC2PrivateDNSName}} system:bootstrappers,system:nodes arn:aws:iam::534***385:user/eks-root eks-root system:masters
Вернитесь к хосту тестирования и попробуйте снова получить доступ:
root@rtfm-do-production:/home/setevoy# kubectl get node NAME STATUS ROLES AGE VERSION ip-10–0–40–30.eu-west-2.compute.internal Ready133m v1.15.10-eks-bac369 ip-10–0–63–187.eu-west-2.compute.internal Ready 133m v1.15.10-eks-bac369
И давайте проверим что-то еще, то же самое aws-auth. Например configmap:
root@rtfm-do-production:/home/setevoy# kubectl -n kube-system get cm aws-auth -o yaml apiVersion: v1 data: mapRoles: | - groups: - system:bootstrappers - system:nodes rolearn: arn:aws:iam::534***385:role/eksctl-eks-dev-nodegroup-worker-n-NodeInstanceRole-UNGXZXVBL3ZP username: system:node:{{EC2PrivateDNSName}} mapUsers: | - groups:- system:masters userarn: arn:aws:iam::534***385:user/eks-root username: eks-root kind: ConfigMap …
Mapusers с нашим пользователем добавили — все хорошо здесь.
Позже мы можем использовать это AWS-AUTH Чтобы добавить новых пользователей или добавить задачу доступным для выполнения eksctl Создать iAmidentitymapping, или мы можем создать нашу собственную конфигурацию и загрузить его на экс.
Я приступим к задачам от наших хостов Дженкинса, как у нас есть погибший доступно в любом месте.
Обязательная облачность
Параметры облака и аналимыми переменными
Перед началом следующих задач — давайте подумаем о параметрах, используемых в стеке облака, от предыдущей части, и то, что нам нужно будет иметь в нашем предложении.
Первое, что имеется в виду, это акт, что у нас будет Dev , Этап , Производство Cluster + Dynamic для команды QA (чтобы позволить им возможность создавать выделенный пользовательский кластер из задания Jenkins для проверки чего-либо), поэтому параметры должны быть достаточно гибкими, чтобы создать стек в любом регионе с любыми сетями VPC.
Таким образом, у нас будет:
- Общие параметры для всех:
- область, край
- AWS Access/Secret (или IAM EC2 Профиль экземпляра )
- Выделенные параметры для окружающей среды:
- Env (Dev, Stage, Prod)
- VPC CIDR (10.0.0.0/16, 10.1.0.0.0/16 и т. Д.)
- SSH Ключ для Kubernetes Working Ussies Access
- AWS ES2 Типы экземпляров для рабочих узлов Kubernetes (T3.NANO, C5.9xLarge и т. Д.)
В частности, стоит обратить внимание на именования стеков и кластеров.
Итак, мы будем иметь для имена, которые используются «глобально» над непредвиденным PlayBook и ролями, и которые мы увидим позже в консоли AWS:
- Имя окружающей среды — dev , Этап , продлицо
- Имя стека облака, созданное нами из облачность Роль (корневой стек и его вложенные стеки)
- Имя стека облака, созданное eksctl при создании кластера и его работников узлов
- и Название кластера EKS
Эккт, конечно, сделает некоторые вещи за сценой и добавит некоторые префиксы-постфиксы на имена здесь.
Например, при создании стека для самого кластера EKS — он добавит свое имя стека облака с помощью eksctl- префикс и добавлю a -Кустер Postfix, а для его Wokernodes Stacks — будет использовать префикс Экктл- и постфикс -нодегруппа + Имя группы рабочих пользователей из кластера Config-файл.
Но все же сам кластер будет назван именно так, как мы устанавливаем его в EKS-Cluster-Config.yml.
Итак, давайте вообще схватим — какие переменные мы будем использовать:
- env:
- Формат: строка » dev «
- Описание: Используется для составных значений для других переменных
- Результат: дев
- eks_cluster_name:
- Формат: BTTRM-EKS — $ {ENV}
- Описание: Установите метаданные: name: в Eks-Cluster-Config.yml Cluster-Config будет использоваться для состоить значения для других переменных и Облачные метки
- Результат: bttrm-eks-dev
- cf_stack_name:
- Формат: eksctl — $ {eks_cluster_name} -stack
- Описание: С — куча Здесь мы отмечаем, что это содержит только доступные ресурсы AWS, Нет экс
- результат: eksctl-bttrm-eks-dev-stack
- (Авто) eks_cluster_stack_name:
- Формат: eksctl — $ {cluster_name} -Cluster
- Описание: будет создан сам EksCtl для стека облака, просто помня
- результат: eksctl-bttrm-eks-dev-cluster
- (Авто) eks_nodegroup_stack_name:
- Формат: eksctl — $ {cluster_name} -nodegroup — $ {рабочие-узлов-имя}, где Рабочий-узлов-имя — это значение из узлов: — Имя: из кластерной конфигурации EKS-Cluster-Config.yml
- Описание: будет создан сам EksCtl для стека облака, просто помня
- результат: eksctl-bttrm-eks-dev-cluster
Что касается разных файлов для различных сред — на данный момент, можно использовать Common Group_vars/all.yml, а позже увидим, как сделать их разделенными.
Создать каталог:
$ mkdir group_vars
Создайте файл All.yml и установите начальные значения:
################### # ANSIBLE globals # ################### ansible_connection: local ##################### # ENV-specific vars # ##################### env: "dev" ################# # ROLES globals # ################# region: "eu-west-2" # (THIS) eks_cluster_name: used for EKS service to set an exactly cluster's name - "{{ eks_cluster_name }}" # (AUTO) eks_cluster_stack_name: used for CloudFormation service to format a stack's name as "eksctl-{{ eks_cluster_name }}-cluster" # (AUTO) eks_nodegroup_stack_name: used for CloudFormation service to format a stack's name as "eksctl-{{ eks_cluster_name }}-nodegroup-{{ worker-nodes-name }}" eks_cluster_name: "bttrm-eks-{{ env }}" # used bythe cloudformation role to st a stack's name cf_stack_name: "eksctl-{{ eks_cluster_name }}-stack" ################## # ROLES specific # ################## # cloudforation role vpc_cidr_block: "10.0.0.0/16"
Также поставьте общие переменные здесь, как регион — он будет использоваться облачность и Экктл Роли, а VPC_CIDR_BLOCK — только в облачность Отказ
Роль облака
После того, как мы закончили наши шаблоны в Предыдущая часть У нас должны быть следующие каталоги и файлы сооружения:
$ tree . └── roles ├── cloudformation │ ├── files │ │ ├── eks-azs-networking.json │ │ ├── eks-region-networking.json │ │ └── eks-root.json │ ├── tasks │ └── templates └── eksctl ├── tasks └── templates └── eks-cluster-config.yml
Теперь, в корне репозитория Создайте новый файл EKS-Cluster.yml — это будет наш наш Anisible Playbook.
Добавьте облачность Исполнение там:
- hosts: - all become: true roles: - role: cloudformation tags: infra
Добавить теги, которые могут быть в состоянии позже запустить роли самостоятельно — будут полезны, когда мы начнем писать роль для Eksctl.
Создать роли/облачность/задачи/задачи/main.yml файл — добавьте облачность Выполнение модуля Здесь и установите необходимые параметры для наших шаблонов через Template_Parameters — VPCCIDRBLOCK из переменной VPC_CIDR_BLOCK и параметр eksclustername из переменной eks_cluster_name:
- name: "Create EKS {{ cf_stack_name | upper }} CloudFormation stack" cloudformation: region: "{{ region }}" stack_name: "{{ cf_stack_name }}" state: "present" disable_rollback: true template: "/tmp/packed-eks-stacks.json" template_parameters: VPCCIDRBlock: "{{ vpc_cidr_block }}" EKSClusterName: {{ eks_cluster_name }}, tags: Stack: "{{ cf_stack_name }}" Env: "{{ env }}" EKS-cluster: "{{ eks_cluster_name }}"
Не использовал неспособных в течение половины года — забыл все (
Google для » Аналимый инвентарь » — и прочитал Лучшие практики
В корне репозитория создайте файл Ansible.cfg с некоторыми значениями по умолчанию:
[defaults] gather_facts = no inventory = hosts.yml
В том же месте создайте файл инвентаризации — Hosts.yml:
all: hosts: "localhost"
W ERA E Использование localhost Здесь как Anbible не будет использовать ssh где угодно — все задачи будут сделаны локально.
Проверьте синтаксис:
admin@jenkins-production:~/devops-kubernetes$ ansible-playbook eks-cluster.yml — syntax-check playbook: eks-cluster.yml
Выглядит неплохо? Создайте файл шаблона (в трубопроводе Jenkins должен иметь дополнительный этап для этого:
admin@jenkins-production:~/devops-kubernetes$ cd roles/cloudformation/files/ admin@jenkins-production:~/devops-kubernetes/roles/cloudformation/files$ aws --region eu-west-2 cloudformation package --template-file eks-root.json --output-template /tmp/packed-eks-stacks.json --s3-bucket eks-cloudformation-eu-west-2 --use-json Successfully packaged artifacts and wrote output template to file /tmp/packed-eks-stacks.json.
Выполните следующую команду для развертывания упакованного шаблона
$ aws cloudformation deploy --template-file /tmp/packed-eks-stacks.json --stack-name
Запустите создание стека:
admin@jenkins-production:~/devops-kubernetes$ ansible-playbook eks-cluster.yml … TASK [cloudformation : Setting the Stack name] **** ok: [localhost] TASK [cloudformation : Create EKS EKSCTL-BTTRM-EKS-DEV-STACK CloudFormation stack] **** changed: [localhost] PLAY RECAP **** localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
Проверять:
Имя стека было установлено как eksctl-bttrm-eks-dev-стек — красивый.
Теперь можно начать писать роль для eksctl для создания самого кластера.
Обязательный Эккт
У нас уже есть файл конфигурации кластера — давайте переименуем его в .j2 (Чтобы заметить его как файл Jinja — неблагомусный шаблон двигатель):
admin@jenkins-production:~/devops-kubernetes$ mv roles/eksctl/templates/eks-cluster-config.yml roles/eksctl/templates/eks-cluster-config.yml.j2
Из стека облака, созданного в первой роли, нам нужно пройти кучу значений здесь — VPC ID, идентификаторы подсети и т. Д., Чтобы установить значения в Cluster Config для eksctl.
Давайте будем использовать неизбежный модуль cloudformation_info Чтобы собрать информацию о созданном стеке.
Добавьте его, сохраните свой вывод в переменную Stack_info, а затем проверите его содержимое.
Создайте новые файловые роли/eksctl/tasks/main.yml:
- cloudformation_info: region: "{{ region }}" stack_name: "cf_stack_name" register: stack_info - debug: msg: "{{ stack_info }}"
Добавьте исполнение ролей EksCTL в Playbook Eks-Cluster.yml, добавьте теги:
- hosts: - all become: true roles: - role: cloudformation tags: infra - role: eksctl tags: eks
Запустите использование EKSTAGS EKS, чтобы выполнить только роль EksCTL:
admin@jenkins-production:~/devops-kubernetes$ ansible-playbook — tags eks eks-cluster.yml … TASK [eksctl : cloudformation_info] **** ok: [localhost] TASK [eksctl : debug] **** ok: [localhost] => { "msg": { "changed": false, "cloudformation": { "eksctl-bttrm-eks-dev-stack": { "stack_description": { … "outputs": [ { "description": "EKS VPC ID", "output_key": "VPCID", "output_value": "vpc-042082cd2d011f44d" }, …
Прохладно.
Теперь — давайте сократим только блок {«выводы»}.
Обновите задачу — от Stack_info в MSG Pass только Stack_Outputs:
- cloudformation_info: region: "{{ region }}" stack_name: "{{ cf_stack_name }}" register: stack_info - debug: msg: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs }}"
Бежать:
admin@jenkins-production:~/devops-kubernetes$ ansible-playbook — tags eks eks-cluster.yml … TASK [eksctl : debug] **** ok: [localhost] => { "msg": { "APrivateSubnetID": "subnet-0471e7c28a3770828", "APublicSubnetID": "subnet-07a0259b33ddbcb4c", "AStackAZ": "eu-west-2a", "BPrivateSubnetID": "subnet-0fa6eece43b2b6644", "BPublicSubnetID": "subnet-072c107cef77fe859", "BStackAZ": "eu-west-2b", "VPCID": "vpc-042082cd2d011f44d" } } …
НИИЦА!
И теперь — давайте попробуем установить эти значения в качестве переменных, чтобы использовать их для генерации конфигурации кластера с его шаблона.
Обновите роли/eksctl/tasks/main.yml, добавьте переменную VPC_ID и распечатайте ее через Debug, чтобы проверить его значение:
- cloudformation_info: region: "{{ region }}" stack_name: "{{ cf_stack_name }}" register: stack_info - debug: msg: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs }}" - set_fact: vpc_id: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.VPCID }}" - debug: msg: "{{ vpc_id }}" - name: "Check template's content" debug: msg: "{{ lookup('template', './eks-cluster-config.yml.j2') }}"
В « Проверьте содержимое шаблона »Путем прямого вызова Шаблон Модуль Давайте проверим, что мы будем иметь в качестве приведенного файла из файла шаблона.
Редактировать роли/eksctl/шаблоны/eks-cluster-config.yml.j2 — установите {{vpc_id}}
:
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: eks-dev region: eu-west-2 version: "1.15" nodeGroups: - name: worker-nodes instanceType: t3.medium desiredCapacity: 2 privateNetworking: true vpc: id: "{{ vpc_id }}" subnets: public: eu-west-2a: ...
Проверять:
admin@jenkins-production:~/devops-kubernetes$ ansible-playbook — tags eks eks-cluster.yml … TASK [eksctl : debug] **** ok: [localhost] => { "msg": { "APrivateSubnetID": "subnet-0471e7c28a3770828", "APublicSubnetID": "subnet-07a0259b33ddbcb4c", "AStackAZ": "eu-west-2a", "BPrivateSubnetID": "subnet-0fa6eece43b2b6644", "BPublicSubnetID": "subnet-072c107cef77fe859", "BStackAZ": "eu-west-2b", "VPCID": "vpc-042082cd2d011f44d" } } TASK [eksctl : set_fact] *****ok: [localhost] TASK [eksctl : debug] **** ok: [localhost] => { "msg": "vpc-042082cd2d011f44d" } TASK [eksctl : Check the template's content] **** ok: [localhost] => { "msg": "apiVersion: eksctl.io/v1alpha5\nkind: ClusterConfig\nmetadata:\n name: eks-dev\n region: eu-west-2\n version: \"1.15\"\nnodeGroups:\n — name: worker-nodes\n instanceType: t3.medium\n desiredCapacity: 2\n privateNetworking: true\nvpc:\n id: \"vpc-042082cd2d011f44d\"\n […]
VPC: \ N ID: \ «VPC-VPC-042082CD2D011F44D \» — Хорошо, мы получили наш VPC ID в шаблоне.
Добавьте другие вариалы, поэтому шаблон будет выглядеть так:
apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: "{{ eks_cluster_name }}" region: "{{ region }}" version: "{{ k8s_version }}" nodeGroups: - name: "{{ k8s_worker_nodes_group_name }}" instanceType: "{{ k8s_worker_nodes_instance_type }}" desiredCapacity: {{ k8s_worker_nodes_capacity }} privateNetworking: true vpc: id: "{{ vpc_id }}" subnets: public: {{ a_stack_az }}: id: "{{ a_stack_pub_subnet }}" {{ b_stack_az }}: id: "{{ b_stack_pub_subnet }}" private: {{ a_stack_az }}: id: "{{ a_stack_priv_subnet }}" {{ b_stack_az }}: id: "{{ b_stack_priv_subnet }}" nat: gateway: Disable cloudWatch: clusterLogging: enableTypes: ["*"]
Далее необходимо добавить дополнительные переменные для Anbible для использования в этом шаблоне:
- eks_cluster_name — уже добавлено
- VPC_ID — уже добавлено
- Для стека доступныхzone-а нужно добавить:
- a_stack_pub_subnet.
- a_stack_priv_subnet.
- Для доступныхzone-™ надо добавить:
- a_stack_pub_subnet.
- a_stack_priv_subnet.
- регион — уже добавляется, будет установлен позже от параметров Jenkins
- kubernetes_version.
- kubernetes_worker_nodes_group_name.
- kubernetes_worker_nodes_instance_type.
- kubernetes_worker_nodes_capity.
Добавить Set_Facts в ролях/eksctl/tasks/main.yml:
- cloudformation_info: region: "{{ region }}" stack_name: "{{ cf_stack_name }}" register: stack_info - debug: msg: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs }}" - set_fact: vpc_id: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.VPCID }}" a_stack_az: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.AStackAZ }}" a_stack_pub_subnet: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.APublicSubnetID }}" a_stack_priv_subnet: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.APrivateSubnetID }}" b_stack_az: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.BStackAZ }}" b_stack_pub_subnet: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.BPublicSubnetID }}" b_stack_priv_subnet: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.BPrivateSubnetID }}" - name: "Check the template's content" debug: msg: "{{ lookup('template', './eks-cluster-config.yml.j2') }}"
В Group_vars/All.yml добавляют значения для Экктл роль:
... ################## # ROLES specific # ################## # cloudforation role vpc_cidr_block: "10.0.0.0/16" # eksctl role k8s_version: 1.15 k8s_worker_nodes_group_name: "worker-nodes" k8s_worker_nodes_instance_type: "t3.medium" k8s_worker_nodes_capacity: 2
Давайте проверим — на данный момент, позвонив каталог шаблона:
… TASK [eksctl : Check the template's content] **** ok: [localhost] => { "msg": "apiVersion: eksctl.io/v1alpha5\nkind: ClusterConfig\nmetadata:\n name: \"bttrm-eks-dev\"\n region: \"eu-west-2\"\n version: \"1.15\"\nnodeGroups:\n — name: \"worker-nodes\"\n instanceType: \"t3.medium\"\n desiredCapacity: 2\n privateNetworking: true\nvpc:\n id: \"vpc-042082cd2d011f44d\"\n subnets:\n public:\n eu-west-2a:\n id: \"subnet-07a0259b33ddbcb4c\"\n eu-west-2b:\n id: \"subnet-072c107cef77fe859\"\n private:\n eu-west-2a:\n id: \"subnet-0471e7c28a3770828\"\n eu-west-2b:\n id: \"subnet-0fa6eece43b2b6644\"\n nat:\n gateway: Disable\ncloudWatch:\n clusterLogging:\n enableTypes: [\"\*\"]\n" } …
«Оно работает!» ©.
Ну — не пришло время запустить экккт.
Cluster Config — eks-cluster-config.yml
Перед вызовом eksctl необходимо создать конфигурацию из шаблона.
В конце ролей/eksctl/tasks/main.yml добавьте шаблон и используя роль/eksctl/chumplates/eks-cluster-config.yml.j2, генерируют файл eks-cluster-config.yml в/tmp каталог:
... - name: "Generate eks-cluster-config.yml" template: src: "eks-cluster-config.yml.j2" dest: /tmp/eks-cluster-config.yml
Eksctl Создать VS обновление
Примечание. На самом деле, обновление для eksctl выполнит обновление версии вместо обновления конфигурации, но я оставлю эту часть здесь только для примера
Кстати, что если кластер уже существует? Работа потерпит неудачу, так как мы передаем создание.
Ну — мы можем добавить проверку, если кластер уже присутствует, а затем создать переменную для хранения значения Создать или Обновление Точно так же я сделал это в Bash: Скрипт Создания AWS CloudFormation Стека Отказ
Таким образом, надо:
- Получить список кластеров EKS в регионе AWS
- Попробуйте найти имя кластера, создаваемого в этом списке
- Если не нашел тогда установить значение Создайте
- Если найдено, установите значение Обновить
Давайте попробуем сделать это таким образом:
# populate a clusters_exist list with names of clusters devided by TAB "\t" - name: "Getting existing clusters list" shell: "aws --region {{ region }} eks list-clusters --query '[clusters'] --output text" register: clusters_exist - debug: msg: "{{ clusters_exist.stdout }}" # create a list from the clusters_exist - set_fact: found_clusters_list: "{{ clusters\_exist.stdout.split('\t') }}" - debug: msg: "{{ found_clusters_list }}" # check if a cluster's name is found in the existing clusters list - fail: msg: "{{ eks_cluster_name }} already exist in the {{ region }}" when: eks_cluster_name not in found_clusters_list - meta: end_play ...
Эти задачи во время тестирования добавляют в начало ролей/eksctl/tasks/main.yml, а для остановки выполнения после них — добавьте — Meta: end_play.
В состоянии сбоя сейчас установлено « не в », как мы просто тестируем сейчас и не имеем созданного кластера:
… TASK [eksctl : debug] **** ok: [localhost] => { "msg": "eks-dev" } TASK [eksctl : set_fact] **** ok: [localhost] TASK [eksctl : debug] **** ok: [localhost] => { "msg": [ "eks-dev" ] } TASK [eksctl : fail] **** fatal: [localhost]: FAILED! => {"changed": false, "msg": "bttrm-eks-dev already exist in the eu-west-2"} …
Прохладно.
Теперь добавьте переменную Eksctl_action с помощью « Create » или «Обновление », в зависимости от того, был найден кластер или нет:
# populate a clusters_exist list with names of clusters devided by TAB "\t" - name: "Getting existing clusters list" shell: "aws --region {{ region }} eks list-clusters --query '[clusters'] --output text" register: clusters_exist - debug: msg: "{{ clusters_exist.stdout }}" # create a list from the clusters_exist - set_fact: found_clusters_list: "{{ clusters_exist.stdout.split('\t') }}" - debug: msg: "{{ found_clusters_list }}" - set_fact: eksctl_action: "{{ 'create' if (eks_cluster_name not in found_clusters_list) else 'update' }}" - debug: var: eksctl_action # check if a cluster's name is found in the existing clusters list - fail: msg: "{{ eks_cluster_name }} already exist in the {{ region }}" when: eks_cluster_name not in found_clusters_list ...
Проверять:
… TASK [eksctl : debug] **** ok: [localhost] => { "eksctl_action": "create" } …
Далее добавьте это на eksctltask — добавьте {{eksctl_action}}
Для его аргументов вместо прямых » Создать «:
- cloudformation_info: region: "{{ region }}" stack_name: "{{ cf_stack_name }}" register: stack_info - set_fact: vpc_id: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.VPCID }}" a_stack_az: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.AStackAZ }}" a_stack_pub_subnet: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.APublicSubnetID }}" a_stack_priv_subnet: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.APrivateSubnetID }}" b_stack_az: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.BStackAZ }}" b_stack_pub_subnet: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.BPublicSubnetID }}" b_stack_priv_subnet: "{{ stack_info.cloudformation[cf_stack_name].stack_outputs.BPrivateSubnetID }}" - name: "Generate eks-cluster-config.yml" template: src: "eks-cluster-config.yml.j2" dest: /tmp/eks-cluster-config.yml # populate a clusters_exist list with names of clusters devided by TAB "\t" - name: "Getting existing clusters list" command: "aws --region {{ region }} eks list-clusters --query '[clusters'] --output text" register: clusters_exist # create a list from the clusters_exist - set_fact: found_clusters_list: "{{ clusters_exist.stdout.split('\t') }}" - name: "Setting eksctl action to either Create or Update" set_fact: eksctl_action: "{{ 'create' if (eks_cluster_name not in found_clusters_list) else 'update' }}" - name: "Running eksctl eksctl_action {{ eksctl_action | upper }} cluster with name {{ eks_cluster_name | upper }}" command: "eksctl {{ eksctl_action }} cluster -f /tmp/eks-cluster-config.yml"
Момент истины!:-)
Бежать:
admin@jenkins-production:~/devops-kubernetes$ ansible-playbook — tags eks eks-cluster.yml … TASK [eksctl : cloudformation_info] **** ok: [localhost] TASK [eksctl : set_fact] **** ok: [localhost] TASK [eksctl : Generate eks-cluster-config.yml] **** ok: [localhost] TASK [eksctl : Getting existing clusters list] **** changed: [localhost] TASK [eksctl : set_fact] **** ok: [localhost] TASK [eksctl : Setting eksctl action to either Create or Update] **** ok: [localhost] TASK [eksctl : Running eksctl eksctl_action CREATE cluster with name BTTRM-EKS-DEV]
Стек и кластер создают, зовут стека eksctl-bttrm-dev-кластер — Все, как мы планировали:
Ура!
Оставил только еще один тест.
Тест: CloudFormation && EKS Пользовательские параметры
Последняя вещь для тестирования — это гибкость всего, что мы написали.
Например, команда QA хочет создать совершенно новый кластер с именем Qa-test С VPC CIDR 10.1.0.0/16 .
Обновите group_vars/all.yml, набор:
- env: » dev «> «
- qa-test» Регион: « ЕС-Запад-2 «> « ЕС-Запад-3
- » vpc_cidr_block: « 10.0.0.0/16 «> « 10.1.0.0/16
... env: "qa-test" ... region: "eu-west-3" ... vpc_cidr_block: "10.1.0.0/16"
Завершите шаблон, чтобы повторно Geneteare упакованный EKS-Stack.json:
admin@jenkins-production:~/devops-kubernetes$ cd roles/cloudformation/files/ admin@jenkins-production:~/devops-kubernetes/roles/cloudformation/files$ aws — region eu-west-3 cloudformation package — template-file eks-root.json — output-template packed-eks-stacks.json — s3-bucket eks-cloudformation-eu-west-3 — use-json
Запустите Anbible без NOTTAGS, чтобы создать стопки облака и кластеров EKS с нуля:
admin@jenkins-production:~/devops-kubernetes$ ansible-playbook eks-cluster.yml … TASK [cloudformation : Create EKS EKSCTL-BTTRM-EKS-QA-TEST-STACK CloudFormation stack] **** changed: [localhost] TASK [eksctl : cloudformation_info] **** ok: [localhost] TASK [eksctl : set_fact] **** ok: [localhost] TASK [eksctl : Generate eks-cluster-config.yml] **** changed: [localhost] TASK [eksctl : Getting existing clusters list] **** changed: [localhost] TASK [eksctl : set_fact] **** ok: [localhost] TASK [eksctl : Setting eksctl action to either Create or Update] **** ok: [localhost] TASK [eksctl : Running eksctl eksctl_action CREATE cluster with name BTTRM-EKS-QA-TEST] **** …
Подождите, проверьте:
Ура!
На самом деле — вот все.
Конечная вещь будет создать Jenkins-Job.
О, подожди! Забыл о конфигурации.
Слияние AWS-AUTH CONFIGMAP
Неважно, как сильно вы пытаетесь — Ты что-то забудет.
Так — надо добавить Eks-root , пользователь, созданный в самом начале этого поста к кластеру, мы создаем.
Это можно сделать с помощью одной команды и две переменные.
Примечание: на самом деле, это принесет пользователю каждый раз, когда выполняется при условии, что в моем окончательном решении я сделал это немного другого пути, но на данный момент я оставляю его здесь «как есть» — добавит лучший способ потом.
В group_vars/all.yml добавить ARN пользователя:
... eks_root_user_name: "eks-root" eks_root_user_arn: "arn:aws:iam::534***385:user/eks-root"
А в ролях/eksctl/tasks/main.yml — добавь его в кластер:
... - name: "Update aws-auth ConfigMap with the EKS root user {{ eks_root_user_name | upper }}" command: "eksctl create iamidentitymapping --cluster {{ eks_cluster_name }} --arn {{ eks_root_user_arn }} --group system:masters --username {{ eks_root_user_name }}"
Бежать:
… TASK [eksctl : Running eksctl eksctl_action UPDATE cluster with name BTTRM-EKS-QA-TEST] **** changed: [localhost] TASK [eksctl : Update aws-auth ConfigMap with the EKS root user EKS-ROOT] **** changed: [localhost] …
Вернитесь на сервер RTFM, где у нас есть «чистый» доступ только к Eks-root Пользователь, обновите его ~/.kube/config:
root@rtfm-do-production:/home/setevoy# aws — region eu-west-3 eks update-kubeconfig — name bttrm-eks-qa-test Added new context arn:aws:eks:eu-west-3:53***385:cluster/bttrm-eks-qa-test to /root/.kube/config
Попробуйте получить доступ к узлам Info:
root@rtfm-do-production:/home/setevoy# kubectl get node NAME STATUS ROLES AGE VERSION ip-10–1–40–182.eu-west-3.compute.internal Ready94m v1.15.10-eks-bac369 ip-10–1–52–14.eu-west-3.compute.internal Ready 94m v1.15.10-eks-bac369
И стручки:
root@rtfm-do-production:/home/setevoy# kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE aws-node-rgpn5 1/1 Running 0 95m aws-node-xtr6m 1/1 Running 0 95m coredns-7ddddf5cc7–5w5wt 1/1 Running 0 102m …
Готово.
Полезные ссылки
Кубернеты
- Введение в Cobernetes Pod Networking
- Kubernetes на AWS: Учебное пособие и лучшие практики для развертывания
- Как управлять Kubernetes с Kubectl
- Строительство больших кластеров
- Кубернаны производства лучших практик
Неизбежный
Aws
Екс
- Kubernetes Cluster на AWS EKS
- EKS VS GKE VS AKS — Оценка Кубератесов в облаке
- Модульная и масштабируемая архитектура Amazon EKS
- Построить кластер Kubernetes с eksctl
- Групповые соображения безопасности Amazon EKS
Облачность
- Управление инфраструктурой AWS в качестве кода с использованием Anbible, CloudFormation и CodeBuild
- Стек вложенного облака: руководство для разработчиков и системных администраторов
- Прохождение с вложенной облаком Стеки
- Как пройти параметры TOMADELIMITEDLISTLIST, чтобы вложенные стеки в AWS CloudFormation?
- Как использовать несколько значений для отдельных параметров в шаблоне CloudFormation AWS?
- Два года с облачным отформацией: извлеченные уроки
- Усаживание раздутых шаблонов облаковных дел с помощью вложенного стека
- Отсрочка отсчета лучшие практики
- 7 удивительных хаки облака
- AWS Cloudformation лучшие практики — сертификация
- Определение свойств ресурсов условно с использованием AWS:: Novalue на облачность
Первоначально опубликовано в RTFM: Linux, DevOps и системное администрирование Отказ
Оригинал: «https://dev.to/setevoy/aws-elastic-kubernetes-service-a-cluster-creation-automation-part-2-ansible-eksctl-4afk»