machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Kubernetes: запуск полного кластера EKS за 13 шагов, более или менее

Дата публикации Oct 3, 2019

При первом развертывании сервиса Amazon Kubernetes вы получаете работающий кластер без развернутых рабочих узлов и нескольких предварительно настроенных модулей. Существует несколько отдельных инструкций по настройке распространенных надстроек, но для того, чтобы собрать все части, требуется немного опыта и времени. Вот мой процесс установки.


1. Разверните сам EKS через Terraform

Во-первых, вам нужно создать кластер EKS, и мой предпочтительный инструмент для этогоTerraform,

resource "aws_iam_role" "eks-cluster-control-plane" {
name = "eks-cluster-control-plane"
assume_role_policy = "${data.aws_iam_policy_document.eks-cluster-control-plane-assume-role.json}" tags {
Name = "eks-cluster-control-plane"
}
}resource "aws_eks_cluster" "cluster" {
name = "my-eks-cluster"
role_arn = "${aws_iam_role.eks-cluster-control-plane.arn}"
version = "1.13"

enabled_cluster_log_types = [
"api",
"audit",
"authenticator",
"controllerManager",
"scheduler"
]

vpc_config {
security_group_ids = [
"${aws_security_group.eks-cluster-control-plane.id}"
]
subnet_ids = [
"${module.integration.eks_private_subnets}"
]

endpoint_private_access = true
endpoint_public_access = false
} provider = "aws.eks-creation" count = "${signum(var.eks-bootstrap["creator-role-exists"])}" depends_on = ["aws_cloudwatch_log_group.eks"]
}resource "aws_cloudwatch_log_group" "eks" {
name = "/aws/eks/${var.environment}-eks/cluster"
retention_in_days = 30
}

Это создает кластер, роль плоскости управления и группу журналов CloudWatch. Создание группы журналов в Terraform позволяет настроить хранение и упростить подключение нескольких других вещей позже, не в последнюю очередь политик IAM.

Вы можете заметить, что я использую обычайprovider, Это потому, что когда вы создаете кластер, Kubernetescluster-adminроль (см.Использование авторизации RBAC) связан с созданием пользователя или роли. Присвоение этой роли выделенной роли IAM облегчает задачу в дальнейшем, но требует дополнительной настройки и шага начальной загрузки (сначала создайте роль, а затем создайте кластер):

resource "aws_iam_role" "eks-cluster-owner" {
name = "eks-cluster-owner"
assume_role_policy = "${data.aws_iam_policy_document.eks-cluster-owner-assume-role.json}" tags {
Name = "eks-cluster-owner"
}
}variable "eks-bootstrap" {
description = "Properties needed to control progressive creation of EKS cluster"
type = "map"
default = {
creator-role-exists = 0 # Change this to 1 after the role exists
}
}locals {
provider-aws-eks-cluster-owner-role-list = "${signum(var.eks-bootstrap["creator-role-exists"]) == 1 ? join(",",aws_iam_role.eks-cluster-owner.*.arn) : ""}"
provider-aws-eks-cluster-owner-effective-role = "${element(split(",",local.provider-aws-eks-cluster-owner-role-list),0)}"
}provider "aws" {
region = "${var.region}"
access_key = "${var.access_key}"
secret_key = "${var.secret_key}" version = "~> 2.0" assume_role {
role_arn = "${local.provider-aws-eks-cluster-owner-effective-role}"
} alias = "eks-creation"
}

Здесь вы можете увидеть, что есть некоторая дополнительная магия Terraform, чтобы гарантировать, что действительный поставщик создан независимо от того, существует роль или нет, но она имеет толькоassume_roleустановить, когдаcreator-role-existsустановлено.

Вам также нужны политики для этих ролей. Вот мои правила:

data "aws_iam_policy_document" "eks-cluster-control-plane-assume-role" {
statement {
sid = "AllowAssumeRole"
effect = "Allow"
actions = [
"sts:AssumeRole",
]
principals {
type = "Service"
identifiers = [ "eks.amazonaws.com" ]
}
}
}resource "aws_iam_role_policy_attachment" "eks-cluster-control-plane-aws-service-policy" {
role = "${aws_iam_role.eks-cluster-control-plane.name}"
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy"
}resource "aws_iam_role_policy_attachment" "eks-cluster-control-plane-aws-cluster-policy" {
role = "${aws_iam_role.eks-cluster-control-plane.name}"
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
}data "aws_iam_policy_document" "eks-cluster-owner-assume-role" {
statement {
sid = "AllowAssumeRole"
effect = "Allow"
actions = [
"sts:AssumeRole",
]
principals {
type = "AWS"
identifiers = [
"arn:aws:iam::${data.aws_caller_identity.this.account_id}:root",
]
}
}
}resource "aws_iam_role_policy_attachment" "eks-administration" {
role = "${aws_iam_role.eks-cluster-owner.name}"
policy_arn = "${aws_iam_policy.eks-administration.arn}"
}resource "aws_iam_policy" "eks-administration" {
name = "eks-administration"
path = "/"
policy = "${data.aws_iam_policy_document.eks-administration.json}"
}data "aws_iam_policy_document" "eks-administration" {
statement {
sid = "AllowEKSManagement"
effect = "Allow"
actions = [
"eks:*",
]
resources = [
"arn:aws:eks:${data.aws_region.this.name}:${data.aws_caller_identity.this.account_id}:cluster/${var.environment}-eks",
"arn:aws:eks:${data.aws_region.this.name}:${data.aws_caller_identity.this.account_id}:cluster/${var.environment}-eks/*",
]
}statement {
sid = "AllowPassControlPlaneRole"
effect = "Allow"
actions = [ "iam:PassRole" ]
resources = [
"${aws_iam_role.eks-cluster-control-plane.arn}",
]
}
}

Вы также можете увидеть некоторые ссылки наaws_regionа такжеaws_caller_identityВот. Это простые помощники:

data "aws_region" "this" { }
data "aws_caller_identity" "this" { }

Вам, конечно, также понадобятся группы безопасности. Я не освещал их здесь, так как это займет много времени, будет скучно читать и довольно хорошо освещеноВопросы группы безопасности кластера, Одной вещью, которую можно упустить, является то, что использование сети AWS ENI напрямую (как я настоятельно рекомендую) означает, что модули должны иметь возможность общаться напрямую, что означает, что им также нужны правила доступа к группе безопасности. Как правило, это означает, что группы безопасности AWS VPC будут разрешать весь трафик между серверами API и узлами, а также между различными узлами. Это может быть усилено уровнем сетевой политики или использованием выделенных подсетей для модулей. Вы столкнетесь с проблемами, если для этого будете полагаться на группы безопасности VPC в основных сетевых подсетях.


2. Проверьте компоненты кластера

При развертывании кластера EKS AWS предварительно назначит CoreDNS, kube-proxy и aws-node (агент CNI). Тем не менее, вы должны проверить версии, что вы хотите. Помните, что вам нужно держать их в курсе. ВидетьОбновление версии Amazon EKS Cluster Kubernetes, Рекомендуется убедиться, что вы полностью понимаете эту страницу и регулярно проверяете ее на наличие обновлений.


3. Обновите CoreDNS для вложенного разрешения ExternalName

Видетьhttps://github.com/coredns/coredns/issues/2038, По умолчанию CoreDNS не позволяет рекурсивно разрешать службу ExternalName. Это может быть полезно, если вы хотите подключить службы в разных пространствах имен. Исправление тривиально, просто добавьтеupstream /etc/resolv.confв CoreDNS ConfigMap:

kubectl edit configmap --namespace kube-system coredns

Вы также можете масштабировать развертывание. Чтобы убедиться, что он получает новый ConfigMap (который может занять до 10 секунд, чтобы стать доступным), я использую следующее:

kubectl scale --namespace kube-system deployment coredns \
--replicas=0
# WAIT
kubectl scale --namespace kube-system deployment coredns \
--replicas=2

4. Патч конфигурации CNI

В идеале вы должны сделать это, прежде чем запускать какие-либо рабочие узлы. CNI DaemonSet использует переменные среды для управления своим поведением. Вы можете прочитать об этом здесь:Переменные конфигурации CNI,

Я предпочитаю добавлять ConfigMap со своими изменениями, с минимальными изменениями в DaemonSet. Вот мой ConfigMap:

apiVersion: v1
kind: ConfigMap
metadata:
namespace: kube-system
name: my-aws-cni-environment
data:
AWS_VPC_CNI_NODE_PORT_SUPPORT: "true"
AWS_VPC_K8S_CNI_CUSTOM_NETWORK_CFG: "false"
AWS_VPC_K8S_CNI_EXTERNALSNAT: "true"
WARM_IP_TARGET: "10"

Затем я исправляю DaemonSet следующим образом:

#!/bin/bashPATCH_SPEC="$(cat - <<EOF
{
"spec": {
"template": {
"spec": {
"containers": [
{
"name": "aws-node",
"envFrom": [
{
"configMapRef": {
"name": "my-aws-cni-environment",
"optional": false
}
}
]
}
]
}
}
}
}
EOF
)"kubectl patch --namespace kube-system daemonset/aws-node \
-p "${PATCH_SPEC}"

5. Примените авторизацию узла AWS IAM

Чтобы рабочие узлы проходили аутентификацию в системе RBAC Kubernetes, необходимо убедиться, чтоaws-authConfigMap настроен. Вот мой:

apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: @@INSTANCEROLE@@
username: system:node:{{EC2PrivateDNSName}}
groups:
- system:bootstrappers
- system:nodes

Я использую скрипт для инъекций@@INSTANCEROLE@@но вы можете добавить его напрямую, если хотите.


6. Добавить классы хранения

Я предпочитаю иметь выделенные классы хранения для каждой зоны доступности. Вам также могут потребоваться дополнительные классы хранения для разных рабочих нагрузок. Вот один пример:

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: gp2-us-east-1a
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
zones: us-east-1a

7. Разверните сервер метрик

Kubernetes использует компонент сервера метрик для поддержки HorizontalPodAutoscaler. Это полезный компонент, но не полнофункциональный агент метрик. Лично я не считаю это необязательным. Развертывание полностью описано здесь:Установка метрического сервера Kubernetes,


8. Разверните свой входной контроллер

Я писал об этом в предыдущем постеВот,


9. Разверните поставщик EFS

Если вы хотите использовать EFS для хранения файлов (что имеет преимущество в том, что вы не привязаны к одной зоне доступности), вы можете развернутьEFS-Provisioner, Для этого потребуется некоторая адаптация, лучше всего просмотреть все развертывание и настроить его под свои нужды.

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

sudo -i
mount -t nfs4 <EFS-DNS>:/ /mnt
mkdir /mnt/my-efs-root-folder
umount /mnt

10. Примените возможности доставки журналов

Я использовал комбинациюfluentdи пользовательские возможности, чтобы гарантировать, что стручок иSYSTEMDбревна были отправлены на нашу платформу. То, что вам нужно, будет зависеть от вашей среды.


11. Добавьте надстройку поддержки NVidia GPU, если вы хотите поддержку обработки GPU

Это позволяет вам управлять ресурсами GPU и делать их доступными для модулей. Вам необходимо развернуть DaemonSet:Плагин устройства NVIDIA для Kubernetes,


12. Добавьте поддержку для вашего агента развертывания

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


13. Добавить поддержку метрики Прометея

Опять же, в зависимости от того, что вам требуется, вам может потребоваться выполнить различные шаги здесь. Для моего использования было три действия по развертыванию:

  1. Прометей Узел Экспортер, Однако в документации говорится:

Не рекомендуется развертывать его как контейнер Docker, поскольку для него требуется доступ к хост-системе.

Так что вы можете захотеть развернуть это прямо на ваших рабочих узлах.

2.Кубэ-состояние-метрика, Развертывание описаноВотно вы можете настроить способ доступа к нему Прометея, особенно если Прометей является внешним по отношению к кластеру EKS.

3. Учетная запись службы Kubernetes для Prometheus, чтобы использовать для очистки кластера. Я назначаю одно ClusterRole для этого:

apiVersion: v1
kind: Namespace
metadata:
name: my-system-prometheus
---
apiVersion: v1
kind: ServiceAccount
metadata:
namespace: my-system-prometheus
name: kubelet-scraping
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: my-system-prometheus:kubelet-scraping
rules:
- apiGroups:
- ""
resources:
- nodes/metrics
- nodes/proxy
verbs:
- get
- apiGroups:
- ""
resources:
- nodes
verbs:
- list
- get
- watch
- nonResourceURLs:
- /metrics
verbs:
- get
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: my-system-prometheus:kubelet-scraping
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: my-system-prometheus:kubelet-scraping
subjects:
- kind: ServiceAccount
name: kubelet-scraping
namespace: my-system-prometheus

И вот, у меня есть тринадцать шагов для запуска нового кластера EKS. Я не рассмотрел, как вы настраиваете свои собственные рабочие узлы EKS, потому что это будет сильно зависеть от того, чего вы хотите достичь. Возможно, в другой раз.

Я надеюсь, что это поможет вам сэкономить время и, по крайней мере, укажет вам несколько моментов.


Этот пост также опубликован в моем блоге наhttps://stevehorsfield.wordpress.com/2019/10/03/kubernetes:-launching-a-full-eks-cluster-in-13-steps-more-or-less/,


Обновить, Теперь вы можете увидеть пример кода Terraform для некоторых из них здесь:https://github.com/stevehorsfield/eks-example,

Оригинальная статья

Footer decor

© machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map