В этом посте я собираюсь показать вам реальное решение для создания среды, использующей технологии и практики DevOps для развертывания приложений и облачных сервисов/облачной инфраструктуры на AWS.
Я разобью эту серию статей на две части, где это будет первая часть, а вторую часть вам лучше поискать. Однако я размещу ссылку на вторую часть в конце этого поста.
Полное раскрытие информации — как стажер DevOps с разрешения, мне пришлось использовать исходный код целевой страницы ruralx.africa и начальные практики и технологии DevOps.
Почему DevOps?
Представьте, что вы сейчас работаете в организации, которая очень монолитна. В ней много голого металла, виртуализации, ручного развертывания приложений и старых методов, основанных на знаниях текущей команды в области ИТ.
Вас приглашают в компанию и команду, чтобы сделать все более современным, чтобы организация могла не только преуспеть, но и опередить конкурентов. Руководство теперь понимает потребности и сложности, связанные с опережением конкурентов, и знает, что это необходимо. В противном случае организацию ждет крах.
Решение?
Решение в этом посте — это реальный пример того, как добавить немного DevOps в существующий исходный код. DevOps — это набор практик, объединяющих разработку программного обеспечения и ИТ-операции. Его цель — сократить жизненный цикл разработки систем и обеспечить непрерывную доставку с высоким качеством программного обеспечения.
Предварительные условия
Для создания среды DevOps я буду использовать следующие технологии и платформы.
-
AWS
AWS будет использоваться для размещения приложения, облачной инфраструктуры и любых других сервисов, которые могут нам понадобиться для обеспечения правильного развертывания приложения ruralx. -
AWS CLI
AWS CLI — это способ взаимодействия со всеми службами AWS на программном уровне с помощью терминала. -
GitHub
Для хранения кода приложения и инфраструктуры/автоматизации -
Nodejs
Nodejs будет использоваться для веб-приложения (оно написано на JavaScript). -
Docker
Создайте образ Docker
Храните образ Docker в AWS ECR -
Terraform
Создайте ведро S3 для хранения файлов Terraform State
Создайте репозиторий AWS ECR с помощью Terraform
Создайте кластер EKS -
Kubernetes
Чтобы запустить образ Docker, созданный для контейнеризированного приложения ruralx. Kubernetes, в данном случае EKS, будет использоваться для оркестровки контейнера. -
CI/CD
Используйте GitHub Actions для создания кластера EKS -
Автоматизированное тестирование
Тестирование кода Terraform с помощью Checkov -
Prometheus
Система мониторинга с открытым исходным кодом с размерной моделью данных, гибким языком запросов, эффективной базой данных временных рядов и современным подходом к оповещению.
В этой первой части я покажу вам, как я применяю практику DevOps в непрерывной разработке; используя AWS, Docker и Terraform. А в последней части я покажу вам, как я применяю непрерывную интеграцию и непрерывное развертывание; используя GitHub Action, Kubernetes и Prometheus.
Давайте приступим к этому.
1.0 AWS
Установка AWS CLI
Шаги по установке AWS довольно просты и понятны, следуйте каждому шагу из документации AWS. Обратите внимание, что установка основных инструментов, таких как AWS, текстовый редактор, Docker и другие, выходит за рамки данного поста. В противном случае, это сделает этот пост неоправданно длинным, поэтому я буду считать, что у вас есть все необходимые знания, упомянутые выше.
Для получения документации по AWS CLI, вот ссылка
Настройка учетных данных для доступа к AWS на программном уровне
Цель — настроить учетные данные IAM на моем локальном компьютере, чтобы вы могли получить доступ к AWS на программном уровне (SDK, CLI, Terraform и т.д.).
- Откройте консоль управления AWS и перейдите в IAMSign in to the organization account, на вкладке Ваше имя пользователя в правом верхнем углу выберите Security Credential;
- Создайте нового пользователя или используйте существующего пользователя AWSДля этого доступа настоятельно рекомендуется создать нового пользователя. Особенно для проекта организации, где каждая команда имеет отдельный доступ к определенным активам организации и контролируется пользователем root.
Щелкните User (Пользователь) в строке меню IAM в левом верхнем углу;
-
Предоставьте пользователю программный доступ
На панели Security Credential выберите выпадающий список Access Key, затем нажмите на Create New Access Key; -
Скопируйте ключ доступа и секретный ключ
Важно отметить, что после выхода из диалогового окна вы не сможете снова получить доступ к этому ключу, поэтому вам необходимо скопировать ключ или загрузить и сохранить его. Хотя в случае потери вы всегда можете создать новый;
Настройка AWS CLI
-
Откройте окно терминала
Попробуйте проверить, правильно ли установлен aws, выполнив эту команду.Если отображение отличается от примера ниже, знайте, что вам нужно переустановить систему, чтобы избежать дальнейших осложнений;
-
Выполните команду configure
Для конфигурирования выполните командуaws configure
.
Заполните идентификатор ключа доступа и секретный ключ доступа.
Если вы не уверены в имени региона по умолчанию, просто оставьте его как есть, нажав кнопку Enter.
Для формата вывода я советую использовать JSON, нажмите кнопку Enter.
Вот так просто мы закончили настройку AWS.
Однако, если вам нужна дополнительная информация об установке и настройке AWS CLI, я рекомендую эту ссылку
2.0 VPC — виртуальное частное облако
Чтобы создать мой кластер VPC с публичной и частной подсетями
- Откройте консоль AWS CloudFormation, введите CloudFormation в поле службы.
- Выберите Create stack.
- Выберите Шаблон готов и, Amazon S3 URL. Затем вставьте следующий URL в текстовую область и выберите Next:
https://s3.us-west-2.amazonaws.com/amazon-eks/cloudformation/2020-10-29/amazon-eks-vpc-private-subnets.yaml
.
- На странице Specify Stack Details заполните следующее и выберите Next:
- Имя стека: Я выбираю имя стека для своего стека AWS CloudFormation. Например, я называю его ruralx-vpc.
- VpcBlock: Выберите диапазон CIDR для моего VPC. Каждому рабочему узлу, капсуле и балансировщику нагрузки, которые я развертываю, присваивается IP-адрес из этого блока. Значение по умолчанию обеспечивает достаточное количество IP-адресов для большинства реализаций, но если это не так, то я могу его изменить. Для получения дополнительной информации смотрите раздел Размер VPC и подсети в руководстве пользователя Amazon VPC. Я также могу добавить дополнительные блоки CIDR в VPC после его создания.
- PublicSubnet01Block: Укажите блок CIDR для публичной подсети 1. Значение по умолчанию обеспечивает достаточное количество IP-адресов для большинства реализаций, но если это не так, то я могу его изменить.
- PublicSubnet02Block: Укажите блок CIDR для публичной подсети 2. Значение по умолчанию обеспечивает достаточное количество IP-адресов для большинства реализаций, но если это не так, то я могу его изменить.
- PrivateSubnet01Block: Укажите блок CIDR для частной подсети 1. Значение по умолчанию обеспечивает достаточное количество IP-адресов для большинства реализаций, но если это не так, то я могу изменить его.
- PrivateSubnet02Block: Укажите блок CIDR для частной подсети 2. Значение по умолчанию обеспечивает достаточное количество IP-адресов для большинства реализаций, но если это не так, то я могу изменить его.
- (Необязательно) На странице Параметры отметьте ресурсы стека. Выберите Далее.
- На странице Обзор выберите Создать.
- Когда мой стек будет создан, выберите его в консоли и выберите Outputs.
- Запишите значение Security Groups для созданной группы безопасности. Когда я добавляю узлы в свой кластер, я должен указать идентификатор группы безопасности. Группа безопасности применяется к эластичным сетевым интерфейсам, которые создаются Amazon EKS в моих подсетях, что позволяет плоскости управления взаимодействовать с моими узлами. В описании этих сетевых интерфейсов указано Amazon EKS.
- Запишите VpcId для созданного VPC. Он понадобится мне при запуске шаблона группы узлов.
- Запишите SubnetIds для созданных подсетей и то, как я их создал — как публичные или частные подсети. Когда я добавляю узлы в свой кластер, я должен указать идентификаторы подсетей, в которые я хочу запустить узлы.
3.0 Terraform
Цель раздела Terraform — создать все облачные сервисы AWS, которые понадобятся мне с точки зрения среды/инфраструктуры для работы приложения ruralx.
Создание ведра S3 для хранения файлов TFSTATE
Здесь я создам ведро S3, которое будет использоваться для хранения файлов состояния Terraform.
Я создал файл main.tf внутри каталога, напишите в нем этот код;
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "terraform_state" {
bucket = "terraform-state-rurlax"
versioning {
enabled = true
}
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
}
Terraform main.tf
будет делать следующее:
- Создайте ведро S3 в регионе us-east-1.
- Убедитесь, что для параметра включения версии установлено значение
True
. - Использовать шифрование AES256.
- Создайте ведро, выполнив следующие действия:
terraform init
— для инициализации рабочего каталога и извлечения провайдера.
Создание реестра эластичных контейнеров
Идея заключается в том, чтобы создать репозиторий для хранения образа Docker, который я создал для приложения ruralx.
Затем я добавляю в main.tf
следующее;
terraform {
backend "s3" {
bucket = "terraform-state-ruralx"
key = "ecr-terraform.tfstate"
region = "us-east-1"
}
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_ecr_repository" "ruralx-ecr-repo" {
name = var.ruralx-ecr
image_tag_mutability = "MUTABLE"
image_scanning_configuration {
scan_on_push = true
}
}
Также создаю файл variables.tf
внутри директории, в основном для хранения env репо. Затем я пишу этот код;
variable ruralx-ecr {
type = string
default = "ruralx"
description = "ECR repo to store a Docker image"
}
Обратите внимание, что Terraform main.tf
будет делать это:
- Используйте бэкенд Terraform для хранения
.tfstate
в ведре S3. - Используйте ресурс
aws_ecr_repository
Terraform для создания нового хранилища.
- Создайте ведро, выполнив следующие действия:
terraform init
— Для инициализации рабочего каталога и извлечения провайдера.
Создание кластера EKS и роли/политики IAM
Здесь я собираюсь создать кластер EKS, написав следующий код;
terraform {
backend "s3" {
bucket = "terraform-state-ruralx"
key = "ecr-terraform.tfstate"
region = "us-east-1"
}
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
provider "aws" {
region = "us-east-1"
}
resource "aws_s3_bucket" "terraform_state" {
bucket = "terraform-state-ruralx"
versioning {
enabled = true
}
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
}
resource "aws_ecr_repository" "ruralx-africa-ecr-repo" {
name = var.ruralx-africa-ecr
image_tag_mutability = "MUTABLE"
image_scanning_configuration {
scan_on_push = true
}
}
terraform {
backend "s3" {
bucket = "terraform-state-ruralx"
key = "eks-terraform-workernodes.tfstate"
region = "us-east-1"
}
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
# IAM Role for EKS to have access to the appropriate resources
resource "aws_iam_role" "eks-iam-role" {
name = "ruralx-eks-iam-role"
path = "/"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "eks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
## Attach the IAM policy to the IAM role
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" "ruralx-eks" {
name = "ruralx-cluster"
role_arn = aws_iam_role.eks-iam-role.arn
vpc_config {
subnet_ids = [var.subnet_id_1, var.subnet_id_2]
}
depends_on = [
aws_iam_role.eks-iam-role,
]
}
## Worker Nodes
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"
})
}
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_eks_node_group" "worker-node-group" {
cluster_name = aws_eks_cluster.ruralx-eks.name
node_group_name = "ruralx-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 = 1
max_size = 1
min_size = 1
}
depends_on = [
aws_iam_role_policy_attachment.AmazonEKSWorkerNodePolicy,
aws_iam_role_policy_attachment.AmazonEKS_CNI_Policy,
#aws_iam_role_policy_attachment.AmazonEC2ContainerRegistryReadOnly,
]
}
variable "subnet_id_1" {
type = string
default = "subnet-05f2a43d392934382"
}
variable "subnet_id_2" {
type = string
default = "subnet-0086dd63b54f54812"
}
- Создайте кластер EKS, выполнив следующее:
terraform plan
— Пройти «проверку» и подтвердить правильность конфигураций.
Если вы хотите более подробно ознакомиться с terraform, вы можете начать здесь Нажмите на эту ссылку
4.0 Docker
Здесь мы планируем требования к приложению, кодируем, собираем и тестируем приложение.
Я предполагаю, что все эти этапы уже пройдены, так как команда DevOps не отвечает за них единолично, а скорее работает с более крупной командой как разработчиков, так и операторов организации.
Создание образа Docker для приложения ruralx
Цель этой работы — создать образ Docker из исходного кода приложения, который есть у организации, контейнеризировать его и сохранить контейнер в репозитории контейнеров. Здесь я буду использовать репо-контейнер AWS ECR.
- В корневом каталоге исходного кода приложения создайте
Dockerfile
. - Откройте Dockerfile, затем определите инструкцию, это зависит от базового образа и других параметров, вы можете рассматривать это как пример;
# syntax=docker/dockerfile:1
FROM node:10.16.1-alpine
ENV NODE_ENV=production
WORKDIR /app
COPY ["package.json", "package-lock.json*", "./"]
RUN npm install --production
COPY . .
CMD [ "npm", "start" ]
- Чтобы создать образ Docker, выполните следующую команду:
docker build -t ruralx:latest .
Тег -t означает тег (имя) образа Docker, а . говорит Docker CLI, что Dockerfile находится в текущем каталоге. - После создания образа Docker выполните следующую команду, чтобы убедиться, что образ Docker находится на вашей машине;
docker image ls
.
Запуск образа Docker локально
Теперь, когда образ Docker создан, вы можете запустить контейнер локально, чтобы убедиться, что он будет работать и не упадет.
- Чтобы запустить контейнер Docker, выполните следующую команду:
docker run -tid ruralx
. - Чтобы подтвердить, что контейнер Docker запущен, выполните следующую команду:
docker container ls
.
Войдите в репозиторий AWS ECR
Идея заключается в том, чтобы передать изображение в ECR
-
Войдите в ECR с помощью AWS CLI
-
Пометить образ Docker
Пометьте образ Dockerdocker tag ruralx 1XX9-6XXX-6XX7.dkr.ecr.us-east-1.amazonaws.com
. -
Передача образа Docker в ECR
Переместите образ Docker в ECRdocker push 1XX9-6XXX-6XX7.dkr.ecr.us-east-1.amazonaws.com/ruralx
.
В дополнение к документации Docker, нажмите здесь, чтобы найти еще один полезный ресурс от Нельсона (канал YouTube; Amigoscode).
Чтобы узнать больше, догоните меня во второй части!
Читайте >>>
Спасибо за прочтение! Счастливых облачных вычислений!
Буду рад пообщаться с вами на LinkedIn