Docker best practices

В рамках данной статьи будут рассмотрены наиболее частые антипаттерны при проектировании docker образов, а так же будет представлено оптимальное решение для каждого Использование избыточного базового образа Один из распространенных антипаттернов при использовании Docker - это использование избыточного базового образа. # Плохо FROM ubuntu Оптимальное решение - использовать наиболее легковесный базовый образ, который содержит только необходимые компоненты, в роли которого может выступать alpine. # Хорошо FROM alpine Сравнение размера двух образов:...

апреля 29, 2024 · 3 минуты · OldTyT

Docker для чайников

Docker для самых маленьких Для закрепления материала, рекомендуется выполнить команды указанные в статье Введение Docker - это платформа для разработки, доставки и запуска приложений в контейнерах. Контейнеры представляют собой легковесные и изолированные окружения, которые позволяют запускать приложения на любой операционной системе без необходимости установки дополнительных зависимостей. В этой статье мы рассмотрим основы Docker и покажем, как использовать его для разработки приложений. Установка Docker Перед тем, как начать использовать Docker, вам необходимо установить его на свою систему....

апреля 29, 2024 · 2 минуты · OldTyT

Cron

Введение Cron — это хронологический демон-планировщик задач, работающий в операционных системах типа Unix, включая дистрибутивы Linux. Cron запускается в фоновом режиме, а задачи, запланированные в cron и именуемые «задачи cron», выполняются автоматически, что делает cron полезным для автоматизации связанных с обслуживанием задач. Особенности среды Все команды выполнялись в Ubuntu 22.04, если ваша машина имеет другую ОС, команды могут отличаться. Установка cron Большинство дистрибутивов linux имеют уже установленный cron по умолчанию, но если вы используете Ubuntu, где cron не установлен, его можно установить с помощью пакетного менеджера apt...

марта 13, 2024 · 4 минуты · OldTyT

База DevOps

Данная статья предназначена для тех, кто только хочет вкатиться в DevOps. Она поможет понять некоторые нюансы. Статья находится в активной разработке База FHS bash Знать и уметь в top и htop cron Уметь в systemd(написание untit’oв, просмотр логов в journalctl) Уметь в траблшутинг Пощупать ansible и погонять сборки локально в molecule(заложена ошибка специально, когда выполнишь команду molecule test, она станет явной) Продвинутый уровень Docker. Почитать можно тут и тут CI/CD Prometheus Grafana Специфичное K8s Jenkins Python GO OpenSearch / ELK Написание SQL запросов

марта 13, 2024 · 1 минута · OldTyT

Как я запускал minecraft в kubernetes

Minecraft в kubernetes Всем привет, в этой статье я поделюсь своим опытом запуска Minecraft в kubernetes. Основная проблема, возникающая при попытке запустить Minecraft в Kubernetes, заключается в том, что во время работы Minecraft происходит работа с файлами на локальном диске, а такой подход в Kubernetes является нежелательным, поскольку в случае сбоя ноды (назовем его нода A), на которой развернут под - под не сможет быть создан на другой ноде (нода B), так как известно, что под ранее работал на ноде A и, соответственно, все его постоянные файлы находятся там. Варианты решения проблем с использованием постоянных файлов В поисках решения этой проблемы, я определил возможные методы решения: отказ от постоянных файлов использовать Persistent Volume создать сетевой диск использовать csi-s3 Давайте подробнее рассмотрим каждый из вариантов Отказ от постоянных файлов Плюсы: Работает нативно Это лучшее решение, т.к. не будет проблем с пересозданием пода на другой ноде в случае сбоя Минусы: Не применимо к текущему приложению Использовать Persistent Volume Плюсы: Высокая скорость чтения/записи файлов Минусы: Все данные находятся на одной ноде, в случае его поломки pod не сможет подняться Создать сетевой диск Плюсы: Данные реплицируются на несколько нод Минусы: Более низкая скорость чтения/записи файлов Использовать csi-s3 Плюсы: Данные не находятся в кластере Минусы: Более низкая скорость чтения/записи файлов Из-за большого количества вызовов API может получиться высокая цена Анализ вариантов Основываясь на полученных данных, мы приходим к выводу, что на данный момент не существует решения, которое могло бы соответствовать нашим требованиям, а именно: высокая скорость чтения/записи файлов не должно быть привязки к определенной ноде минимальные затраты на реализацию данного функционала Решение проблемы с использованием постоянных данных Чтобы решить эту проблему, был подготовлен docker контейнер. Алгоритм работы контейнера Добавляются SSH-ключи. Ключи берутся из значений переменных ENV Репозиторий сервера клонируется из git с конфигурацией сервера в каталог - /app Последовательности MYSQL_.+ заменяются во всех файлах в /app/plugins на их значение ENV Игровой мир копируется из хранилища s3 и распаковывается Игровые плагины и ядро копируются из хранилища s3 Начинается /task_manager.py - который отвечает за выполнение задач cron, работу сервера и вывод syslog Cron задачи В задачах cron в настоящее время настроены следующие задачи: * * * * * root /git_pull.sh | logger * * * * * root /git_commit.sh | logger 0 * * * * root /copy_worlds.sh | logger Информация по каждой задаче: /git_pull.sh - выполняет git pull в каталоге /app /git_commit.sh - создает commit и отправляет его в репозиторий /copy_worlds.sh - создает копию мира и загружает ее в хранилище s3 вместо существующей Пример развертывания службы Настройка ingress контроллера Рассмотрим пример с traefik. Чтобы настроить ingres контроллер, вам нужно будет выполнить следующую команду: $ helm upgrade --values traefik-values.yaml traefik traefik/traefik -n kube-system Контент файла traefik-values.yaml: ports: traefik: port: 9000 expose: false exposedPort: 9000 protocol: TCP web: port: 8000 expose: true exposedPort: 80 protocol: TCP minecraft: port: 22565 expose: true exposedPort: 25565 protocol: TCP websecure: port: 8443 expose: true exposedPort: 443 protocol: TCP http3: enabled: false tls: enabled: true options: "" certResolver: "" domains: [] middlewares: [] metrics: port: 9100 expose: false exposedPort: 9100 protocol: TCP После этого подключения к LoadBalancer будут разрешены через порт 25565 $ kubectl get svc -n kube-system | grep -v "none" NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE traefik LoadBalancer 10.43.2.50 100.10.0.11 25565:30224/TCP,80:31380/TCP,443:30226/TCP 2d21h Deploy Пример окончательного манифеста, содержащего требуемую конфигурацию: --- apiVersion: v1 kind: Namespace metadata: name: minecraft --- apiVersion: v1 kind: Secret metadata: name: minecraft-secret namespace: minecraft type: Opaque data: SSH_KEY_PUBLIC: "SECRET" SSH_KEY_PRIVATE: "SECRET" MYSQL_ROOT_PASSWORD: "SECRET" MYSQL_DBS: "SECRET" MYSQL_HOST: "SECRET" MYSQL_USER: "SECRET" MYSQL_PASSWORD: "SECRET" S3_BUCKET: "SECRET" S3_ACCESS_KEY: "SECRET" S3_ACCESS_KEY_ID: "SECRET" --- apiVersion: apps/v1 kind: Deployment metadata: name: some_worlds_name namespace: minecraft spec: selector: matchLabels: app: some_worlds_name strategy: type: Recreate template: metadata: namespace: minecraft labels: app: some_worlds_name spec: imagePullSecrets: - name: github-registry containers: - image: ghcr.io/oldtyt/docker_minecraft imagePullPolicy: Always name: some_worlds_name resources: requests: cpu: 1000m memory: 5G limits: memory: 6G cpu: 1200m env: - name: XMX value: "5G" - name: "XMS" value: "512M" - name: MYSQL_HOST valueFrom: secretKeyRef: name: minecraft-secret key: MYSQL_HOST - name: MYSQL_USER valueFrom: secretKeyRef: name: minecraft-secret key: MYSQL_USER - name: MYSQL_DB valueFrom: secretKeyRef: name: minecraft-secret key: MYSQL_USER - name: MYSQL_PASSWORD valueFrom: secretKeyRef: name: minecraft-secret key: MYSQL_PASSWORD - name: S3_BUCKET valueFrom: secretKeyRef: name: minecraft-secret key: S3_BUCKET - name: S3_ACCESS_KEY valueFrom: secretKeyRef: name: minecraft-secret key: S3_ACCESS_KEY - name: S3_ACCESS_KEY_ID valueFrom: secretKeyRef: name: minecraft-secret key: S3_ACCESS_KEY_ID - name: SSH_KEY_PRIVATE valueFrom: secretKeyRef: name: minecraft-secret key: SSH_KEY_PRIVATE - name: SSH_KEY_PUBLIC valueFrom: secretKeyRef: name: minecraft-secret key: SSH_KEY_PUBLIC - name: PLUGINS_LIST value: "some,plugins,list" - name: GIT_REPO value: "git@github.com:USER/REPO.git" - name: KERNEL value: "KERNEL" - name: "WORLDS" value: "some_worlds_name" --- apiVersion: v1 kind: Service metadata: name: some_worlds_name namespace: minecraft labels: env: prod app: some_worlds_name owner: OldTyT spec: ports: - name: minecraft targetPort: 25565 port: 25565 protocol: TCP selector: app: some_worlds_name Команда для развертывания манифеста: $ kubectl apply -f minecraft.yaml

октября 7, 2023 · 4 минуты · OldTyT