User data на выделенном сервере
User data — пользовательские параметры конфигурации операционной системы сервера. Описываются в виде скриптов в формате cloud-config (текстовые файлы с YAML-синтаксисом) или как bash-скрипт. Скрипты автоматически кодируются в Base64, передаются на сервер и выполняются с помощью агента cloud-init при первом запуске операционной системы. Использование user data помогает автоматизировать настройку серверов.
Указать user data можно на этапе установки операционной системы.
Подробнее о форматах скриптов cloud-config и bash в инструкции User data formats документации cloud-init.
В скриптах можно передава ть как отдельные параметры конфигурации операционной системы, так и целые последовательности параметров. Например:
- установить часовой пояс;
- создать каталог и загрузить в него файлы;
- обновить репозитории и установить пакеты;
- разместить SSH-ключ на сервере;
- настроить файл конфигурации преобразователя доменных имен resolv.conf.
Посмотрите другие примеры в инструкции Cloud config examples документации cloud-init.
Указать user data
Указать user data можно только при автоустановке ОС на базе Linux. Текст скрипта вводится в поле User data.
После завершения автоматической установки текст в поле User data изменить нельзя.
Максимальный размер скрипта с данными, которые не закодированы в Base64, — 16 КБ.
Примеры user data
Установить часовой пояс
Cloud-config
Bash-скрипт
Пример скрипта для установки часового пояса Europe/Moscow:
#cloud-config
timezone: Europe/Moscow
Пример скрипта для установки часового пояса Europe/Moscow:
#!/bin/bash
timedatectl set-timezone Europe/Moscow
Создать каталог и загрузить в него файлы
Cloud-config
Bash-скрипт
Пример скрипта для создания каталога и загрузки в него файла по сети:
#cloud-config
runcmd:
- mkdir <directory>
- [ wget, "<url>", -O, <directory>/<file_name> ]
Укажите:
<directory>— каталог на сервере, например/run/newdir;<url>— URL-адрес до файла, напримерhttps://repo.local/static/page.html;<file_name>— имя файла, под которым загруженный файл будет сохранен в каталоге, напримерindex.html.
Пример скрипта для создания каталога и загрузки в него файла по сети:
#!/bin/bash
mkdir <directory>
wget <url> -O <directory>/<file_name>
Укажите:
<directory>— каталог на сервере, например/run/newdir;<url>— URL-адрес до файла, напримерhttps://repo.local/static/page.html;<file_name>— имя файла, под которым загруженный файл будет сохранен в каталоге, напримерindex.html.
Обновить репозитории и установить пакеты
Cloud-config
Bash-скрипт
Пример скрипта для установки пакетов:
pwgen— утилита для генерации случайных паролей;pastebinit— инструмент командной строки для публикации в онлайн-сервисах текстов, например выводов команд, логов и др., из терминала.
#cloud-config
package_update: true
packages:
- pwgen
- pastebinit
Пример скрипта для установки пакетов:
pwgen— утилита для генерации случайных паролей;pastebinit— инструмент командной строки для публикации в онлайн-сервисах текстов из терминала, например выводов команд, логов и др.
#!/bin/bash
apt update
apt install pwgen pastebinit
Разместить SSH-ключ на сервере
Cloud-config
Bash-скрипт
Пример скрипта для размещения на сервере двух SSH-ключей.
Ключ будет добавлен пользователю ОС, по умолчанию это пользователь root, в директорию ~/.ssh/authorized_keys.
#cloud-config
ssh_authorized_keys:
- ssh-rsa <ssh_key_user_1> <user_name_1>@<host_name_1>
- ssh-rsa <ssh_key_user_2> <user_name_2>@<host_name_2>
Укажите:
<ssh_key_user_1>— публичный SSH-ключ первого пользователя, напримерAAAAB3N…V7NZ;<user_name_1>@<host_name_1>— комментарий к SSH-ключу первого пользователя, где:<user_name_1>— имя первого пользователя, который сгенерировал SSH-ключ;<host_name_1>— имя устройства, на котором сгенерировали SSH-ключ;
<ssh_key_user_2>— публичный SSH-ключ второго пользователя, напримерAAAAB3N…NtHw==;<user_name_2>@<host_name_2>— комментарий к SSH-ключу второго пользователя, где:<user_name_2>— имя второго пользователя, который сгенерировал SSH-ключ;<host_name_2>— имя устройства, на котором сгенерировали SSH-ключ.
Пример скрипта для размещения на сервере двух SSH-ключей.
Ключ будет добавлен пользователю ОС, по умолчанию это пользователь root, в директорию ~/.ssh/authorized_keys.
#!/bin/bash
echo "ssh-rsa <ssh_key_user_1> <user_name_1>@<host_name_1>" >> /root/.ssh/authorized_keys
echo "ssh-rsa <ssh_key_user_2> <user_name_2>@<host_name_2>" >> /root/.ssh/authorized_keys
Укажите:
<ssh_key_user_1>— публичный SSH-ключ первого пользователя, напримерAAAAB3N…V7NZ;<user_name_1>@<host_name_1>— комментарий к SSH-ключу первого пользователя, где:<user_name_1>— имя первого пользователя, который сгенерировал SSH-ключ;<host_name_1>— имя устройства, на котором сгенерировали SSH-ключ;
<ssh_key_user_2>— публичный SSH-ключ второго пользователя, напримерAAAAB3N…NtHw==;<user_name_2>@<host_name_2>— комментарий к SSH-ключу второго пользователя, где:<user_name_2>— имя второго пользователя, который сгенерировал SSH-ключ;<host_name_2>— имя устройства, на котором сгенерировали SSH-ключ.
Настроить файл конфигурации
Cloud-config
Bash-скрипт
Приме р скрипта для преобразователя доменных имен resolv.conf:
#cloud-config
manage_resolv_conf: true
resolv_conf:
nameservers: ['<dns_server_ip_address_1>', '<dns_server_ip_address_2>']
searchdomains:
- <searchdomain_1>
- <searchdomain_2>
domain: <domain>
options:
rotate: true
timeout: 1
Укажите:
<dns_server_ip_address_1>,<dns_server_ip_address_2>— IP-адреса DNS-серверов, к которым будет обращаться система для разрешения доменных имен, например4.4.4.4и8.8.8.8;<searchdomain_1>,<searchdomain_2>— домены, которые будут добавляться к коротким (неполным) именам хостов при обращении к ним;<domain>— (legacy) основной DNS-домен, который будет добавляться к коротким (неполным) именам хостов при обращении к ним.
Пример скрипта для преобразователя доменных имен resolv.conf:
#!/bin/bash
cat <<EOF > /etc/resolv.conf
domain <domain>
nameserver <dns_server_ip_address_1>
nameserver <dns_server_ip_address_2>
search <searchdomain_1> <searchdomain_2>
options rotate
options timeout:1
EOF
Укажите:
<domain>— (legacy) основной DNS-домен, который будет добавляться к коротким (неполным) именам хостов при обращении к ним;<dns_server_ip_address_1>,<dns_server_ip_address_2>— IP-адреса DNS-серверов, к которым будет обращаться система для разрешения доменных имен, например4.4.4.4и8.8.8.8;<searchdomain_1>,<searchdomain_2>— домены, которые будут добавляться к коротким (неполным) именам хостов при обращении к ним.
Отключить доступ в интернет
Bash-скрипт
Python-скрипт
Пример скрипта для выключения сетевого интерфейса с публичным IPv4-адресом:
#!/bin/bash
ip addr show
public_interface=$(ip -4 addr show | awk '/inet/ && !/127.0.0.1/ && !/10\./ && !/172\.(1[6-9]|2[0-9]|3[0-1])\./ && !/192\.168\./ {print $NF}')
if [ -n "$public_interface" ]; then
ip link set down dev "$public_interface"
else
echo "Public interface not found."
fi
Пример скрипта для выключения сетевого интерфейса с публичным IPv4-адресом:
#!/usr/bin/env python3
import subprocess
import re
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
def disable_public_interface():
logging.info('Starting disable_public_interface function.')
output = subprocess.check_output('ip -4 addr show', shell=True).decode('utf-8')
interfaces = re.findall(r'^\d+: (\S+):.*?\n(?:.*\n)*?\s+inet (\d+\.\d+\.\d+\.\d+)/\d+', output, re.MULTILINE)
public_interfaces = []
for iface, ip in interfaces:
if iface == 'lo':
continue
if re.match(r'^(127\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|192\.168\.)', ip):
continue
public_interfaces.append(iface)
for interface in public_interfaces:
command = ['ip', 'link', 'set', 'dev', interface, 'down']
try:
subprocess.run(command, check=True)
logging.info(f'Successfully disabled interface: {interface}')
except subprocess.CalledProcessError as e:
logging.error(f'Failed to disable interface: {interface}, error: {e}')
if __name__ == "__main__":
logging.info('Script started.')
disable_public_interface()
logging.info('Script finished.')
Настроить конфигурации контейнеров для установки ОС с приложением Containers Ready
При установке ОС с приложением Containers Ready вы можете с помощью скрипта в поле User data настроить конфигурации контейнеров. Чтобы открывать панель Portainer по домену, нужно в поле User data вставить скрипт:
#cloud-config
write_files:
- path: "/opt/containers/docker-compose.yaml"
permissions: "0644"
content: |
version: "3.9"
services:
<containers>
- path: "/opt/containers/.env"
permissions: "0644"
content: |
<environment_variables>
- path: "/opt/user-values.yaml"
permissions: "0644"
content: |
portainer_use_le: true
portainer_domain: "<example.com>"
portainer_le_email: "<root@example.com>"
Укажите:
-
<containers>— содержимое файла Docker Compose для файлаdocker-compose.yaml. Подробнее в инструкции docker compose документации Docker; -
<environment_variables>— переменные окружения для файла.env. Если файл не нужен, удалите блок кода. Подробнее в инструкции Use environment variables документации Docker; -
в блоке кода
content:для файла/opt/user-values.yamlукажите параметры конфигурации для Portainer:portainer_use_le: true— параметр для автоматического выпуска TLS(SSL)-сертификата от Let’s Encrypt®;<example.com>— домен для доступа к Portainer. Чтобы домен открывался по публичному IP-адресу сервера, в панели управления своего DNS-хостинга добавьте А-запись и укажите в значении записи публичный IP-адрес сервера. IP-адрес можно скопировать в панели управления: в верхнем меню нажмите Продукты → Выделенные серверы → страница сервера → вкладка Операционная система → в поле IP нажмите . Если домен делегирован в DNS-хостинг Servercore (actual), используйте инструкцию Добавить ресурсную запись. После установки ОС для домена автоматически выпустится TLS(SSL)-сертификат от Let’s Encrypt®. При ошибке выпуска TLS(SSL)-сертификата панель Portainer будет доступна по IP-адресу сервера;<root@example.com>— электронная почта администратора Containers Ready для создания аккаунта и получения уведомлений Let’s Encrypt®.