Налаштування Kubernetes за допомогою Kops (Операції Kubernetes)

pic

архітектура проєкту

Код джерела: https://github.com/RyderGreystorm/kops_kubernetes.git

Kops (Kubernetes Operations) широко використовується в продуктивних середовищах, особливо для розгортання та управління Kubernetes-кластерами на AWS. Він надає спрощений автоматизований спосіб створення, оновлення та управління Kubernetes-кластерами з вбудованими найкращими практиками. Kops є популярним серед організацій, які хочуть мати більший контроль над своєю інфраструктурою Kubernetes, оскільки він дозволяє налаштування на кожному рівні — від мережі до типів інстансів та операційних систем. Оскільки Kops глибоко інтегрується з AWS-сервісами, такими як Route 53, EC2 та S3, він є відмінним вибором для команд, які вже працюють з AWS. Крім того, Kops підтримує налаштування кластерів HA (High Availability), що робить його підходящим для критичних додатків, які потребують стійкості та масштабованості.

Kops вибирають, коли команди потребують гнучкості та готові управляти Kubernetes на більш низькому рівні. Це особливо цінно для команд DevOps, які повинні налаштувати свою архітектуру Kubernetes відповідно до специфічних вимог безпеки, відповідності або мережевих налаштувань. У порівнянні з керованими Kubernetes-сервісами, такими як EKS або GKE, Kops надає більше можливостей для детального налаштування компонентів кластеру, але це також означає більше операційних витрат. Незважаючи на це, його надійність і економічність роблять його привабливим варіантом для компаній, які прагнуть уникнути прив'язки до керованих сервісів, одночасно підтримуючи Kubernetes-кластери рівня продакшн. Загалом, Kops вважається зрілим та надійним інструментом для управління Kubernetes-кластерами, особливо в середовищах, орієнтованих на AWS.

Перед тим як продовжити, переконайтеся, що ви зайшли на репозиторій і зробили його форк, щоб отримати копію коду джерела. Посилання на код джерела надано на початку цієї документації, але якщо ви його пропустили, ось воно знову: https://github.com/RyderGreystorm/kops_kubernetes.git

У цьому проєкті ми будемо розгортати Kubernetes-кластер за допомогою Kops. Код джерела містить конфігурацію Terraform, призначену для створення необхідної інфраструктури AWS. Ця конфігурація налаштує AWS Route 53, створить Virtual Private Cloud (VPC) і запустить інстанс EC2 з відповідними мережевими налаштуваннями для розгортання сервера адміністрування Kops.

Ми почнемо з реалізації інфраструктури як коду (IaC) за допомогою Terraform.
Модуль буде створений для визначення та налаштування VPC, EC2 інстансу та хостингової зони Route 53, забезпечуючи структурований і багаторазовий підхід до управління інфраструктурою.

terraform_iac/modules/vpc.tf

resource "aws_vpc" "kops-server" {  
 cidr_block = var.cidr  
 enable_dns_hostnames = true  
 enable_dns_support = true  

 tags = {  
 Name = "kops"  
 }  
}  


#Internet Gateway  
resource "aws_internet_gateway" "gw" {  
 vpc_id = aws_vpc.kops-server.id  

 tags = {  
 Name = "main"  
 }  

}  


#Public subnet  
resource "aws_subnet" "pub-sub" {  
 count = length(var.availability_zones)  
 vpc_id = aws_vpc.kops-server.id  
 cidr_block = element(var.pub-cidr, count.index)  
 availability_zone = element(var.availability_zones, count.index)  
 map_public_ip_on_launch = true  

 tags = {  
 Name = "pub-subnet${count.index}"  
 }  
}  


#Route Table  
resource "aws_route_table" "my-rt" {  
 vpc_id = aws_vpc.kops-server.id  

 route {  
 cidr_block = "0.0.0.0/0"  
 gateway_id = aws_internet_gateway.gw.id  
 }  

 tags = {  
 Name = "rt"  
 }  
}  

#Public Route table association  
resource "aws_route_table_association" "pub-rt-assoc" {  
 count = length(var.availability_zones)  
 subnet_id = aws_subnet.pub-sub[count.index].id  
 route_table_id = aws_route_table.my-rt.id  
}  

resource "aws_security_group" "kops-server-sg" {  
 name = "kops-server-sg"  
 description = "firewall for ec instance runnig kops"  

 vpc_id = aws_vpc.kops-server.id  

 ingress {  
 from_port = 22  
 to_port = 22  
 protocol = "tcp"  
 cidr_blocks = ["0.0.0.0/0"] #Use your trusted IP here, this is a security risk, don't allow it like this. It should be your IP Address  
 }  

 egress {  
 from_port = 0  
 to_port = 0  
 protocol = "-1"  
 cidr_blocks = ["0.0.0.0/0"]  
 }  

 tags = {  
 Name = "kops_Host"  
 }  
}

Далі ми створимо хостингову зону AWS Route 53, що є критично важливим компонентом для розгортання Kops. Хостингова зона служитиме внутрішнім DNS для Kubernetes кластера, забезпечуючи безперешкодне вирішення ресурсів та сервісів кластеру.

Налаштувавши спеціалізовану хостингову зону, Kops зможе ефективно керувати DNS записами кластера, забезпечуючи стабільну комунікацію між вузлами та сервісами. Цей підхід спрощує створення повністю кваліфікованих доменних імен (FQDN) для API сервера Kubernetes та інших компонентів кластера. Крім того, використання Route 53 дозволяє автоматично оновлювати DNS записи під час масштабування або змін конфігурації, підвищуючи стійкість кластера та спрощуючи його обслуговування.

Хостингова зона також відіграє важливу роль у забезпеченні безпеки внутрішньо-кластерної комунікації, гарантуючи, що DNS розв'язання залишатиметься в межах AWS середовища, знижуючи зовнішні залежності та підвищуючи продуктивність. Для цього вам знадобиться доменне ім’я. На godaddy.com можна придбати недорогі домени. Після покупки домену ви зможете створити хостингову зону. Ви можете використовувати префікс profile, як у мене profile.devopsfetish.xyz, але замінити URL на ваше доменне ім’я.

terraform_iac/modules/route53_hostedzone.tf

resource "aws_route53_zone" "profileapp" {  
 name = "profile.devopsfetish.xyz" # Replace with your desired domain name  
 comment = "Public hosted zone for devopsfetish.xyz"  

 tags = {  
 Environment = "dev"  
 Project = "profileapp"  
 }  
}  

# Output the name servers assigned to the hosted zone  
output "name_servers" {  
 value = aws_route53_zone.profileapp.name_servers  
}

Наступним кроком буде налаштування сервера адміністрування Kops, який буде відповідальний за управління та налаштування Kubernetes-кластера.
Для безпечного доступу та налаштування сервера необхідні пари SSH ключів.

Перед тим як продовжити, переконайтеся, що ви згенерували власні SSH ключі за допомогою команди:

ssh-keygen -t rsa -b 2048

Ця пара ключів буде використана для аутентифікації та підключення до EC2 інстансу, на якому розміщений сервер адміністрування Kops.

Важлива примітка з безпеки:
Я навмисно не завантажив свої SSH ключі на GitHub, оскільки це створює значний ризик для безпеки. Публікація приватних ключів може призвести до несанкціонованого доступу до вашої інфраструктури, що може викликати порушення або втрату контролю. Найкраща практика — зберігати ключі локально та уникати включення їх у систему контролю версій.

Після того, як пара ключів буде згенерована, ви можете продовжити налаштування EC2 інстансу та асоціювати ваш публічний ключ для безпечного доступу.

terraform_iac/modules/ec2.tf

data "aws_ami" "ubuntu" {  
 most_recent = true  

 filter {  
 name = "name"  
 values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]  
 }  

 filter {  
 name = "virtualization-type"  
 values = ["hvm"]  
 }  

 owners = ["099720109477"] # Canonical  
}  

resource "aws_key_pair" "mykey" {  
 key_name = "mykey"  
 public_key = file("../key_pair/mykey.pub")  
}  

resource "aws_instance" "web" {  
 ami = data.aws_ami.ubuntu.id  
 instance_type = var.instance-type  
 key_name = aws_key_pair.mykey.key_name  
 subnet_id = aws_subnet.pub-sub[0].id  
 vpc_security_group_ids = [aws_security_group.kops-server-sg.id]  

 root_block_device {  
 volume_size = var.volume-size  
 }  

 tags = {  
 Name = "kops-server"  
 }  
}

Тепер, ось файл змінних для модуля:

variable "cidr" {  
 description = "vpc cidr range"  
 type = string  
}  

variable "availability_zones" {  
 description = "availability zones to occupy"  
 type = list(string)  
}  

variable "pub-cidr" {  
 description = "cidr range for public subnets"  
 type = list(string)  
}  

variable "pub-key" {  
 type = string  
 description = "public key"  
}  

variable "priv-key" {  
 type = string  
 description = "private key for the instance"  
}  

variable "instance-type" {  
 type = string  
 description = "aws instance type"  
}  

variable "volume-size" {  
 description = "instance storage size"  
 type = number  
}

Це завершує налаштування модуля. Наступний крок — налаштування віддаленого керування станом для Terraform шляхом створення файлу backend.tf у кореневій директорії вашої конфігурації Terraform.

Налаштування віддаленого керування станом:

Створення S3 бакету:
Terraform вимагає наявності бекенду для зберігання своїх файлів стану. Для цього буде використано S3 бакет для безпечного зберігання та керування станом на відстані. Виконайте наступну команду для створення S3 бакету (переконайтеся, що ім’я бакету є унікальним у глобальному масштабі):

aws s3api create-bucket --bucket  --region 

Замість та вставте відповідні значення.

Увімкнення блокування стану за допомогою DynamoDB:
Для запобігання одночасного виконання Terraform та забезпечення цілісності стану, створіть таблицю DynamoDB для блокування стану:

aws dynamodb create-table \  
 --table-name  \  
 --attribute-definitions AttributeName=LockID,AttributeType=S \  
 --key-schema AttributeName=LockID,KeyType=HASH \  
 --billing-mode PAY_PER_REQUEST

Визначення змінних проєкту:
Після налаштування віддаленого бекенду стану, створіть файл terraform.tfvars, щоб визначити змінні, що стосуються конкретного проєкту. Цей файл міститиме значення для важливих конфігурацій, таких як CIDR VPC, типи інстансів EC2 та імена хостингових зон Route53.

Основна конфігурація:
У файлі main.tf посилайтесь на створений раніше Terraform модуль.
Передайте необхідні параметри, щоб модуль міг налаштувати необхідну інфраструктуру.

Організовуючи інфраструктуру таким чином, Terraform ефективно керуватиме ресурсами AWS, забезпечуючи масштабованість, безпеку та підтримуваність під час розгортання.

terraform_iac/backend.tf

provider "aws" {  
 region = var.REGION  
}  

terraform {  
 required_version = ">= 1.0"  
 required_providers {  
 aws = {  
 source = "Hashicorp/aws"  
 version = "~> 5.82.2"  
 }  
 }  
 backend "s3" {  
 bucket = "enter-your-s3-bucket-here"  
 key = "global/mystatefiles/terraform.tfstate"  
 region = "us-east-1"  
 dynamodb_table = "terraform-locks"  
 }  
}

terraform_iac/variables.tf

variable "cidr" {  
 description = "vpc cidr range"  
 type = string  
}  

variable "availability_zones" {  
 description = "availability zones to occupy"  
 type = list(string)  
}  

variable "pub-cidr" {  
 description = "cidr range for public subnets"  
 type = list(string)  
}  

variable "pub-key" {  
 type = string  
 description = "public key"  
}  

variable "priv-key" {  
 type = string  
 description = "private key for the instance"  
}  

variable "instance-type" {  
 type = string  
 description = "aws instance type"  
}  

variable "volume-size" {  
 description = "instance storage size"  
 type = number  
}  

variable "REGION" {  
 type = string  
 description = "AWS region"  
}

terraform_iac/terraform.tfvars

cidr = "10.0.0.0/16"  
availability_zones = ["us-east-1a", "us-east-1b"]  
pub-cidr = ["10.0.1.0/24", "10.0.2.0/24"]  
pub-key = "../key_pair/mykey.pub"  
priv-key = "../key_pair/mykey"  
instance-type = "t3.medium"  
volume-size = 25  
REGION = "us-east-1"

terraform_iac/main.tf

module "kops-server" {  
 source = "./modules"  
 cidr = var.cidr  
 availability_zones = var.availability_zones  
 pub-cidr = var.pub-cidr  
 pub-key = var.priv-key  
 priv-key = var.priv-key  
 instance-type = var.instance-type  
 volume-size = var.volume-size  
}  

# Вивести імена серверів із модуля  
output "route53_name_servers" {  
 value = module.kops-server.name_servers  
}

Ця конфігурація налаштує як сервер Kops, так і хостингову зону AWS Route 53. Після завершення налаштування буде згенеровано вихідний результат, який міститиме записи серверів імен (NS) з хостингової зони Route 53.

pic

Terraform створив сервер kops

Оскільки я використовую GoDaddy як постачальника доменних імен, мені потрібно вручну оновити записи серверів імен на сторінці керування DNS GoDaddy, щоб відобразити записи NS, надані Route 53. Цей крок важливий для забезпечення правильної DNS-резолюції для вашого Kubernetes кластера.

Нижче наведено скріншот записів серверів імен, які я ввів у GoDaddy для зв'язку хостингової зони з моїм доменом:

pic

Записи NS оновлені на GoDaddy

Завершивши цей крок, домен буде коректно пов'язаний з вашою хостинговою зоною Route 53, що забезпечить безперешкодну інтеграцію з кластером Kops.

Тепер створіть S3 бакет для вашого кластера, щоб зберігати та керувати його станом:

aws s3api create-bucket --bucket  --region 

Увійдіть на сервер і згенеруйте ssh ключі. Я назвав свої kops. Kops використовуватиме цей ключ під час створення вашого кластера. Також запустіть shell-скрипт kops_setup.sh, який знаходиться в кореневій директорії цього проєкту, щоб встановити всі необхідні інструменти: kubectl, aws_cli та kops.
Налаштуйте і конфігуруйте AWS з ключами доступу та секретними ключами в регіоні, де ви хочете розгорнути кластер.

pic

ssh ключ для kops

kops create cluster --name=profile.devopsfetish.xyz \  
--state=s3://bucket_name \  
--zones=us-east-1a,us-east-1b,us-east-1c \  
--node-count=2 \  
--node-size=t3.medium \  
--control-plane-size=t3.medium \  
--dns-zone=profile.devopsfetish.xyz \  
--node-volume-size=25 \  
--control-plane-volume-size=25 \  
--ssh-public-key=~/.ssh/

Замініть devopsfetish.xyz на власну URL-адресу домену, а також переконайтесь, що вказали правильне ім’я S3 бакету, який ви створили, а також свій публічний SSH ключ. Після цих оновлень запустіть конфігурацію Terraform.

Якщо процес пройде успішно і не буде виявлено помилок, майте на увазі, що для повної готовності Kubernetes кластера може знадобитися приблизно 10-15 хвилин. Під час цього часу будуть розгорнуті ресурси, а кластер буде налаштований. Після розгортання ви побачите ваш контрольний план і кількість вказаних вузлів, а ваша хостингова зона міститиме записи про точку доступу API Kubernetes і інші необхідні DNS ресурси. Kops також встановить ваш контекст на контрольний план.

Використовуйте наступну команду, щоб отримати список вузлів:

kubectl get nodes

pic

pic

Розгортання манифестів і контролера NGINX Ingress на AWS для балансування навантаження в Kubernetes

Щоб розпочати процес розгортання, необхідно налаштувати контролер NGINX Ingress, який автоматизує створення та управління AWS Load Balancer для обробки зовнішнього трафіку для нашого Kubernetes кластера.

Крок 1: Розгортання контролера NGINX Ingress

Запустіть наступну команду для розгортання контролера NGINX Ingress:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.11.3/deploy/static/provider/aws/deploy.yaml

pic

Балансувальник навантаження, наданий контролером

pic

балансувальник навантаження

Крок 2: Перевірка розгортання та створення ресурсів

Ця команда створює кілька ресурсів у кластері. Основні компоненти включають:

  • Namespace (простір імен): Створюється новий простір імен ingress-nginx для ізоляції та управління всіма ресурсами, пов'язаними з контролером Ingress.
  • Pods: Кілька pod (контейнерів) будуть працювати в просторі імен ingress-nginx. Ці pod відповідають за управління контролером Ingress, обробку трафіку та автоматичне створення AWS Load Balancer.

Крок 3: Перевірка створення Load Balancer

Після успішного застосування конфігурації, перевірте розгортання, перевіривши консоль керування AWS:

  • Перейдіть до EC2Load Balancers.
  • Має з'явитись новий Load Balancer, створений контролером NGINX Ingress.

Цей Load Balancer буде маршрутизувати зовнішній трафік до сервісів у вашому Kubernetes кластері, забезпечуючи ефективне управління вхідними запитами та високу доступність. Цей крок є важливим, і якщо його не виконати належним чином, ваш додаток може бути недоступним в Інтернеті.

Тепер давайте почнемо з налаштування інфраструктури бекенду.

Інфраструктура бекенду складається з трьох основних компонентів:

  1. MySQL база даних — основне сховище даних.
  2. Memcached — для кешування запитів до бази даних і покращення продуктивності.
  3. RabbitMQ — брокер повідомлень для управління комунікацією між сервісами.

Постійне сховище для бази даних

Щоб забезпечити збереження даних і високу доступність, базі даних MySQL потрібен Persistent Volume Claim (PVC).
PVC запитуватиме ресурси для зберігання з Storage Class (SC), який взаємодіє з AWS Elastic Block Store (EBS). Така конфігурація дозволяє динамічно створювати томи бази даних. Використовуючи EBS, том може бути від'єднаний від одного pod (контейнера) і підключений до іншого у разі збою pod, що забезпечить мінімальний час простою та збереження даних. Хороша новина в тому, що kops за замовчуванням створює Storage Class, коли він ініціалізується, тому нам не потрібно створювати його вручну — достатньо просто створити PVC.

Управління обліковими даними

Як MySQL, так і RabbitMQ потребують безпечного зберігання чутливих облікових даних, таких як паролі. Зберігання паролів у вигляді відкритого тексту не рекомендується через ризики безпеки. Натомість:

  • Паролі будуть зашифровані або закодовані в base64.
  • Потім вони будуть безпечно збережені в Kubernetes Secrets (наприклад, secrets.yml).
  • Такий підхід підвищує рівень безпеки, мінімізуючи ризик витоку чутливої інформації в конфігураційних файлах.

backend_manifests/secret.yml
Щоб отримати паролі для бази даних і rabbitMQ, перейдіть до src/main/resources/application.properties, який містить секрети бази даних. Потім закодуйте їх у base64 і додайте як дані у вашому файлі secrets.yml.

Також зверніть увагу, що в розгортаннях, після вказання порту, на якому повинні бути доступні контейнери, я додав ім'я порту і використав це ім'я в сервісах як цільовий порт. Це дуже важливо для зручності управління системою. Якщо в майбутньому ми змінимо порти, достатньо буде оновити розгортання, і зміни набудуть чинності в сервісах.

echo -n "the-password" | base64
apiVersion: v1  
kind: Secret  
metadata:  
 name: app-secret  
type: opaque  
data:  
 db-password: dnByb2RicGFzcw==  
 rabbit-mq: Z3Vlc3Q=  
 rmq_user: Z3Vlc3Q=

backendmanifests/dbpvc.yml

apiVersion: v1  
kind: PersistentVolumeClaim  
metadata:  
 name: db-pvc  
 labels:  
 app: vprodb  
spec:  
 accessModes:  
 - ReadWriteOnce  
 resources:  
 requests:  
 storage: 8Gi  
 storageClassName: default

backendmanifests/dbdeployment.yml

apiVersion: apps/v1  
kind: Deployment  
metadata:  
 name: db-deployment  
 labels:  
 app: vprodb  
spec:  
 replicas: 1  
 selector:  
 matchLabels:  
 app: vprodb  
 template:  
 metadata:  
 labels:  
 app: vprodb  
 spec:  
 containers:  
 - name: vprofile  
 image: vprocontainers/vprofiledb  
 ports:  
 - containerPort: 3306  
 name: dbport  
 env:  
 - name: MYSQL_PASSWORD  
 valueFrom:  
 secretKeyRef:  
 name: app-secret  
 key: db-password  
 volumeMounts:  
 - mountPath: /var/lib/mysql  
 name: db-storage  
 livenessProbe:  
 exec:  
 command:  
 - mysqladmin  
 - ping  
 - "-h"  
 - "localhost"  
 initialDelaySeconds: 30  
 periodSeconds: 10  
 readinessProbe:  
 exec:  
 command:  
 - sh  
 - "-c"  
 - "mysql -uroot -p$MYSQL_PASSWORD -e 'SELECT 1'"  
 initialDelaySeconds: 20  
 periodSeconds: 10  
 resources:  
 limits:  
 cpu: "500m"  
 memory: "512Mi"  
 requests:  
 cpu: "250m"  
 memory: "256Mi"  
 volumes:  
 - name: db-storage  
 persistentVolumeClaim:  
 claimName: db-pvc  
 initContainers:  
 - name: busybox  
 image: busybox:latest  
 args: ["rm", "-rf", "/var/lib/mysql/lost+found"]  
 volumeMounts:  
 - name: db-storage  
 mountPath: /var/lib/mysql

Після того, як розгортання бази даних буде підготовлене, створимо для нього сервіс:
backendmanifests/dbdeployment.yml

apiVersion: v1  
kind: Service  
metadata:  
 name: vprodb  
spec:  
 selector:  
 app: vprodb  
 ports:  
 - protocol: TCP  
 port: 3306  
 targetPort: dbport  
 type: ClusterIP

backendmanifests/memcachedeploy.yml
Тепер налаштовуємо розгортання Memcached з 3-ма репліками.
Ми керуємо ресурсами для pod (контейнерів), створених цим розгортанням.

apiVersion: apps/v1  
kind: Deployment  
metadata:  
 name: mc-deployment  
 labels:  
 app: mc  
spec:  
 replicas: 3  
 selector:  
 matchLabels:  
 app: mc  
 template:  
 metadata:  
 labels:  
 app: mc  
 spec:  
 containers:  
 - name: memcached  
 image: memcached:latest  
 ports:  
 - containerPort: 11211  
 name: mcport  
 resources:  
 limits:  
 cpu: "500m"  
 memory: "512Mi"  
 requests:  
 cpu: "250m"  
 memory: "256Mi"  
 livenessProbe:  
 tcpSocket:  
 port: 11211  
 initialDelaySeconds: 30  
 periodSeconds: 10  
 readinessProbe:  
 tcpSocket:  
 port: 11211  
 initialDelaySeconds: 10  
 periodSeconds: 5

backendmanifests/memcachesvc.yml

Тепер ми створимо сервіс типу clusterIP для цього розгортання.

apiVersion: v1  
kind: Service  
metadata:  
 name: vprocache01  
spec:  
 selector:  
 app: mc  
 ports:  
 - protocol: TCP  
 port: 11211  
 targetPort: mcport  
 type: ClusterIP

backendmanifests/rmqdeploy.yml

apiVersion: apps/v1  
kind: Deployment  
metadata:  
 name: rmq-deployment  
 labels:  
 app: rmq  
spec:  
 replicas: 3  
 selector:  
 matchLabels:  
 app: rmq  
 template:  
 metadata:  
 labels:  
 app: rmq  
 spec:  
 containers:  
 - name: rmq  
 image: rabbitmq:latest  
 ports:  
 - containerPort: 5672  
 name: rmqport  
 env:  
 - name: RMQ_PASSWORD  
 valueFrom:  
 secretKeyRef:  
 name: app-secret  
 key: rabbit-mq  
 - name: RMQ_USER  
 valueFrom:  
 secretKeyRef:  
 name: app-secret  
 key: rmq_user  
 resources:  
 limits:  
 cpu: "500m"  
 memory: "512Mi"  
 requests:  
 cpu: "250m"  
 memory: "256Mi"  
 livenessProbe:  
 tcpSocket:  
 port: 5672  
 initialDelaySeconds: 30  
 periodSeconds: 10  
 readinessProbe:  
 tcpSocket:  
 port: 5672  
 initialDelaySeconds: 10  
 periodSeconds: 5

backendmanifests/rmqsvc.yml

apiVersion: v1  
kind: Service  
metadata:  
 name: vpromq01  
spec:  
 selector:  
 app: rmq  
 ports:  
 - protocol: TCP  
 port: 5672  
 targetPort: rmqport  
 type: ClusterIP

Це завершить налаштування бекенду.
Приготуємо файли маніфестів для фронтенду.

frontend/tomcat_deploy.yml

apiVersion: apps/v1  
kind: Deployment  
metadata:  
 name: myappdeployment  
 labels:  
 app: myapp  
spec:  
 replicas: 3  
 selector:  
 matchLabels:  
 app: myapp  
 template:  
 metadata:  
 labels:  
 app: myapp  
 spec:  
 containers:  
 - name: vprofileapp  
 image: vprocontainers/vprofileapp  
 imagePullPolicy: Always  
 ports:  
 - containerPort: 8080  
 name: myappport  
 resources:  
 limits:  
 cpu: "500m"  
 memory: "2Gi"  
 requests:  
 cpu: "250m"  
 memory: "256Mi"  
 livenessProbe:  
 tcpSocket:  
 port: 8080  
 initialDelaySeconds: 30  
 periodSeconds: 10  
 readinessProbe:  
 tcpSocket:  
 port: 8080  
 initialDelaySeconds: 10  
 periodSeconds: 5  

 initContainers:  
 - name: init-rmq  
 image: busybox:1.28  
 command: ['sh', '-c', "until nslookup vpromq01.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]  

 - name: init-mydb  
 image: busybox:1.28  
 command: ['sh', '-c', "until nslookup vprodb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]  

 - name: init-memcache  
 image: busybox:1.28  
 command: ['sh', '-c', "until nslookup vprocache01.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mycache; sleep 2; done"]  
 resources:  
 limits:  
 cpu: "500m"  
 memory: "2Gi"  
 requests:  
 cpu: "250m"  
 memory: "256Mi"

frontend/tomcat_svc.yml

apiVersion: v1  
kind: Service  
metadata:  
 name: vproapp  
spec:  
 selector:  
 app: myapp  
 ports:  
 - protocol: TCP  
 port: 8080  
 targetPort: myappport  
 type: ClusterIP

Коли файли розгортання та сервісу будуть готові, нам знадобиться файл ingress.yml, який визначає, як трафік має маршрутизуватися з зовнішнього світу до pod (контейнерів).

ingress.yml

apiVersion: networking.k8s.io/v1  
kind: Ingress  
metadata:  
 name: app-ingress  
 annotations:  
 nginx.ingress.kubernetes.io/rewrite-target: /  
spec:  
 ingressClassName: nginx  
 rules:  
 - host: profileapp.devopsfetish.xyz  
 http:  
 paths:  
 - path: /  
 pathType: Prefix  
 backend:  
 service:  
 name: vproapp  
 port:  
 number: 8080

Частина host під правилами дуже важлива, оскільки нам потрібно буде додати її як запис CNAME в Godaddy, щоб наша програма могла бути знайдена. Перейдіть на Godaddy, під вашим доменом зайдіть в DNS і додайте запис типу CNAME, де ім'я буде префіксом з цього хоста, у моєму випадку це «profileapp». Значення буде DNS нашого балансувальника навантаження, який був створений контролером nginx. Але перед цим давайте розгорнемо pod (контейнери).

Для бекенду перейдіть в каталог бекенду і виконайте команду

kubectl apply -f db_pvc.yml

Це розгорне Persistent Volume Claim (PVC), і щоб перевірити, чи працює все правильно, перейдіть до сервісу EC2, потім до розділу volumes, ви побачите новий том, доступний, але ще не використовується.

pic

Для фронтенду перейдіть в каталог фронтенду і виконайте команду

kubectl apply -f .

Коли це буде зроблено, перейдіть до кореневої директорії, де знаходиться ingress.yml, і виконайте команду

kubectl apply -f ingress.yml

Почекайте деякий час і виконайте наступні команди для перевірки розгортань, сервісів і ingress:

kubectl get deploy  
kubectl get svc  
kubectl get ingress

pic

ресурси

Давайте перевіримо, чи все підключено правильно. Виконайте:

kubectl describe pod 

Скопіюйте IP-адресу, яку присвоєно pod, і збережіть її де-небудь.
Тепер опишемо сервіс бази даних і перевіримо IP-адресу, яка була призначена для кінцевої точки портів. Вона має співпасти.

pic

pic

Перевірте, чи вдалося базі даних отримати EBS том, який було створено.

kubectl get pvc

pic

успішно отримано PVC для бази даних

pic

Консоль AWS показує, що EBS том був отриманий і використовується

Ви також можете перевірити клас зберігання (storage class), який створив для нас EBS.

kubectl get sc

pic

клас зберігання має значення "default" в дужках

Відкриємо застосунок для світу

Давайте отримаємо DNS балансувальника навантаження та перейдемо на godaddy.com, щоб додати його як запис CNAME.

kubectl get ingress

pic

Наш DNS балансувальника навантаження

Альтернативно, ви можете скопіювати його з консолі UI.

Після цього ви зможете відвідати застосунок у браузері, використовуючи ваше URL; у моєму випадку це profileapp.devopsfetish.com.

pic

pic

pic

pic

pic

Доступ до вебсайту

Остаточно:

Щасливого кодування та продовжуйте робити важкі речі! Якщо виникли проблеми під час реалізації цього проєкту, будь ласка, звертайтеся до мене через GitHub, електронну пошту або зв'язуйтесь через мій дуже активний профіль на LinkedIn:

Електронна пошта: [email protected]
LinkedIn: https://www.linkedin.com/in/godbless-biekro-2289261ba/
GitHub: RyderGreystorm (Godbless Biekro)

Перекладено з: Kubernetes with Kops (Kubernetes Operation) Set up

Leave a Reply

Your email address will not be published. Required fields are marked *