суббота, 1 сентября 2018 г.

Установка Kubernetes с помощью kops в AWS

В этой заметке я опишу, как быстро с нуля поднять рабочий кластер k8s в облаке амазона.
Если у вас много денег, можете использовать EKS (который еще недоступен во многих регионах), в качестве альтернативы я использую именно связку AWS+kops.

Ставим необходимые пакеты для работы с кубером (моя локальная ОС Mac OS X)
brew update
brew install awscli kubectl kops kubernetes-helm

Готовим некоторые переменные:
cat <<EOT > .env
export KOPS_ENV=dev
export [email protected] # пригодится позже
EOT

source .env

Создаем группу пользователя для работы в облаке амазона:
aws iam create-group --group-name kops-${KOPS_ENV}
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess --group-name kops-${KOPS_ENV}
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonRoute53FullAccess --group-name kops-${KOPS_ENV}
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess --group-name kops-${KOPS_ENV}
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/IAMFullAccess --group-name kops-${KOPS_ENV}
aws iam attach-group-policy --policy-arn arn:aws:iam::aws:policy/AmazonVPCFullAccess --group-name kops-${KOPS_ENV}
aws iam create-user --user-name kops-${KOPS_ENV}
aws iam add-user-to-group --user-name kops-${KOPS_ENV} --group-name kops-${KOPS_ENV}

aws iam create-access-key --user-name kops-${KOPS_ENV}

Используем новые креды пользователя, которые мы получили:
cat <<EOT >> .env
export AWS_ACCESS_KEY_ID=AAA
export AWS_SECRET_ACCESS_KEY=BBB

export DOMAIN=k8s-${KOPS_ENV}.domain.org
export ZONE_ID=Z1UJ9MQQPGMX38 # domain.org zone ID (см. Amazon Console Route53)
EOT

source .env

Создаем зону для домена:
ID=$(uuidgen)
aws route53 create-hosted-zone --name ${DOMAIN} --caller-reference ${ID}

И достаем созданную зону:
SUBDOMAIN_ZONE_ID=$(aws route53 list-hosted-zones-by-name --dns-name ${DOMAIN} --max-items 1 --output json | jq '.HostedZones[].Id' | awk -F '/' '{print $3}' | tr -d '"')

cat <<EOT >> .env
export SUBDOMAIN_ZONE_ID=${SUBDOMAIN_ZONE_ID} # k8s-dev.domain.org zone ID
EOT

source .env

Теперь нужно получить днс-сервера зоны:
aws route53 get-hosted-zone --id ${SUBDOMAIN_ZONE_ID} --output json | jq '.DelegationSet.NameServers[]' | tr -d '"'

Генерируем json-файл с днс-серверами (замените ${NS_1,2,3,4} валидными днс-серверами:
cat << EOF > json/${DOMAIN}.json
{
  "Comment": "Create a ${DOMAIN} NS record in the parent domain",
  "Changes": [
    {
      "Action": "CREATE",
      "ResourceRecordSet": {
        "Name": "${DOMAIN}",
        "Type": "NS",
        "TTL": 300,
        "ResourceRecords": [
          {
            "Value": "${NS_1}"
          },
          {
            "Value": "${NS_2}"
          },
          {
            "Value": "${NS_3}"
          },
          {
            "Value": "${NS_4}"
          }
        ]
      }
    }
  ]
}
EOF

Привяжем субдомен к домену:
aws route53 change-resource-record-sets --hosted-zone-id ${ZONE_ID} --change-batch file://json/${DOMAIN}.json

И проверим доступность зоны:
dig ns ${DOMAIN} +short

Создадим бакет для kops и включим версионирование для него:
aws s3api create-bucket --bucket ${DOMAIN} --region eu-west-1 --create-bucket-configuration LocationConstraint=eu-west-1
aws s3api put-bucket-versioning --bucket ${DOMAIN} --versioning-configuration Status=Enabled

Добавим еще некоторые переменные:
cat <<EOT >> .env
export NAME=${DOMAIN}
export KOPS_STATE_STORE=s3://${DOMAIN}
export ZONES=eu-west-1a
export INSTANCE_TYPE=m5.large
EOT

source .env

Сгенерируем SSH-ключ для доступа к кластеру:
ssh-keygen -f ~/.ssh/k8s-${KOPS_ENV} -C admin@${DOMAIN} -N ''

Создадим стейт кластера в бакете:
kops create cluster \
--name=${NAME} \
--zones ${ZONES} \
--master-zones ${ZONES} \
--node-count=2 \
--node-size=${INSTANCE_TYPE} \
--master-count=1 \
--master-size=${INSTANCE_TYPE} \
--cloud=aws \
--kubernetes-version=1.10.5 \
--image kope.io/k8s-1.10-debian-stretch-amd64-hvm-ebs-2018-08-17 \
--ssh-public-key=~/.ssh/k8s-${KOPS_ENV}.pub

Если это дев кластер, то его можно запускать на спот-инстансах, так получится дешевле.
Вот ценник на них: https://aws.amazon.com/ec2/spot/pricing/
Для мастеров я использовать спот-инстанс не буду, а для нод буду.

Настроим спот-инстансы и установим максимальное кол-во нод:
kops edit instancegroups nodes --name ${NAME} --state=s3://${NAME}
...
spec:
  maxPrice: "0.042"
  maxSize: 4

Непосредственно инициируем создание кластера:
kops update cluster --name=${NAME} --yes

Wait for 5 min and check cluster status:
Ждем некоторое время, попутно проверяя состояние кластера:
kops validate cluster --name=${NAME} | tail -1

Проверяем SSH-доступ к мастеру:
ssh -i ~/.ssh/k8s-${KOPS_ENV} admin@api.${DOMAIN} \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null

На этом базовая установка кластера окончена.

Комментариев нет: