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

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

Однако это не означает, что война официально окончена.

В этой записи блога вы узнаете с теоретической и практической точки зрения, что такое Elastic Container Service, что такое оркестрация и как реализовать как AWS EKS, так и ECS.

Что такое оркестровка?

Когда большинство инженеров или технических руководителей думают об оркестровке, о чем они обычно думают? Кубернетес.

При этом важно сделать шаг назад и на самом деле подумать о том, что такое оркестровка.

Оркестровка дает вам возможность:

  • Масштабируйте контейнерные рабочие нагрузки.
  • Автоматически планируйте, где должны выполняться контейнерные рабочие нагрузки.
  • Такие функции, как самовосстановление.

По сути, оркестровка управляет «инфраструктурой» контейнеров за вас, поэтому вам не нужно этого делать.

До оркестровки вы могли использовать контейнеры, но они не могли ничего сделать, кроме запуска одной рабочей нагрузки и выхода. Причина в том, что не было гарантии, что контейнер сможет работать долгое время. Это было очень хорошо для тестирования приложения или запуска рабочей нагрузки, а затем выключения контейнера, но это все. Затем, как только появится оркестровка, вы сможете иметь долго работающие контейнеры с рабочими нагрузками. Если контейнер выйдет из строя, новый контейнер будет создан автоматически.

Размышляя над вышеизложенным, вы должны спросить себя — является ли Kubernetes единственным способом «аранжировки» контейнеров?

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

Что такое ЭКС?

Elastic Container Service (ECS) — это способ автоматического масштабирования и оптимизации контейнерных рабочих нагрузок. Если вам нужно более простое решение, отличное от Kubernetes, ECS — отличное решение с очень похожими функциями, возможностями и результатами.

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

При создании кластера ECS у вас есть три варианта:

  • Только сеть
  • на базе Linux
  • на базе Windows

Вариант «Только сеть» развертывает ECS с использованием профиля AWS Fargate, который по сути является «бессерверным». Он работает как для Linux, так и для Windows в зависимости от вашей рабочей нагрузки. Это означает, что нет экземпляров EC2 под управлением Linux или Windows, которыми вы должны управлять.

ECS на базе Linux имеет экземпляры Linux EC2, на которых выполняются рабочие нагрузки ECS. На базе Windows — это EC2, на котором есть серверы Windows, на которых выполняются рабочие нагрузки ECS. К счастью, для обоих этих вариантов включено автоматическое масштабирование, поэтому вам не нужно беспокоиться об увеличении или уменьшении масштаба инстансов EC2.

Два самых больших отличия заключаются в том, что Fargate может быть немного дороже в зависимости от вашей рабочей нагрузки, и Fargate в настоящее время не поддерживает DaemonSets, то есть Pod, который запускается на каждом рабочем узле.

Что такое ЭКС?

Прежде чем перейти к EKS, давайте ответим на вопрос — что такое Kubernetes?

Ну, этот ответ сам по себе может заполнить несколько книг, так что давайте будем краткими. Как упоминалось в разделе Что такое оркестрация?, Kubernetes — это способ планирования, самовосстановления и управления контейнерными рабочими нагрузками. Да, в него входит гораздо больше, но это общая суть.

EKS — это просто способ запустить Kubernetes как управляемую службу. Когда вы загружаете Kubernetes, например, с Kubeadm on-prem, на это уходит много всего. Общая сеть, инфраструктура, операционные системы, лицензии и управление. С EKS многое из этого абстрагируется от вас. Вам не нужно беспокоиться об управлении плоскостями управления. Вместо этого вы просто беспокоитесь о рабочих узлах, которые могут работать как экземпляры EC2 или с Fargate.

EKS — отличное решение, если вы уже работаете с AWS и хотите запускать рабочие нагрузки в Kubernetes без локального кластера Kubernetes.

Как и во всех облачных управляемых сервисах Kubernetes, вы теряете доступ к уровням управления. Хотя для некоторых это не имеет большого значения, другие организации могут захотеть такой контроль. Это редкость, но что-то нужно иметь в виду.

Разница?

Читая разделы выше, вы, вероятно, подумали про себя: ECS и EKS, а также Kubernetes, работающие в любом другом облаке, похоже, делают одно и то же.

Ответ положительный. Функционально оркестровка — это оркестровка, и, в конце концов, она выполняет одну работу — оркестрацию контейнеров. Однако есть различия.

Давайте подумаем о трех ключевых отличиях:

  • Как вы можете запускать рабочие нагрузки
  • Где можно запускать рабочие нагрузки
  • Общая поддержка

Во-первых, давайте поговорим о том, как вы можете запускать рабочие нагрузки. Хотя ECS отлично подходит для оркестровки, на момент написания этой статьи он поддерживал только среду выполнения Docker. Хотя это подходит почти для всех организаций, вам все же придется подумать об этом. Если вы хотите использовать что-то вроде Podman, у вас не получится. Поскольку это конкретный сервис AWS, вы будете ограничены его возможностями.

Где вы можете запускать эти рабочие нагрузки, также имеет большое значение. ECS предназначен для AWS. Это означает, что если вы решите, что больше не хотите его использовать, вам придется подумать о переходе на другое решение. Если вы запускаете Kubernetes в EKS и хотите, например, переключиться на AKS, это не проблема. Некоторый рефакторинг инфраструктуры как кода и, возможно, откуда вы извлекаете образ контейнера, но это все. Хорошая новость заключается в том, что если вы используете ECS, рабочие нагрузки уже контейнеризованы. Вам просто нужно построить для Kubernetes. Вы не переходите от приложений, работающих на «голом железе», к Kubernetes. Используя ECS, вы уже на полпути. ECS также является лучшим решением для небольших команд, потому что Kubernetes сам по себе является зверем и может не понадобиться прямо сейчас.

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

Настройка ECS и EKS

Теперь, когда вы ознакомились с теорией, давайте посмотрим, как настроить ECS и EKS.

В настройке EKS и ECS есть свои плюсы и минусы. Плюс в том, что есть несколько способов их настройки. Минус в том, что есть несколько способов их настроить (посмотрите, что я там сделал?).

Поэтому давайте пойдем по маршруту Terraform.

Если вы не используете Terraform, ничего страшного. Выполните быстрый поиск в Google. Что-то вроде «как настроить EKS с помощью X tool». Например — «как настроить EKS с помощью AWS CLI».

Существует масса информации о различных методах настройки.

ЭКС

Сначала укажите сервер ECS, который вы хотите создать. Это будет считаться «кластером».

resource "aws_ecs_cluster" "levancluster" {
  name = "levanecscluster"
  setting {
    name  = "containerInsights"
    value = "enabled"
  }
}

Далее укажите определение задачи. Определение задачи — это контейнерная рабочая нагрузка, которую вы хотите запустить в ECS.

resource "aws_ecs_task_definition" "nginxapp" {
  family                   = "nginxapptask"
  cpu                      = 1024
  memory                   = 2048
  container_definitions = <<DEFINITION
[
  {
    "image": "nginx:latest",
    "name": "nginx",
    "networkMode": "awsvpc",
    "portMappings": [
      {
        "containerPort": 80,
        "hostPort": 80
      }
    ]
  }
]
DEFINITION
}

Последним шагом является указание службы ECS. Служба ECS позволяет указать, сколько копий определения задачи (контейнерной рабочей нагрузки) вы хотите запустить в кластере ECS. Он также прикрепляет определение задачи к созданной вами службе ECS.

resource "aws_ecs_service" "ecsservice" {
  name            = "nginxservice"
  cluster         = "levanecscluster"
  task_definition = aws_ecs_task_definition.nginxapp.arn
  desired_count   = 2
  depends_on = [
    aws_ecs_task_definition.nginxapp
  ]
}

ЭКС

Сначала настройте конфигурацию и провайдера серверной части Terraform.

terraform {
  backend "s3" {
    bucket = "name_of_bucket"
    key    = "eks-terraform.tfstate"
    region = "us-east-1"
  }
  required_providers {
    aws = {
      source = "hashicorp/aws"
    }
  }
}

Затем создайте роль IAM для EKS, чтобы иметь доступ к соответствующим ресурсам.

resource "aws_iam_role" "eks-iam-role" {
  name = "eks-iam-role"
  path = "/"
  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "eks.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

Прикрепите политики IAM к роли IAM для EKS и реестра контейнеров.

resource "aws_iam_role_policy_attachment" "AmazonEKSClusterPolicy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy"
  role       = aws_iam_role.eks-iam-role.name
}
resource "aws_iam_role_policy_attachment" "AmazonEC2ContainerRegistryReadOnly-EKS" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
  role       = aws_iam_role.eks-iam-role.name
}
## Create the EKS cluster
resource "aws_eks_cluster" "k8squickstart-eks" {
  name = "k8squickstart-cluster"
  role_arn = aws_iam_role.eks-iam-role.arn
  #enabled_cluster_log_types = ["api", "audit", "scheduler", "controllerManager"]
  vpc_config {
    subnet_ids = [var.subnet_id_1, var.subnet_id_2]
  }
  depends_on = [
    aws_iam_role.eks-iam-role,
  ]
}

Затем настройте рабочие узлы.

resource "aws_iam_role" "workernodes" {
  name = "eks-node-group-example"
  assume_role_policy = jsonencode({
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = {
        Service = "ec2.amazonaws.com"
      }
    }]
    Version = "2012-10-17"
  })
}

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

resource "aws_iam_role_policy_attachment" "AmazonEKSWorkerNodePolicy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
  role       = aws_iam_role.workernodes.name
}
resource "aws_iam_role_policy_attachment" "AmazonEKS_CNI_Policy" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
  role       = aws_iam_role.workernodes.name
}
resource "aws_iam_role_policy_attachment" "EC2InstanceProfileForImageBuilderECRContainerBuilds" {
  policy_arn = "arn:aws:iam::aws:policy/EC2InstanceProfileForImageBuilderECRContainerBuilds"
  role       = aws_iam_role.workernodes.name
}
resource "aws_iam_role_policy_attachment" "AmazonEC2ContainerRegistryReadOnly" {
  policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
  role       = aws_iam_role.workernodes.name
}
resource "aws_iam_role_policy_attachment" "CloudWatchAgentServerPolicy-eks" {
  policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
  role       = aws_iam_role.workernodes.name
}

Наконец, создайте ресурс для рабочих узлов.

resource "aws_eks_node_group" "worker-node-group" {
  cluster_name    = aws_eks_cluster.k8squickstart-eks.name
  node_group_name = "k8squickstart-workernodes"
  node_role_arn   = aws_iam_role.workernodes.arn
  subnet_ids      = [var.subnet_id_1, var.subnet_id_2]
  instance_types = ["t3.xlarge"]
  scaling_config {
    desired_size = var.desired_size
    max_size     = var.max_size
    min_size     = var.min_size
  }
  depends_on = [
    aws_iam_role_policy_attachment.AmazonEKSWorkerNodePolicy,
    aws_iam_role_policy_attachment.AmazonEKS_CNI_Policy,
    #aws_iam_role_policy_attachment.AmazonEC2ContainerRegistryReadOnly,
  ]
}

Заключение

В конце концов, Kubernetes/EKS и ECS — отличные варианты. Вы не можете ошибиться в любом случае с точки зрения оркестровки. Они оба делают одно и то же на 95% пути. Самое главное, о чем вам нужно подумать, — это насколько велики будут ваши рабочие нагрузки и удобно ли вам быть привязанным к определенному сервису AWS.