====== Выполнение домашнего задания для DevOps-тренировок в Яндексе, лекция "Облако. Кто виноват и что делать." ======
Описание задания и все ссылки есть у меня в репозитории на [[https://github.com/igkfellk/y-y-devops-trainings-cloud-1 | github]]
Для начала нужно создать две виртуальные машины на Яндекс облаке и клонировать себе в каждую машину репозиторий с гитхаба.
В рамках проекта тренировок предоставляется возможность бесплатно использовать виртуальные машины по запросу.
Машины созданы
{{:devops_training_in_yandex:pasted:20231108-110516.png?nolink}}
Подключаемся удобным способом к ним по SSH, я использую Windows Terminal.
Клонируем репозиторий
git clone https://github.com/igkfellk/y-y-devops-trainings-cloud-1/
===== Сборка образа для catGPT =====
Создаем каталог
sudo mkdir /etc/docker/catGPT
Копируем нужные файлы в созданный каталог
sudo cp -r /home/ikfellk/y-y-devops-trainings-cloud-1/catgpt/. /etc/docker/catGPT/
Переходим в каталог
cd /etc/docker/catGPT
Создаем Dockerfile
sudo nano Dockerfile
# Используем образ Golang рекомендуемый в задании
FROM golang:1.21 AS builder
# Указываем автора файла
MAINTAINER Igor Kucherenko
# Устанавливаем и переходим в рабочую директорию
WORKDIR /go/src/app
# Копируем go.mod и go.sum для загрузки зависимостей
COPY go.mod go.sum ./
# Загружаем зависимости
RUN go mod download
# Копируем исходный код приложения
COPY . .
# Собираем приложение
RUN CGO_ENABLED=0 go build -o /go/bin/app
RUN chmod +x /go/bin/app
# Создаем runtime образ на основе gcr.io/distroless/static-debian12:latest-amd64
FROM gcr.io/distroless/static-debian12:latest-amd64
# Копируем собранный бинарный файл из builder образа
COPY --from=builder /go/bin/app /go/bin/app
# Определяем команду, которая будет запускаться при запуске контейнера
CMD ["/go/bin/app"]
Запуск сборки
sudo docker build -t ikfellk/catgpt:v1 .
Запуск контейнера
docker run -d -p 8080:8080 ikfellk/catgpt:v1
===== Тестируем =====
Для проверки созданных образов выполняем команду
docker images
и получаем подобный вывод
{{:devops_training_in_yandex:pasted:20231109-101151.png?nolink}}
Для проверки созданных контейнеров выполняем команду
docker ps -a
и получаем подобный вывод
{{:devops_training_in_yandex:pasted:20231109-101216.png?nolink}}
идем в браузер и открываем страницу
http://ваш_ip:8080/
Получаем такой вывод
{{:devops_training_in_yandex:pasted:20231109-101621.png?nolink}}
===== Коннектимся к яндекс облаку через Oauth =====
Для полноценного выполнения задания еще потребуется настроить связь через oauth яндекса с яндекс облаком.
Тут ничего сложного, нужно получить токен через свой аккаунт яндекса перейдя по [[https://oauth.yandex.ru/authorize?response_type=token&client_id=1a6990aa636648e9b2ef855fa7bec2fb | ссылке]]
Далее в ранее созданной виртуальной машине или машинах выполнить подключение в несколько этапов:
* Скачать и установить яндекс CLI
curl -sSL https://storage.yandexcloud.net/yandexcloud-yc/install.sh | bash
* Выполнить настройку подключения через созданный токен
yc init
{{:devops_training_in_yandex:pasted:20231109-085652.png?nolink}}
===== Создаем реестр =====
Выполнив одну команду, получаем созданный реестр
yc container registry create --name registry-ikfellk
{{:devops_training_in_yandex:pasted:20231109-090316.png?nolink}}
Где:
* **registry-ikfellk** - любое имя на ваше усмотрение
===== Загружаем образ в реестр =====
Для начала смотрим на образы
docker images
{{:devops_training_in_yandex:pasted:20231109-105519.png?nolink}}
Выбираем нужный нам образ для загрузки и присваиваем тег яндекса
docker tag ikfellk/catgpt:v1 \
cr.yandex/crp3b70qbcrknbg22qbk/ikfellkcatgpt:v1
Где:
* **crp3b70qbcrknbg22qbk** - идентификатор вашего реестра на яндекс облаке
Загружаем образ в реестр
docker push cr.yandex/crp3b70qbcrknbg22qbk/ikfellkcatgpt:v1
Проверяем что образ загрузился командой
yc container image list
И получаем такую картину
{{:devops_training_in_yandex:pasted:20231109-105432.png?nolink}}
===== Автосборка с помощью Github CI и отправка в Яндекс облако =====
Для начала нужно создать ключи доступа к яндекс облаку из Github
yc iam access-key create --service-account-name ikfellk
Где:
* **ikfellk** - имя вашего аккаунта в яндекс облаке
Получаем такой вывод
{{:devops_training_in_yandex:pasted:20231109-152827.png?nolink}}
Создаем токен авторизации
yc iam create-token
{{:devops_training_in_yandex:pasted:20231110-111730.png?nolink}}
Создаем в репозитории на гитхабе файл
.github/workflows/docker-build-catgpt.yml
name: Docker Build and Deploy catgpt
on:
push:
tags:
- '*' # Любой тег
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Login to Yandex
run: docker login -u ${{ secrets.YANDEX_USERNAME }} -p ${{ secrets.YANDEX_CLOUD_SERVICE_ACCOUNT_KEY }} cr.yandex/crj3b74hbhretbg25qbk
- name: Build and push Docker image
run: |
docker build -t cr.yandex/crj3b74hbhretbg25qbk/catgpt:v1 ./catgpt
docker push cr.yandex/crj3b74hbhretbg25qbk/catgpt:v1
Где:
* **YANDEX_USERNAME** - логин от яндекс облака
* **YANDEX_CLOUD_SERVICE_ACCOUNT_KEY** - Токен авторизации созданный ранее
* **crj3b74hbhretbg25qbk** - Идентификатор вашего реестра на яндекс облаке
Создаем секреты описанные в предыдущем шаге
для создания вы должны находится в своем репозитории и нажать кнопку **Settings**
{{:devops_training_in_yandex:pasted:20231110-122951.png?nolink}}
Далее перейти в **Secrets and variables** и далее в **Actions**
{{:devops_training_in_yandex:pasted:20231110-123059.png?nolink}}
Теперь создаем секреты для авторизации
Нужно нажать **New repository secret**
Ввести названия что упоминались выше или можете посмотреть свой файл **docker-build-catgpt.yml** и там найти строки с секретами и изменить на ваши названия, которые вы создали
{{:devops_training_in_yandex:pasted:20231110-123202.png?nolink}}
Важное напоминание
У вас должен лежать Dockerfile в каталоге, который использует команда docker build.
В случае данного задания у меня лежит файл в каталоге **./catgpt**
===== Тестируем автосборку и отправку в Яндекс облако =====
В консоли переходим в каталог клонированной ветки репозитория гитхаба
cd y-y-devops-trainings-cloud-1/
Выполняем команды
git pull
git tag -a v1.2.4 -m "Тест автосборки"
git push origin v1.2.4
Вводим логин и пароль от гитхаба и получаем такой вывод
{{:devops_training_in_yandex:pasted:20231110-124248.png?nolink}}
Переходим в браузере в данный репозиторий во складку **Actions**
И видим что процесс автосборки пошел
{{:devops_training_in_yandex:pasted:20231110-124422.png?nolink}}
Буквально через несколько минут там же вы увидите такую картину
Процесс сборки завершился успешно
{{:devops_training_in_yandex:pasted:20231110-124517.png?nolink}}
Теперь переходим в свое яндекс облако и проверяем действительно ли там появился образ
Вуаля и он действительно там
{{:devops_training_in_yandex:pasted:20231110-124617.png?nolink}}
===== Автосборка с помощью Github CI и отправка в Docker Hub =====
Для начала нужно создать токен авторизации на docker hub:
* Переходим на [[https://hub.docker.com/ | сайт]]
* Логинимся под своей учеткой
* Переходим в **Account Settings**
* Далее **Security**
* Нажимаем **New Access Token**
* Даем ему имя и права
* Получаем готовый токен
{{:devops_training_in_yandex:pasted:20231110-125344.png?nolink}}
Токен копируем и не теряем, он пригодится для создания секретов на гитхабе
Создаем в репозитории на гитхабе файл
.github/workflows/docker-publish.yml
name: Publish Docker image
on:
push:
tags:
- '*' # Любой тег
jobs:
push_to_registry:
name: Push Docker image to Docker Hub
runs-on: ubuntu-latest
steps:
- name: Check out the repo
uses: actions/checkout@v4
- name: Log in to Docker Hub
uses: docker/login-action@f4ef78c080cd8ba55a85445d5b36e214a81df20a
with:
username: ${{ secrets.USERNAME }}
password: ${{ secrets.PASSWORD }}
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ikfellk/catgpt
- name: Build and push Docker image
uses: docker/build-push-action@3b5e8027fcad23fda98b2e3ac259d8d67585f671
with:
context: ./catgpt
file: ./Dockerfile
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Где:
* **USERNAME** - логин от docker hub
* **PASSWORD** - Токен авторизации созданный ранее
Создаем секреты описанные в предыдущем шаге
для создания вы должны находится в своем репозитории и нажать кнопку **Settings**
{{:devops_training_in_yandex:pasted:20231110-122951.png?nolink}}
Далее перейти в **Secrets and variables** и далее в **Actions**
{{:devops_training_in_yandex:pasted:20231110-123059.png?nolink}}
Теперь создаем секреты для авторизации
Нужно нажать **New repository secret**
Ввести названия что упоминались выше или можете посмотреть свой файл **docker-publish.yml** и там найти строки с секретами и изменить на ваши названия, которые вы создали
{{:devops_training_in_yandex:pasted:20231110-123202.png?nolink}}
Важное напоминание
У вас должен лежать Dockerfile в корневом каталоге
===== Тестируем автосборку и отправку в Docker Hub =====
В консоли переходим в каталог клонированной ветки репозитория гитхаба
cd y-y-devops-trainings-cloud-1/
Выполняем команды
git pull
git tag -a v1.2.4 -m "Тест автосборки"
git push origin v1.2.4
Получаем выполненный процесс как и в предыдущем тестировании
Переходим в свой репозиторий на **Docker hub** и убеждаемся что файлы попали туда
{{:devops_training_in_yandex:pasted:20231110-130712.png?nolink}}
===== Разворачиваем инфраструктуру с помощью Terraform =====
==== Установка ====
Для начала нужно установить Terraform, а т.к. мы в России, то делать будем это через репозиторий яндекса
Заходим на сайт **https://hashicorp-releases.yandexcloud.net/terraform/** и копируем ссылку последней версии
Выполняем команды:
Скачать архив
wget https://hashicorp-releases.yandexcloud.net/terraform/1.6.3/terraform_1.6.3_linux_amd64.zip
Распаковать архив
unzip terraform_1.6.3_linux_amd64.zip
Переместить файл
sudo mv terraform /usr/local/bin
==== Проверка работы Terraform ====
Переходим в заранее клонированный репозиторий с github в папку terraform
И выполняем команду
terraform init
Если получаете ошибку такого рода
{{:devops_training_in_yandex:pasted:20231113-103023.png?nolink}}
То нужно выполнить следующее:
Создать файл
nano ~/.terraformrc
provider_installation {
network_mirror {
url = "https://terraform-mirror.yandexcloud.net/"
include = ["registry.terraform.io/*/*"]
}
direct {
exclude = ["registry.terraform.io/*/*"]
}
}
После этого пробуем еще раз команду
terraform init
И получаем положительный результат
{{:devops_training_in_yandex:pasted:20231113-103308.png?nolink}}
==== Запуск ====
У вас заранее должны быть созданы два сервисных аккаунта в яндекс облаке с нужными правами, описанными в **main.tf**
Для начала нужно выполнить команду
terraform plan
Данная команда покажет ошибки в вашем main.tf если таковы имеются.
В моем случае ошибки есть и их нужно исправить
{{:devops_training_in_yandex:pasted:20231113-103833.png?nolink}}
=== Разбор ошибок и устранение ===
1) Ошибка в названии регистра
Error: Reference to undeclared resource
on output.tf line 2, in output "container_registry_id":
2: value = yandex_container_registry.registry1.id
A managed resource "yandex_container_registry" "registry1" has not been declared in the root module.
Тут все просто, в файле **output.tf** не верно указано название регистра **registry1**
В моем случае оно называется **ikfellk-registry** Просто меняю на корректное название и ошибка уходит
2) Отсутствует json файл с данными
Error: Invalid SA Key
with provider["registry.terraform.io/yandex-cloud/yandex"],
on main.tf line 11, in provider "yandex":
11: service_account_key_file = "./tf_key.json"
JSON in "./tf_key.json" are not valid: invalid character '.' looking for beginning of value
Error: JSON in "./tf_key.json" are not valid: invalid character '.' looking for beginning of value
with provider["registry.terraform.io/yandex-cloud/yandex"],
on main.tf line 11, in provider "yandex":
11: service_account_key_file = "./tf_key.json"
Для решения нужно сгенерировать json файл с данными для входа
Мы это уже делали ранее [[https://wiki.fellk.ru/doku.php/devops_training_in_yandex/devops-trainings-cloud-1#avtosborka_s_pomoschju_github_ci_i_otpravka_v_jandeks_oblako | тут]]
Теперь выполняем команду
terraform plan
Видим что ошибки ушли, но появилась еще одна
{{:devops_training_in_yandex:pasted:20231113-113611.png?nolink}}
3) Отсутствует SSH ключ для авторизации
Error: Invalid function argument
on main.tf line 119, in resource "yandex_compute_instance_group" "catgpt":
119: ssh-keys = "ubuntu:${file("~/.ssh/devops_training.pub")}"
while calling file(path)
Invalid value for "path" parameter: no file exists at "~/.ssh/devops_training.pub"; this function works
only with files that are distributed as part of the configuration source code, so if this file will be
created by a resource in this configuration you must instead obtain this result from an attribute of that
resource.
Для решения нужно сгенерировать SSH ключ
ssh-keygen -t rsa
Указываем путь и название как в ошибке **/root/.ssh/devops_training**
Вводим пароль
Проверяем полученные сертификаты
~/.ssh/
{{:devops_training_in_yandex:pasted:20231113-114723.png?nolink}}
Теперь выполняем команду
terraform plan
И получаем полностью корректный план.
Небольшой пример как это выглядит
{{:devops_training_in_yandex:pasted:20231113-123824.png?nolink}}
После этого можно запускать команду, которая настроит все необходимые ресурсы в автоматическом режиме
terraform apply
В конце, как отработает команда, вы получите такой вывод
{{:devops_training_in_yandex:pasted:20231113-132702.png?nolink}}
===== Тестируем отработанный Terraform =====
Переходим в свой личный кабинет яндекс облака и смотрим что там появились машины, сети, балансировщик и регистр
{{:devops_training_in_yandex:pasted:20231113-133032.png?nolink}}
Теперь нужно загрузить актуальную версию приложения в контейнер
Для этого выполняем уже знакомые нам команды
git pull
git tag -a v1.2.5 -m "Тест автосборки"
git push origin v1.2.5
Вводим логин и пароль от гитхаба
Спустя примерно минуту или полторы, смотрим в личный кабинет яндекс облака и видим там контейнер
{{:devops_training_in_yandex:pasted:20231113-141414.png?nolink}}
Теперь переходим в веб браузер по ip адресам виртуальный машин созданный нашим terraform файлом
и видим там рабочее приложение и метрики
{{:devops_training_in_yandex:pasted:20231113-141532.png}}
{{:devops_training_in_yandex:pasted:20231113-141625.png}}
{{:devops_training_in_yandex:pasted:20231113-141549.png}}
{{:devops_training_in_yandex:pasted:20231113-141641.png}}
Для проверки балансировки нужно отключить одну виртуальную машину и со второй ничего не должно произойти и приложение так же останется в рабочем состоянии
Все работает как нужно.
Делаем удаление всех ресурсов
terraform destroy
Задание выполнено.