INT 21h

Hi, I am Vladimir Smagin, SysAdmin, DevOps and barely good guy. Telegram Email / GIT / Микроблог / Thingiverse / RSS / GPG

Прекрасный Hashicorp Packer

№ 11013 В разделе "Sysadmin" от May 30th, 2020,
В подшивках:

Допустим, у вас где-то в облачном сервисе хостится большое количество однотипных серверов, какая-то ферма из wordpress или кластер kubernetes и вы хотите сделать регулировку количества нод в зависимости от нагрузки для снижения стоимости эксплуатации. Нодами можно управлять руками или с помощью terraform и деплоить туда софт через ansible, но такой метод все равно плохо подходит когда это нужно делать быстро. Есть выход из ситуации в виде создания образа ноды из уже поднятой рабочей ноды, а потом в зависимости от нагрузки поднимать из этого образа новые ноды, но такой способ довольно затратен по времени и может легко вылиться в часы работы. Одна хитрая фирма, занимающаяся автоматизацией процессов создала штуку под названием Packer. И нет, это не накладной хуец, как мог бы подумать гугол.

Packer предназначен для быстрого создания образов для последующего развертывания. Конфигурационный файл описывает состояние будущей виртуальной машины и Packer старается привести образ к этому состоянию. Для примера можно взять Hetzner и какой-то php проект, для которого развернем nginx, php-fpm, модули баз данных, сами базы данных и пара административных утилит. Поскольку это всего-лишь пример работы, я здесь не упоминаю многих функций и рекомендую изучить полное руководство.

Все необходимые файлы лежат в этом git репозитории. Откройте hetzner.json и внимательно его изучите. В билдере как раз описывается требуемое состояние образа. Кстати, никто не запрещает иметь два билдера, или три, для прода, стейджинга или даже в другом облаке. В текущем примере билдер всего один для хецнера. Метки и имена очень полезны для последующей работы с образами, не пренебрегайте ими. Есть 2 пути доставки команд в образ, через user_data и через provisioners и между ними есть существенное отличие, которое рекомендую тщательно изучить, этот пример использует оба пути. Также провижионерами можно, например, копировать файлы или запустить ansible плейбук.

{
  "variables": {
    "hcloud_token": "my_hetzner_token"
  },
  "builders": [
    {
      "type": "hcloud",
      "token": "{{user `hcloud_token`}}",
      "image": "ubuntu-18.04",
      "location": "nbg1",
      "server_type": "cx11",
      "ssh_keys": [
        "vlad"
      ],
      "snapshot_name": "nginx-php",
      "snapshot_labels": {
        "test": "label",
        "shell": "bash",
        "python": "3"
      },
      "user_data_file": "ubuntu_deps.sh",
      "communicator": "ssh",
      "ssh_username": "root",
      "pause_before_connecting": "1m"
    }
  ],
  "provisioners": [
    {
      "type": "shell",
      "script": "ubuntu_deps.sh"
    },
    {
      "type": "shell",
      "inline": [
        "sudo apt-get install -y php-mysql php-pgsql mysql-server postgresql-10"
      ]
    }
  ]
}

Для работы с апи хецнера требуется токен, который прописывается в виде переменной. Переменным значения можно не передавать, просто захардкодив их, или можно передать через переменные окружения. А можно брать вообще из Vault или Consul, в документации отлично рассказано про всё это. В моем примере я передаю их через командную строку при команде build, которая необходима для старта сборки образа. Такой подход позволяет лучше автоматизировать процесс сборки, т.к. json файл будет являться по сути шаблоном, в который ваша CI подставляет необходимые значения.

packer build -var 'hcloud_token=DF23J2LK35J23KJ2LK352GHJF2HGFD23HG' hetzner.json

После начала сборки в панели управления облаком вы увидите, что поднялась новая виртуальная машина заданного типа в которую устанавливаются все указанные пакеты. По окончании сборки с виртуальной машины снимется образ, который будет виден в разделе Snapshots. Теперь из этого образа можно поднимать огромное количество нод и их тип совсем не ограничен той, которая была прописана в server_type.

Я думаю вы с легкостью найдете применение этой замечательной утилите. Когда закончите изучение этой обратите внимание на другую крутую штуку Vagrant, которая помогает управлять виртуальными машинами.

Репозиторий с примером https://git.blindage.org/21h/packer-hetzner-sample

Нет комментариев »

Warm Image operator for Kubernetes

№ 11010 В разделе "Sysadmin" от May 28th, 2020,
В подшивках: , , ,

For example, you have huge image with your software and running POD on node. When POD moving to another node your image downloads to new node minute or two. This operator forces nodes to download image before rescheduling, so POD starts faster.

It runs /bin/sh with infinite loop on specified image as DaemonSet with additional options like NodeSelector, Affinity or resource limits. You can specify custom command if your image not contains /bin/sh interpreter or you want to run own script.

Your first warmer:

apiVersion: blindage.org/v1alpha1
kind: WarmImage
metadata:
  name: mongo4
spec:
  image: mongo
  version: "4"
  nodeSelector:
    node-role.kubernetes.io/master: ""

Now you warmed mongo:4 on all master nodes.

Repository here https://git.blindage.org/21h/warm-image-operator

Нет комментариев »

История провала: webdav и nginx для Windows

№ 10985. В разделе " Sysadmin " от April 25th, 2020

В подшивках: , ,

How to move snap application between computers with snapshots

№ 10960. В разделе " Sysadmin " от March 29th, 2020

В подшивках: ,

wal-g and Postgresql

№ 10938 В разделе "Sysadmin" от March 20th, 2020,
В подшивках: , ,

Initials

Master database: postgresql-10, in production
Backup storage: minio with empty pg-walg-backup bucket

Task: Create slave postgresql-10 server with recovery

Preparing for both servers

Install wal-g binary manually or use my Ubuntu repository (install walg-lzo).

Create special script for wal-g with variables, save to /var/lib/postgresql/walg-postgresql

#!/bin/bash
source /etc/profile

export AWS_ENDPOINT=http://minio.myserv.com:9000
export AWS_ACCESS_KEY_ID="KEYNAMEKEYNAMEKEYNAME"
export AWS_SECRET_ACCESS_KEY="SECRETSECRETSECRETSECRETSECRETSECRET"
export WALE_S3_PREFIX="s3://pg-walg-backup/"
export AWS_S3_FORCE_PATH_STYLE="true"
export AWS_REGION=us-east-1
export PGHOST=/var/run/postgresql
export PGUSER=postgres
export PGPORT=5433

wal-g $@

It is not secure to store this file global readable. Best choice to place it in postgres home directory without read by others:

chmod 500 /var/lib/postgresql/walg-postgresql
chown postgres:postgres /var/lib/postgresql/walg-postgresql

Master server

Add to postgresql.conf:

archive_mode = on
archive_command = '/var/lib/postgresql/walg-postgresql wal-push %p'

Ok, now run backup-push to create full backup:

/var/lib/postgresql/walg-postgresql backup-push /pg_data/10/main

Slave server

Stop postgresql and remove data directory, wal-g requires empty directory before restore.

Now run:

/var/lib/postgresql/walg-postgresql backup-fetch /pgdata/10/main LATEST

Create /pgdata/10/main/recovery.conf:

standby_mode = 'on'
restore_command = 'walg-postgresql wal-fetch "%f" "%p"'

Now see logfile for wal restoring, database in recovery mode.

Нет комментариев »

Яндекс.Метрика

Fortune cookie: "The policeman isn't there to create disorder. The policeman is there to ________preserve disorder." -- Mayor Daley