173 lines
9.2 KiB
Markdown
173 lines
9.2 KiB
Markdown
|
||
# Тестовое задание SimbirSoft DevOps
|
||
|
||
>[!NOTE]
|
||
>Соловьев Руслан
|
||
>
|
||
>Резюме - [HH](https://krasnodar.hh.ru/resume/b105319cff0f77ed050039ed1f5a4a4a733148)
|
||
>
|
||
>Узнать поднобнее - https://ruslansoloviev.ru
|
||
|
||
|
||
## Почему хочу девопсить
|
||
|
||
Мне нравится DevOps за сочетание разработки и системного администрирования. Мне интересно не только написать приложение, но и разобраться, как оно будет развёрнуто, как автоматизировать этот процесс, обеспечить его стабильную работу и понять, что происходит с сервисом после его запуска.
|
||
|
||
Именно поэтому со временем я стал больше заниматься инфраструктурной частью своих проектов: Docker, CI/CD, Kubernetes, мониторингом, сетями и автоматизацией. Особенно нравится автоматизировать повторяющиеся процессы и превращать ручную настройку в воспроизводимую конфигурацию.
|
||
|
||
В дальнейшем я хочу развиваться именно как DevOps-инженер, работать с более крупной инфраструктурой и задачами, где требования к надёжности, автоматизации и наблюдаемости значительно выше, чем в моих текущих проектах.
|
||
|
||
## Теоретическая часть
|
||
|
||
1) Нужно обеспечить высокую доступность сервиса, как бы ее реализовал?
|
||
<br>
|
||
- Так как у нас технически в данном задании nginx раздает только статику я бы вообще убрал сервер как точку отказа и вынес статическую страницу в объектное хранилище S3 и подключил CDN, таким образом высокая доступность будет обеспечена силами облачного провайдера, а CDN ускорит доставку контента до пользователей и сократит затраты на GET операции в хранилище.
|
||
- Если же необходимо реализовать высокую доступность именно посредством серверов, то я бы поднял как минимум 2 экземпляра на разных ВМ в разных зонах доступности и повесил на них балансировщик с хелс чеками доступности каждой из ВМ что бы не слать трафик на заведомо мертвую ВМ, 2 AZ поскольку этого будет достаточно в большинстве случаем да и самому nginx не нужен кворум для работы
|
||
<br>
|
||
|
||
2) Тебе надо создать и настроить 5 таких серверов, как бы это реализовал?
|
||
<br>
|
||
|
||
- Так как я описал необходимое состояние ВМ в ansible плейбук то для настройки будет достаточно указать все ВМ в инвентаре плейбука, а для заказа смотря как управляется текущая инфраструктура - если там терраформ или что то похожее то в конфигурации описал бы необходимые 5 экземпляров, если ручками то заказываю в гипервизоре или панели клауд провайдера
|
||
|
||
## Практическая часть
|
||
|
||
В данном тестовом задании я использовал Ansible и для его воспроизводимости понадобятся сам Ansible и некоторые его коллекции, установить которые можно следующими командами:
|
||
<br>
|
||
|
||
**Debian/Ubuntu**
|
||
```sh
|
||
sudo apt update && sudo apt install -y ansible
|
||
```
|
||
|
||
**macOS**
|
||
```sh
|
||
brew install ansible
|
||
```
|
||
|
||
**Через pip**
|
||
```sh
|
||
python3 -m pip install ansible
|
||
```
|
||
|
||
```sh
|
||
ansible-galaxy collection install community.general
|
||
ansible-galaxy collection install community.crypto
|
||
ansible-galaxy collection install community.docker
|
||
ansible-galaxy collection install ansible.posix
|
||
```
|
||
|
||
В файле *hosts.yaml* необходимо указать адрес ВМ и пользователя, например
|
||
|
||
```yaml
|
||
all:
|
||
hosts:
|
||
nginx:
|
||
ansible_host: 192.168.20.217
|
||
ansible_user: rouxinol
|
||
```
|
||
|
||
Далее в файле *secrets.yaml* необходимо указать пароль для указаного ранее пользователя, а так же пароль для *sudo* для указаного пользователя, например:
|
||
|
||
```yaml
|
||
ansible_password: "superpass123"
|
||
ansible_become_password: "superpass123"
|
||
```
|
||
|
||
Далее можно зашифровать этот файл:
|
||
|
||
```sh
|
||
ansible-vault encrypt secrets.yaml
|
||
```
|
||
|
||
После всех действий можно запустить плейбук:
|
||
|
||
```sh
|
||
ansible-playbook -i hosts.yaml playbook.yaml
|
||
```
|
||
|
||
> [!WARNING]
|
||
> Если был зашифрован secrets.yaml то необходимо так же добавить флаг ```--ask-vault-pass```
|
||
|
||
---
|
||
|
||
Скриншоты работы сервиса:
|
||
|
||
**HTTP**
|
||
|
||

|
||
|
||
**HTTPS**
|
||
|
||

|
||
|
||
---
|
||
|
||
В качестве лабораторной работы я заказал ВМ с Ubuntu Server 24.04 с пользователем *rouxinol* в Proxmox VE, IP ВМ в локальной сети - 192.168.20.217
|
||
|
||
Логи выполнения плейбука можно посмотреть в [логе выполнения Ansible](./ansible-playbook.log)
|
||
|
||
Логи повторного выполнения плейбука можно посмотреть в [логе повторного выполнения Ansible](./ansible-playbook-repeat.log)
|
||
|
||
## Ремарки к практическим заданиям
|
||
|
||
3) Продемонстрировать блокировку портов
|
||
|
||
<br>
|
||
|
||
**Конечная конфирукция ufw с ВМ**
|
||
```log
|
||
rouxinol@rouxinol-testserver:/opt/nginx$ sudo ufw status verbose
|
||
Status: active
|
||
Logging: on (low)
|
||
Default: deny (incoming), allow (outgoing), deny (routed)
|
||
New profiles: skip
|
||
|
||
To Action From
|
||
-- ------ ----
|
||
22/tcp (OpenSSH) ALLOW IN Anywhere
|
||
80/tcp ALLOW IN Anywhere
|
||
443/tcp ALLOW IN Anywhere
|
||
22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6)
|
||
80/tcp (v6) ALLOW IN Anywhere (v6)
|
||
443/tcp (v6) ALLOW IN Anywhere (v6)
|
||
```
|
||
|
||
**Nmap по привелигированным портам**
|
||
|
||
```log
|
||
❯ nmap 192.168.20.217
|
||
Starting Nmap 7.98 ( https://nmap.org ) at 2026-08-17 01:54 +0300
|
||
Nmap scan report for 192.168.20.217
|
||
Host is up (0.0029s latency).
|
||
Not shown: 997 filtered tcp ports (no-response)
|
||
PORT STATE SERVICE
|
||
22/tcp open ssh
|
||
80/tcp open http
|
||
443/tcp open https
|
||
|
||
Nmap done: 1 IP address (1 host up) scanned in 43.31 seconds
|
||
```
|
||
|
||
6) Бекап каждый понедельник
|
||
|
||
```log
|
||
root@rouxinol-testserver:/opt/nginx# crontab -l
|
||
CRON_TZ="UTC"
|
||
#Ansible: nginx configuration backup
|
||
0 1 * * 1 /opt/nginx/backup.sh
|
||
root@rouxinol-testserver:/opt/nginx# ./backup.sh
|
||
Successfully copied 25.1kB to /tmp/tmp.9hPGthi4R2/nginx
|
||
root@rouxinol-testserver:/opt/nginx# ls backups/
|
||
nginx_2026-08-16_23-01-36.tar.gz nginx_2026-08-16_23-02-10.tar.gz
|
||
```
|
||
|
||
7) В Dockerfile указано запускать master-процесс от пользователя nginx, а так же в nginx,conf указано запускать worker-процессы так же от nginx, однако для этого были выбраны непривелигированные порты 8080 и 8443, однако можно было использовать образ nginxinc/nginx-unprivileged и не указывать ничего из этого и в Dockerfile есть закомментированный FROM этого образа - однако он не был выбран так как в Docker Hub нет нужной 1.29.6 версии - я подобрал ближайшую
|
||
|
||
8) При запуске плейбука в его корне автоматически создается ssh ed25519 ключ без фразы пароля, для подключения к ВМ будет достаточно именно для моего тестового окружения следующей команды:
|
||
```sh
|
||
ssh -i ./id_ed25519_simbirkey rouxinol@192.168.20.217
|
||
```
|
||
|
||
9) [Dockerfile тут](./roles/nginx/files/Dockerfile)
|