mirror of
https://github.com/batonogov/learn-devops.git
synced 2025-11-29 08:43:01 +00:00
Add docker (#6)
* Add docker * Update example --------- Co-authored-by: Fedor Batonogov <f.batonogov@yandex.ru>
This commit is contained in:
committed by
GitHub
parent
fab1ba15f3
commit
99088532f2
29
.gitignore
vendored
29
.gitignore
vendored
@@ -47,7 +47,36 @@ terraform.rc
|
|||||||
|
|
||||||
# End of https://www.toptal.com/developers/gitignore/api/ansible
|
# End of https://www.toptal.com/developers/gitignore/api/ansible
|
||||||
|
|
||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/go
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=go
|
||||||
|
|
||||||
|
### Go ###
|
||||||
|
# If you prefer the allow list template instead of the deny list, see community template:
|
||||||
|
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||||
|
#
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, built with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Dependency directories (remove the comment below to include it)
|
||||||
|
# vendor/
|
||||||
|
|
||||||
|
# Go workspace file
|
||||||
|
go.work
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/go
|
||||||
|
|
||||||
# Other
|
# Other
|
||||||
.vscode
|
.vscode
|
||||||
.DS_Store
|
.DS_Store
|
||||||
ansible/secrets
|
ansible/secrets
|
||||||
|
main
|
||||||
|
|||||||
@@ -6,8 +6,10 @@
|
|||||||
|
|
||||||
## Структура проекта
|
## Структура проекта
|
||||||
|
|
||||||
0. [kubeadm](./kubeadm/) - это инструмент для простого и быстрого развёртывания кластера Kubernetes.
|
1. [Docker](./docker/) - **Docker** – это программная платформа для быстрой сборки, отладки и развертывания приложений с помощью **контейнеров**.
|
||||||
|
|
||||||
1. [OpenTofu](./opnetofu) — программное обеспечение с **открытым исходным кодом**, используемое для **управления внешними ресурсами** (например, в рамках модели **инфраструктура как код**). Проект Linux Foundation. Пользователи определяют и предоставляют инфраструктуру центра обработки данных с помощью **декларативного языка конфигурации**, известного как HashiCorp Configuration Language (HCL) или JSON.
|
2. [kubeadm](./kubeadm/) - это инструмент для простого и быстрого развёртывания кластера Kubernetes.
|
||||||
|
|
||||||
2. [Ansible](./ansible) — система управления конфигурациями, написанная на языке программирования **Python**, с использованием **декларативного языка разметки** для **описания конфигураций**. Применяется для **автоматизации настройки и развёртывания программного обеспечения**.
|
3. [OpenTofu](./opnetofu) — программное обеспечение с **открытым исходным кодом**, используемое для **управления внешними ресурсами** (например, в рамках модели **инфраструктура как код**). Проект Linux Foundation. Пользователи определяют и предоставляют инфраструктуру центра обработки данных с помощью **декларативного языка конфигурации**, известного как HashiCorp Configuration Language (HCL) или JSON.
|
||||||
|
|
||||||
|
4. [Ansible](./ansible) — система управления конфигурациями, написанная на языке программирования **Python**, с использованием **декларативного языка разметки** для **описания конфигураций**. Применяется для **автоматизации настройки и развёртывания программного обеспечения**.
|
||||||
|
|||||||
32
docker/.dockerignore
Normal file
32
docker/.dockerignore
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Created by https://www.toptal.com/developers/gitignore/api/go
|
||||||
|
# Edit at https://www.toptal.com/developers/gitignore?templates=go
|
||||||
|
|
||||||
|
### Go ###
|
||||||
|
# If you prefer the allow list template instead of the deny list, see community template:
|
||||||
|
# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore
|
||||||
|
#
|
||||||
|
# Binaries for programs and plugins
|
||||||
|
*.exe
|
||||||
|
*.exe~
|
||||||
|
*.dll
|
||||||
|
*.so
|
||||||
|
*.dylib
|
||||||
|
|
||||||
|
# Test binary, built with `go test -c`
|
||||||
|
*.test
|
||||||
|
|
||||||
|
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||||
|
*.out
|
||||||
|
|
||||||
|
# Dependency directories (remove the comment below to include it)
|
||||||
|
# vendor/
|
||||||
|
|
||||||
|
# Go workspace file
|
||||||
|
go.work
|
||||||
|
|
||||||
|
# End of https://www.toptal.com/developers/gitignore/api/go
|
||||||
|
|
||||||
|
# Other
|
||||||
|
docker-compose.yaml
|
||||||
|
Dockefile
|
||||||
|
nginx.tmpl
|
||||||
19
docker/Dockerfile
Normal file
19
docker/Dockerfile
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Используем официальный образ Golang
|
||||||
|
FROM docker.io/library/golang:1.22.2-alpine AS builder
|
||||||
|
# Устанавливаем рабочую директорию
|
||||||
|
WORKDIR /build
|
||||||
|
# Копируем исходный код приложения в контейнер
|
||||||
|
COPY ./ ./
|
||||||
|
RUN CGO_ENABLED=0 go build main.go
|
||||||
|
|
||||||
|
# Отдельный этап сборки для уменьшения размера образа
|
||||||
|
FROM docker.io/library/alpine:3.19.1 AS runner
|
||||||
|
# Устанавливаем рабочую директорию
|
||||||
|
WORKDIR /app
|
||||||
|
# Копируем скомпилированное приложение из предыдущего этапа
|
||||||
|
COPY --from=builder /build/main ./
|
||||||
|
# Запускаем healthcheck, проверяющий доступность веб-сервера на порту 8080
|
||||||
|
HEALTHCHECK --interval=5s --timeout=5s --start-period=3s --retries=3 \
|
||||||
|
CMD wget --quiet --tries=1 --spider http://localhost:8080/ || exit 1
|
||||||
|
# Запускаем приложение при старте контейнера
|
||||||
|
CMD ["./main"]
|
||||||
82
docker/README.md
Normal file
82
docker/README.md
Normal file
@@ -0,0 +1,82 @@
|
|||||||
|
# Docker
|
||||||
|
|
||||||
|
## Описание приложения
|
||||||
|
|
||||||
|
Простой веб сервис написанный на **Go**, возвращающий имя узла.
|
||||||
|
|
||||||
|
Сервис можно запустить несколькими способами.
|
||||||
|
|
||||||
|
### Локальный запуск
|
||||||
|
|
||||||
|
Сборка приложения:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
go build main.go
|
||||||
|
```
|
||||||
|
|
||||||
|
Запуск
|
||||||
|
|
||||||
|
```sh
|
||||||
|
./main
|
||||||
|
```
|
||||||
|
|
||||||
|
Вывод
|
||||||
|
|
||||||
|
```output
|
||||||
|
Сервер запущен на порту 8080...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Запуск в контейнере
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker build -t test . && docker run test
|
||||||
|
```
|
||||||
|
|
||||||
|
Вывод
|
||||||
|
|
||||||
|
```output
|
||||||
|
Сервер запущен на порту 8080...
|
||||||
|
```
|
||||||
|
|
||||||
|
### Запуск при помощи docker compose
|
||||||
|
|
||||||
|
Запуск
|
||||||
|
|
||||||
|
```sh
|
||||||
|
docker compose --profile blue up --wait --remove-orphans --scale web-blue=5
|
||||||
|
```
|
||||||
|
|
||||||
|
Вывод
|
||||||
|
|
||||||
|
```output
|
||||||
|
✔ Network docker_default Created 0.0s
|
||||||
|
✔ Container docker-nginx-proxy-1 Healthy 0.1s
|
||||||
|
✔ Container docker-web-blue-2 Healthy 0.1s
|
||||||
|
✔ Container docker-web-blue-4 Healthy 0.1s
|
||||||
|
✔ Container docker-web-blue-3 Healthy 0.0s
|
||||||
|
✔ Container docker-web-blue-5 Healthy 0.1s
|
||||||
|
✔ Container docker-web-blue-1 Healthy 0.1s
|
||||||
|
```
|
||||||
|
|
||||||
|
### Сине-зеленое развертывание
|
||||||
|
|
||||||
|
Запуск
|
||||||
|
|
||||||
|
```sh
|
||||||
|
bash ./deploy.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Вывод
|
||||||
|
|
||||||
|
```output
|
||||||
|
Список контейнеров
|
||||||
|
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
|
||||||
|
docker-nginx-proxy-1 nginxproxy/nginx-proxy:1.5.1-alpine "/app/docker-entrypo…" nginx-proxy 12 seconds ago Up 5 seconds (healthy) 0.0.0.0:80->80/tcp
|
||||||
|
docker-web-blue-1 docker-web-blue "./main" web-blue 12 seconds ago Up 11 seconds (healthy) 8080/tcp
|
||||||
|
docker-web-blue-2 docker-web-blue "./main" web-blue 12 seconds ago Up 11 seconds (healthy) 8080/tcp
|
||||||
|
docker-web-blue-3 docker-web-blue "./main" web-blue 12 seconds ago Up 11 seconds (healthy) 8080/tcp
|
||||||
|
Журналы запуска web-blue
|
||||||
|
web-blue-2 | Сервер запущен на порту 8080...
|
||||||
|
web-blue-1 | Сервер запущен на порту 8080...
|
||||||
|
web-blue-3 | Сервер запущен на порту 8080...
|
||||||
|
```
|
||||||
51
docker/deploy.sh
Normal file
51
docker/deploy.sh
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Эта строка настраивает оболочку так, чтобы она выходила из скрипта при возникновении ошибки в любой команде.
|
||||||
|
# Это помогает обнаружить и обрабатывать ошибки в скрипте.
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Проверяем состояние контейнера с именем "web-blue", чтобы определить, является ли он "здоровым" (healthy).
|
||||||
|
# Если это так, переменным NEW и OLD присваиваются значения "green" и "blue" соответственно, иначе наоборот.
|
||||||
|
if [ "$(docker compose ps web-blue | grep healthy)" ]
|
||||||
|
then
|
||||||
|
export NEW="green"
|
||||||
|
export OLD="blue"
|
||||||
|
else
|
||||||
|
export NEW="blue"
|
||||||
|
export OLD="green"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Выводим сообщение о том, какой профиль поднимается в данный момент (значение переменной NEW).
|
||||||
|
echo Поднимаю проект с профилем ${NEW}
|
||||||
|
# Эта команда использует docker-compose для запуска проекта с указанным профилем (значение переменной NEW),
|
||||||
|
# разворачивая контейнеры в фоновом режиме, пересоздавая их, удаляя сиротские контейнеры,
|
||||||
|
# масштабируя сервис "web" на три экземпляра и дожидаясь их запуска.
|
||||||
|
docker compose \
|
||||||
|
--profile ${NEW} \
|
||||||
|
up \
|
||||||
|
--detach \
|
||||||
|
--build \
|
||||||
|
--remove-orphans \
|
||||||
|
--scale web-${NEW}=3 \
|
||||||
|
--wait
|
||||||
|
|
||||||
|
# Эта строка выводит сообщение о том, какие сервисы останавливаются в данный момент (значение переменной OLD).
|
||||||
|
echo Останавливаю сервисы ${OLD}
|
||||||
|
# Эта команда использует docker-compose для остановки сервиса "web" с именем, соответствующим значению переменной OLD.
|
||||||
|
docker compose stop \
|
||||||
|
web-${OLD}
|
||||||
|
|
||||||
|
# Эта строка выводит сообщение о том, какие сервисы удаляются в данный момент (значение переменной OLD).
|
||||||
|
echo Удаляю сервисы ${OLD}
|
||||||
|
# Эта команда использует docker-compose для принудительного удаления сервиса "web" с именем, соответствующим значению переменной OLD.
|
||||||
|
docker compose rm -f \
|
||||||
|
web-${OLD}
|
||||||
|
|
||||||
|
# Эта строка выводит сообщение о выводе списка всех контейнеров.
|
||||||
|
echo Список контейнеров
|
||||||
|
docker compose ps -a
|
||||||
|
|
||||||
|
# Эта команда выводит сообщение о том, что будут выведены журналы запуска для сервиса "web" с именем,
|
||||||
|
# соответствующим значению переменной NEW, и затем выводит эти журналы.
|
||||||
|
echo Журналы запуска web-${NEW}
|
||||||
|
docker compose logs web-${NEW}
|
||||||
57
docker/docker-compose.yaml
Normal file
57
docker/docker-compose.yaml
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
services:
|
||||||
|
# Сервис для развертывания приложения с профилем "blue"
|
||||||
|
web-blue: &web
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
environment:
|
||||||
|
- VIRTUAL_HOST=web # Виртуальный хост для NGINX
|
||||||
|
- VIRTUAL_PORT=8080 # Виртуальный порт для NGINX
|
||||||
|
expose:
|
||||||
|
- 8080
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: "0.5" # Лимитированный доступ к ресурсам CPU
|
||||||
|
memory: 32M # Лимит памяти
|
||||||
|
restart: always # Перезапускать сервис при падении
|
||||||
|
profiles:
|
||||||
|
- blue
|
||||||
|
|
||||||
|
# Сервис для развертывания приложения с профилем "green"
|
||||||
|
web-green:
|
||||||
|
<<: *web # Используем настройки из сервиса web-blue
|
||||||
|
profiles:
|
||||||
|
- green
|
||||||
|
|
||||||
|
# NGINX-прокси
|
||||||
|
nginx-proxy:
|
||||||
|
image: nginxproxy/nginx-proxy:1.5.1-alpine
|
||||||
|
expose:
|
||||||
|
- 80
|
||||||
|
ports:
|
||||||
|
- 80:80 # Проксируем порт 80 на хосте
|
||||||
|
healthcheck:
|
||||||
|
# Периодичность проверки состояния (5 секунд)
|
||||||
|
interval: 5s
|
||||||
|
# Максимальное время ожидания ответа (5 секунд)
|
||||||
|
timeout: 5s
|
||||||
|
# Количество попыток в случае неудачной проверки (5 попыток)
|
||||||
|
retries: 5
|
||||||
|
# Время ожидания перед началом проверок (3 секунды)
|
||||||
|
start_period: 3s
|
||||||
|
# Команда для выполнения теста
|
||||||
|
test: curl -f http://localhost/ || exit 1
|
||||||
|
volumes:
|
||||||
|
# Монтируем сокет Docker
|
||||||
|
- /var/run/docker.sock:/tmp/docker.sock:ro
|
||||||
|
# Монтируем шаблон NGINX
|
||||||
|
- ./nginx.tmpl:/app/nginx.tmpl:ro
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '0.1' # Лимитированный доступ к ресурсам CPU
|
||||||
|
memory: 128M # Лимит памяти
|
||||||
|
restart: always
|
||||||
|
profiles:
|
||||||
|
- blue
|
||||||
|
- green
|
||||||
28
docker/main.go
Normal file
28
docker/main.go
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// Обработчик запросов
|
||||||
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Получаем имя хоста
|
||||||
|
hostname, err := os.Hostname()
|
||||||
|
if err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отправляем имя хоста в ответ
|
||||||
|
fmt.Fprintf(w, "Hostname Hostname: %s\n", hostname)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Запуск веб-сервера на порту 8080
|
||||||
|
fmt.Println("Сервер запущен на порту 8080...")
|
||||||
|
if err := http.ListenAndServe(":8080", nil); err != nil {
|
||||||
|
fmt.Printf("Ошибка запуска сервера: %s\n", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
20
docker/nginx.tmpl
Normal file
20
docker/nginx.tmpl
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
{{ range $host, $containers := groupBy $ "Env.VIRTUAL_HOST" }}
|
||||||
|
upstream {{ $host }} {
|
||||||
|
|
||||||
|
{{ range $index, $value := $containers }}
|
||||||
|
{{ with $address := index $value.Addresses 0 }}
|
||||||
|
server {{ $value.Hostname }}:{{ $address.Port }};
|
||||||
|
{{ end }}
|
||||||
|
{{ end }}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# конфигурация веб-сервера
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
proxy_pass http://{{ $host }};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{ end }}
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
virtual_environment_api_token = "root@pam!for-terraform-provider=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
virtual_environment_api_token = "root@pam!for-terraform-provider=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||||
virtual_environment_endpoint = "https://10.0.70.116:8006/"
|
virtual_environment_endpoint = "https://x.x.x.x:8006/"
|
||||||
|
|||||||
Reference in New Issue
Block a user