Рубрики
Uncategorized

Запуск самого управляемого кластера Kubernetes на AWS

В этом посте я хочу пройти через шаги, которые нужно предпринять, чтобы запустить самоуправляемый кусочек Kubernetes … Помечено Kubernetes, AWS, DevOps.

В этом посте я хочу пройти через шаги, которые нужно предпринять, чтобы запустить самостоятельный кластер Kubernetes на AWS. Одна из причин, по которой можно было бы сделать это, заключается в том, что можно запустить новейшую версию Kubernetes, еще не доступной в качестве управляемого сервиса.

Мы собираемся использовать kubeadm Чтобы установить компоненты Kubernetes и использовать интеграции AWS для таких вещей, как балансировка нагрузки, диапазоны CI/DR и т. Д. Я собираюсь установить версию Kubernetes 1.19 на Ubuntu Server 18.04 LTS . Docker будет время выполнения контейнера.

Плоскость управления будет настроена вручную. Рабочие узлы будут частью автоматической группы. Автоскалирование будет управляться кластер-автомассал Анкет

Как плоскость управления, так и плоскость данных будут развернуты в частных подсетях. Нет никаких причин, чтобы ни один из этих случаев был в публичных подсетях.

Для удобства я собираюсь использовать то же самое Ami как для плоскости управления, так и для плоскости данных.

Вещи, с которыми мне приходилось бороться, правильно используют флаг --cloud-provider = aws и помечение экземпляров с kubernetes.io/cluster/kubernetes Анкет

Создание ами

Запустить экземпляр с базой Ubuntu 18.04 изображение. Назначьте пару ключей во время запуска, чтобы мы могли ssh в экземпляр.

Давайте установим кубидм , Кубелет и kubectl первый. Следуя указаниям в https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/ , с небольшими изменениями, нам нужно запустить этот сценарий

sudo apt-get update && sudo apt-get install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
cat <

Сваливание должно быть отключено в экземпляре.

Установить Docker

sudo apt-get update && sudo apt-get upgrade -y && sudo apt-get install -y apt-transport-https curl jq
sudo apt-get install docker.io -y
sudo systemctl enable docker.service
sudo systemctl start docker.service

Узел работника должен использовать AWS CLI , так что давайте установим —

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
sudo apt install unzip
unzip awscliv2.zip
sudo ./aws/install

Кубелет должен работать с флагом --cloud-provider = aws Анкет Мы можем применить это изменение в одном месте в этом AMI, и оно будет перенесено на все случаи, запущенные с этим изображением.

Изменить файл /и т.д/systemd/system/kubelet.service.d/10-kubeadm.conf и изменение строки, чтобы включить Облако-провайдер флаг в конце —

Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf --cloud-provider=aws"

На этом этапе мы можем создать Ami из этого случая. Назовем это K8S-Image Анкет

Настройка плоскости управления

Балансировщик нагрузки

Поскольку наша плоскость управления будет очень доступна, его экземпляры будут работать за балансировщиком нагрузки. Итак, я создал классический Elb который вперед TCP трафик на порту 6443 , порт по умолчанию, используемый плоскостью управления. Я не смог получить Nlb работать в этом эксперименте.

Я настраиваю балансировщик нагрузки для общения с 3 частными зонами доступности, где будет расположена плоскость управления. Допустим, название DNS балансировщика нагрузки — Internal-K8S-111.US-EAST-1.elb.amazonaws.com

Эти группы безопасности были созданы вручную —

ELB Security Group

Я создал группу безопасности для Elb который допустил вход в порт 6443 Из группы безопасности, прикрепленной к рабочим узлам, упомянутым ниже. Назовем это K8S-Loadbalancer-SG

Плоскость управления/группа безопасности рабочих узлов

Для удобства я использовал одну и ту же группу безопасности как для экземпляров плоскости управления, так и для экземпляров плоскости данных. Эта группа безопасности разрешила вход из группы безопасности балансировщика нагрузки, упомянутой выше на порту 6443 Анкет Это также позволило вход во все порты, если источник был самой группой безопасности. Назовем это K8S-Custom-SG Анкет Я также включил SSH на порту 22

IAM Роль

Давайте создадим роль IAM, которая будет прикреплена к нашим случаям. Я собираюсь называть это Customk8srole . Та же самая роль IAM будет прикреплена как к экземплярам плоскости управления, так и к экземплярам плоскости данных в этом эксперименте. В реальном мире вы будете предоставлять только минимальные необходимые привилегии для роли IAM.

Вам нужно будет обновить эту роль, чтобы предоставить доступ ко всем услугам AWS, которые мы собираемся упомянуть в этой статье.

Создание первой машины

Запустите экземпляр, используя наш пользовательский AMI K8S-Image и IAM Роль Customk8srole Анкет

Оставьте узел так, чтобы его можно было обнаружить рабочими узлами, например, с ключом K8S-контроль плоскости Анкет Ключ тега достаточно, значение не будет использоваться.

Добавить еще один тег kubernetes.io/cluster/kubernetes со значением принадлежит Анкет Это кажется необходимым, если мы используем облачный провайдер. Здесь Kubernetes это имя кластера, которое является именем по умолчанию, используемому Kubeadm. Если вы выбрали другое имя для кластера, измените ключ тега соответственно.

Измените имя хоста экземпляра —

sudo hostnamectl set-hostname \
$(curl -s http://169.254.169.254/latest/meta-data/local-hostname)

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

Для API -сервера и диспетчера контроллеров для интеграции с AWS Облачный провайдер нам нужно начать с флага --cloud-provider = aws Анкет Я не мог найти способ сказать kubeadm сделать это с помощью командной строки Args. Итак, мы будем бежать кубидм с файлом конфигурации config.yaml . Если мы используем файл конфигурации, то все аргументы должны перейти в файл, включая конечную точку API -сервера (плоскость управления). Конечная точка плоскости управления — это название DNS ELB, которое мы создали выше.

Создайте файл config.yaml

apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
apiServer:
  extraArgs:
    cloud-provider: aws
controllerManager:
  extraArgs:
    cloud-provider: aws
    configure-cloud-routes: "false"    
controlPlaneEndpoint: internal-k8s-111.us-east-1.elb.amazonaws.com:6443

Кубелет также должен запустить с этим флагом, но эта конфигурация выпекается в этот пользовательский AMI из -за изменения, которое мы внесли в файл 10-kubeadm.conf , поэтому нам не нужен раздел для настройки Kubelet.

Нам не нужно предоставлять диапазоны CI/DR для IPS POD и службы IPS в этом файле конфигурации, потому что мы будем использовать плагин AWS VPC CNI.

Прикрепите этот экземпляр к ELB. Первоначально он покажется вне службы. Это нормально, потому что в этом случае ничего не работает. Но это должно быть прикреплено сейчас, потому что это конечная точка контроллера Kubelet попытается получить доступ. После того, как сервер AAPI начнет работать на экземпляре, он будет отображаться как Inservice Анкет

Начните кубидм —

sudo kubeadm init --config config.yaml --upload-certs

Это должно быть. Единственной ошибкой, с которой я столкнулся на этом шаге, была неправильная конфигурация группы безопасности, когда ELB не смог общаться с Кубелетом.

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

Если есть ошибки, отлаживайте их, используя JournalCtl -a -xeu kubelet -f Анкет

Настройка .kube/config Файл, как указано в сообщении, и вы должны увидеть один мастер -узел.

kubectl get nodes

CNI

Ничто не будет работать, пока вы не установите плагин CNI. Следуя документации AWS о плагине AWS CNI, установите его заменить правильное значение для <Регион-код>

curl -o aws-k8s-cni.yaml https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/v1.7.5/config/v1.7/aws-k8s-cni.yaml
sed -i -e 's/us-west-2//' aws-k8s-cni.yaml
kubectl apply -f aws-k8s-cni.yaml

Добавление узлов плоскости управления

Запустите столько машин, сколько хотелось бы использовать пользовательское изображение и пользовательскую роль IAM.

Добавьте теги kubernetes.io/cluster/kubernetes (Значение принадлежит ) и K8S-контроль плоскости (со значением как пустое), как это сделано для первого узла.

Измените имя хоста, прежде чем что -либо делать, и добавьте машину в ELB.

Запустите команду, как напечатано предыдущим шагом.

sudo hostnamectl set-hostname \
$(curl -s http://169.254.169.254/latest/meta-data/local-hostname)
kubeadm join internal-k8s-111.us-east-1.elb.amazonaws.com:6443 --token 111.111 \
    --discovery-token-ca-cert-hash sha256:111 \
    --control-plane --certificate-key 111

Рабочие узлы

Команда для рабочего узла для присоединения к кластеру была напечатана при настройке нашего первого узла плоскости управления. Это выглядит примерно так —

kubeadm join internal-k8s-111.us-east-1.elb.amazonaws.com:6443 --token 111.111 \
    --discovery-token-ca-cert-hash sha256:111

Таким образом, нам нужен токен, сгенерированный на узле плоскости управления, нам нужно знать конечную точку плоскости управления и хэш сертификата. В настоящее время у нас есть эти значения, потому что мы только что настроили нашу плоскость управления. Но как мы можем решить проблему с добавлением рабочих узлов в кластер из -за автоматического разъема через месяц. Это не очень хорошая идея для хардкодирования этих значений.

Экземпляры EC2 позволяют нам предоставить сценарий как UserData который выполняется сразу после запуска экземпляра. Мы можем использовать UserData Чтобы автоматизировать этот процесс.

Наш скрипт будет использовать AWS CLI, который удобно запечен в нашем изображении.

Мы также будем использовать AWS Systems Manager Run Command для удаленного выполнения команд на узле плоскости управления. Я получил очень выгоду от приведены примеры Анкет

Наши экземпляры должны быть частью автоматической группы (ASG). ASG определяет, сколько экземпляров мы хотим, чтобы в настоящее время работали, минимальное количество экземпляров, которые всегда должны работать, и максимальное количество экземпляров, которые он позволит работать. ASG также заявляет о подсетях, где могут быть запущены экземпляры.

ASG нуждается в конфигурации запуска, которая определяет AMI, которая будет использоваться для запуска экземпляра. Мы будем использовать наш пользовательский AAMI.

Мы также можем объявить теги ресурсов, которые будут применены к экземплярам, запущенным с использованием этой конфигурации запуска. Тег ресурса, который необходимо настроить здесь, является kubernetes.io/cluster/kubernetes со значением принадлежит Анкет

Наш скрипт будет запросить экземпляры EC2, которые были помечены K8S-контроль плоскости , которые все наши узлы плоскости управления. Затем он удаленно выполнит команду в первом узле из этого списка, используя AWS SSM Send-Command Чтобы сгенерировать новый токен и генерировать команду, чтобы присоединиться к кластеру в качестве рабочего узла. Затем он выполнит эту команду и, наконец, выполнит еще одну удаленную команду, чтобы удалить токен, который был сгенерирован.

Вот UserData который мы можем предоставить нашей конфигурации запуска. Агент SSM уже установлен на узлах плоскости управления, потому что мы использовали AWS Managed Ubuntu Image. Наш Customk8srole Нужно добавить политики, которые позволяют ей выполнять эти команды.

#!/bin/bash
sudo hostnamectl set-hostname \
$(curl -s http://169.254.169.254/latest/meta-data/local-hostname)
instances=$(aws ec2 describe-instances --filters "Name=tag-key,Values=k8s-control-plane" | jq -r ".Reservations[].Instances[].InstanceId")
echo "control plane instances- $instances"
instance=$(echo $instances| cut -d ' ' -f 1)
echo "working with instance- $instance. Generating token."
sh_command_id=$(aws ssm send-command \
    --instance-ids "${instance}" \
    --document-name "AWS-RunShellScript" \
    --comment "Generate kubernetes token" \
    --parameters commands="kubeadm token generate" \
    --output text \
    --query "Command.CommandId")
sleep 5
echo "Receiving token"
result=$(aws ssm list-command-invocations --command-id "$sh_command_id" --details | jq -j ".CommandInvocations[0].CommandPlugins[0].Output")
token=$(echo $result| cut -d ' ' -f 1)
echo "generating join command"
sh_command_id=$(aws ssm send-command \
    --instance-ids "${instance}" \
    --document-name "AWS-RunShellScript" \
    --comment "Generate kubeadm command to join worker node to cluster" \
    --parameters commands="kubeadm token create $token  --print-join-command" \
    --output text \
    --query "Command.CommandId")
sleep 10
echo "getting result"
result=$(aws ssm list-command-invocations --command-id "$sh_command_id" --details | jq -j ".CommandInvocations[0].CommandPlugins[0].Output")
join_command=$(echo ${result%%---*})
echo "executing join command"
$join_command
echo "deleting kubernetes token"
sh_command_id=$(aws ssm send-command \
    --instance-ids "${instance}" \
    --document-name "AWS-RunShellScript" \
    --comment "Delete kubernetes token" \
    --parameters commands="kubeadm token delete $token" \
    --output text \
    --query "Command.CommandId")
sleep 5
result=$(aws ssm list-command-invocations --command-id "$sh_command_id" --details | jq -j ".CommandInvocations[0].CommandPlugins[0].Output")
echo $result

Кластер Autoscaler

Скачать манифест YAML curl -o https://raw.githubusercontent.com/kubernetes/autoscaler/master/cluster-autoscaler/cloudprovider/aws/examples/cluster-autoscaler-ony-asg.yaml

Мы используем Один-Асг проявляется в этом случае. Но если ваша настройка использует постоянные объемы, вам придется использовать Многоасг проявится путем настройки одной зоны ASG на доступность.

Заменить K8S-Worker-ASG-1 В файле с именем вашего ASG и отредактируйте раздел для сертификатов, как это —

        - name: ssl-certs
          hostPath:
            path: "/etc/ssl/certs/ca-certificates.crt"

Местоположение, упомянутое в файле /etc/ssl/certs/ca-bundle.crt неверно для нашей настройки.

Применить манифест Kubectl Apply -f Cluster-Autoscaler-One-Asg.yaml Анкет

Калико

Чтобы иметь возможность обеспечить сетевые политики, Calico является одним из вариантов —

Kubectl Apply -f https://raw.githubusercontent.com/aws/amazon-vpc-cni-k8s/v1.7.5/config/v1.7/calico.yaml

Контроллер балансировщика нагрузки AWS

Контроллер INGRESS AWS ALB теперь известен как контроллер балансировщика нагрузки AWS. Он может создать балансировщики нагрузки приложений для услуг, которые вы хотите разоблачить в Интернете.

Я смог развернуть Echoserver Анкет Общественные подсету должны были быть помечены kubernetes.io/role/elb и частные подсету с kubernetes.io/role/internal-elb .

Оригинал: «https://dev.to/pksinghus/running-a-self-managed-kubernetes-cluster-on-aws-mhm»