Proxmox и ZFS — значительное потребление памяти

При использовании ProxmoxVE с ZFS, при работе виртуальных машин, память на хосте постепенно расходуется до полного исчерпания, результатом чего может стать выключение виртуальных машин:

kernel: [1123659.062155] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/qemu.slice/104.scope,task=kvm,pid=1045923,uid=0
kernel: [1123659.062203] Out of memory: Killed process 1045923 (kvm) total-vm:10639204kB, anon-rss:8332420kB, file-rss:2320kB, shmem-rss:4kB, UID:0 pgtables:17172kB oom_score_adj:0
kernel: [1123660.010306] oom_reaper: reaped process 1045923 (kvm), now anon-rss:0kB, file-rss:68kB, shmem-rss:4kB
systemd1: 104.scope: A process of this unit has been killed by the OOM killer.

Следует понимать, что ZFS требовательна к памяти сервера и по умолчанию использует 50% установленной памяти для ARC (Adaptive Replacement Cache). Текущие минимальные и максимальные пределы можно посмотреть командой:

cat /proc/spl/kstat/zfs/arcstats

где c_min и c_max являются таковыми.

Изменить используемые в настоящее время лимиты можно, установив значения в байтах в файлах /sys/module/zfs/parameters/zfs_arc_min и /sys/module/zfs/parameters/zfs_arc_max соответственно, например командой:

echo «$[10 * 1024*1024*1024]» >/sys/module/zfs/parameters/zfs_arc_max

где 10 — максимальный предел выделяемой памяти в ГБ.

Чтобы изменить максимальный предел ARC навсегда, необходимо добавить в файл /etc/modprobe.d/zfs.conf опцию:

options zfs zfs_arc_max=8589934592

где 8589934592 — устанавливаемый предел в 8 ГБ ОЗУ.

Если корневая файловая система также на ZFS, то после изменения лимитов, необходимо обновить образ initramfs:

update-initramfs -u

После чего требуется перезагрузить сервер.

NginX — установка бесплатных SSL-сертификатов для нескольких сайтов

  1. Создаем пользователя letsencrypt и необходимые директории:

  2. adduser —home /var/www/challenges \
    —shell /bin/sh \
    —disabled-password \
    —disabled-login \
    letsencrypt
    mkdir -p /etc/letsencrypt/domains

  3. Создаём основные приватные ключи:

  4. cd /etc/letsencrypt/
    openssl dhparam -out dhparam.pem 2048
    openssl genrsa 4096 > account.key

  5. Скачиваем клиент acme_tiny.py:

  6. cd /var/www/challenges
    wget https://raw.githubusercontent.com/diafygi/acme-tiny/master/acme_tiny.py

  7. Создаем сценарий /var/www/challenges/acme-tiny.sh, для автоматизации. Изменив значение переменной DOMAINS, указываем имена доменов, для которых необходимо получить сертификаты:
  8. DOMAINS=( site1.ru site2.com )
    DOMAIN_ROOT=/etc/letsencrypt/domains
    ACCOUNT_KEY=/etc/letsencrypt/account.key
    ACME_DIR=/var/www/challenges
    ACME_TINY=${ACME_DIR}/acme_tiny.py
    
    [ -d ${DOMAIN_ROOT} ] || { echo "ERROR: DOMAIN_ROOT dir does not exists"; exit 1; }
    [ -f ${ACCOUNT_KEY} ] || { echo "ERROR: ACCOUNT_KEY not found."; exit 1; }
    [ -d ${ACME_DIR} ] || { echo "ERROR: ACME_DIR dir does not exists"; exit 1; }
    [ -f "$ACME_TINY" ] || { echo "ERROR: ACME_TINY not found."; exit 1; }
    
    wget -O - https://letsencrypt.org/certs/lets-encrypt-x3-cross-signed.pem > ${DOMAIN_ROOT}/intermediate.pem
    
    for DOMAIN in "${DOMAINS[@]}"
    do
      if [ ! -f "${DOMAIN_ROOT}/${DOMAIN}.key" ]; then
        echo "INFO: Generation private key for $DOMAIN";
        openssl genrsa 4096 > ${DOMAIN_ROOT}/${DOMAIN}.key
        openssl req -new -sha256 -key ${DOMAIN_ROOT}/${DOMAIN}.key -subj "/CN=${DOMAIN}" > ${DOMAIN_ROOT}/${DOMAIN}.csr
      fi
    
      echo "INFO: Generation cert for $DOMAIN";
      python ${ACME_TINY} --account-key ${ACCOUNT_KEY} --csr ${DOMAIN_ROOT}/${DOMAIN}.csr --acme-dir ${ACME_DIR} > ${DOMAIN_ROOT}/${DOMAIN}.crt || exit 1
      cat ${DOMAIN_ROOT}/${DOMAIN}.crt ${DOMAIN_ROOT}/intermediate.pem > ${DOMAIN_ROOT}/${DOMAIN}.pem
    done
    
    sudo service nginx reload
    
  9. Меняем права на директории:

  10. chmod 755 /etc/letsencrypt
    chown -R letsencrypt: /etc/letsencrypt /var/www/challenges

  11. Создаём файл /etc/nginx/acme:
  12. location ^~ /.well-known/acme-challenge/ {
        alias /var/www/challenges/;
        try_files $uri =404;
        allow all;
    }
    
  13. В конфигурационный файл nginx каждого сайта, в блок server, добавляем строку:

  14. include /etc/nginx/acme;

  15. Запускаем скрипт:

  16. /bin/bash /var/www/challenges/acme-tiny.sh

  17. Включаем шифрование, добавив в конфигурационные файлы nginx каждого сайта:
  18. server {
        server_name site1.ru www.site1.ru;
        listen 80;
    
        include acme;
        # включим переадресацию на https-версию сайта
        location / {
            return 301 https://$host$request_uri;
        }
    }
    
    server {
            server_name site1.ru www.site1.ru;
            listen 443 ssl;
    
            # включим шифрование
            ssl on;
            ssl_certificate /etc/letsencrypt/domains/alluborka.ru.pem;
            ssl_certificate_key /etc/letsencrypt/domains/alluborka.ru.key;
            ssl_dhparam /etc/letsencrypt/dhparam.pem;
    
            ssl_stapling on;
            ssl_stapling_verify on;
    
            # исключим возврат на http-версию сайта
            add_header Strict-Transport-Security "max-age=31536000";
    
            # явно "сломаем" все картинки с http://
            add_header Content-Security-Policy "img-src https: data:; upgrade-insecure-requests";
    
        ...
    }
    
  19. Для автоматического продления сертификатов, создадим файл /etc/cron.d/letsencrypt:
  20. SHELL=/bin/sh
    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    0 0 1 * * letsencrypt /bin/bash /var/www/challenges/acme-tiny.sh >> /var/log/acme_tiny.log
    
  21. Создадим файлы журналов:

  22. sudo touch /var/log/acme_tiny.log
    sudo chown letsencrypt: /var/log/acme_tiny.log

https://superuserdo.info/?p=747

PHP — Fatal error: Call to undefined function mb_internal_encoding

В журнал вэб-сервера записываются ошибки Call to undefined function mb_internal_encoding.
Сие говорит о том, что: либо эта функция отключена директивой disable_functions (настройки в php.ini или в конфигурационном файле сайта, в директории pool.d), либо отключен модуль mbstring.so (закомментирован в файле 20-mbstring.ini в директории conf.d), либо модуль mbstring не установлен (пакет php*.*-mbstring).
Проверяем, установлен ли пакет:

dpkg —get-selections | grep mbstring

В случае отсутствия оного, ищем доступные версии:

apt-cache search mbstring

Выбираем версию, соответствующую версии установленного PHP интерпретатора, и устанавливаем её:

apt-get install php5.6-mbstring

Если же пакет уже был установлен, то правим конфигурационные файлы.

PHP — Fatal error: Call to undefined function utf8_encode

В журнал вэб-сервера записываются ошибки Call to undefined function utf8_encode.
Сие говорит о том, что: либо эта функция отключена директивой disable_functions (настройки в php.ini или в конфигурационном файле сайта, в директории pool.d), либо отключен модуль xml.so (закомментирован в файле 15-xml.ini в директории conf.d), либо модуль xml не установлен (пакет php*.*-xml).
Проверяем, установлен ли пакет с расширением для PHP:

dpkg —get-selections | grep xml

В случае отсутствия оного, ищем доступные версии:

apt-cache search xml

Выбираем версию, соответствующую версии установленного PHP интерпретатора, и устанавливаем её:

apt-get install php5.6-xml

Если же пакет уже был установлен, то правим конфигурационные файлы.

mount error(121): Remote I/O error

В Linux, при попытке монтирования по локальной сети Windows-папки с общим доступом, отображается следующая ошибка:
CIFS VFS: cifs_mount failed w/return code = -121
mount error(121): Remote I/O error
Refer to the mount.cifs(8) manual page (e.g. man mount.cifs)

Проблема находится на стороне Windows и решается путём правки значений реестра:
записи HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\LargeSystemCache устанавливаем значение 1;
записи HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters\Size устанавливаем значение 3.

Proxmox — расширение хранилища

При развёртывании в виртуальной машине Proxmox VE (на чистую машину), в процессе использования, место хранилища под KVM закончилось. Потребовалось увеличить выделенное место жесткого диска для виртуальной машины с Proxmox. После увеличения выделенного места, путём изменения настроек виртуальной машины, встаёт необходимость произвести расширение файловой системы, используемой Proxmox. При попытке выполнить задачу, у пользователей могут возникать следующие ошибки:

  • The util fdisk doesn’t support GPT. Use GNU Parted
  • resize2fs: Device or resource busy while trying to open /dev/sda3
  • Insufficient free space: 1 extents needed, but only 0 available with 32.83g available.


Порядок выполнения действий:

  1. Остановим виртуальные машины: qm shutdown all
  2. Размонтируем логический том хранилища KVM: umount /var/lib/vz
  3. Запустим редактор разделов для жесткого диска sda: parted /dev/sda
  4. Командой resizepart 3 увеличим размер раздела lvm.
  5. Увеличим размер физического диска LVM: pvresize /dev/sda3.
  6. Увеличим размер логического диска LVM: lvextend /dev/pve/data -l +100%FREE
  7. Увеличим размер файловой системы логического диска: resize2fs /dev/pve/data
  8. Проверим и исправим файловую систему: fsck -f /dev/mapper/pve-data
  9. Монтируем том хранилища: mount /var/lib/vz
  10. Перезагрузим систему: reboot

При нестандартных настройках разделов диска:

  • Список дисков и их разделов выводится командой fdisk -l.
  • Номера разделов в программе parted выводятся командой print. Нас интересует номер раздела lvm.
  • Список физических дисков LVM выводится командой pvdisplay.
  • Список логических дисков LVM выводится командой lvdisplay.
  • Список файловых систем выводится командой df -h.

Exim4/Postfix: Network is unreachable

В журнале Exim4 или Postfix периодически появляются записи вида: aspmx.l.google.com [2a00:1450:4010:c08::1b] Network is unreachable.
Используемый MTA (Exim4 или Postfix) пытается подключиться к SMTP Google по протоколу IPv6, но этого не удаётся сделать, по причине отсутствия поддержки IPv6 в используемой сети или конфигурации сетевых интерфейсов.
Для решения проблемы, требуется отключить использование протокола IP 6 версии.
Для Exim4, конфигурационном файле /etc/exim4/exim4.conf.template, в начале файла, перед секцией begin acl необходимо вписать:

disable_ipv6 = true

После чего, необходимо перезагрузить Exim4 командой /etc/init.d/exim4 restart.
Для Postfix, конфигурационном файле /etc/postfix/main.cf, необходимо отредактировать директиву:

inet_protocols = ipv4

После чего, необходимо перезагрузить Postfix командой /etc/init.d/postfix restart.

P.S.: Если Вы всё таки решите задействовать протокол IPv6, не забудьте указать свой IPv6 адрес в DNS записях, чтобы не возникло проблемы с прохождением проверки SPF-записи.

gem: unable to convert U+00A9 from UTF-8 to US-ASCII

При использовании команды gem install, отображаются сообщения о пропуске установки файлов Ruby из-за ошибки конвертации символов из таблицы UTF-8 в US-ASCII.
Вероятнее всего, в системе не была выставлена подходящая кодировка. В этом случае решить проблему можно, выбрав в качестве используемой кодировки ru_RU.UTF-8, используя команду:

dpkg-reconfigure locales

Exim4 — Не доходит отправляемая почта

В журнале Exim4 /var/log/exim4/mainlog постоянно пополняются записи:

Our system has detected an unusual rate of\n421-4.7.0 unsolicited mail originating from your IP address. To protect our\n421-4.7.0 users from spam, mail sent from your IP address has been temporarily\n421-4.7.0 rate limited.

Сие говорит о том, что сервер-получатель отвергает корреспонденцию из-за подозрения на спам (слишком частые отправления писем). Следует отследить в журнале почтовые адреса, от имени которых отправляются письма. Если почтовые адреса отправителей Вам не известны, то скорее всего вредоносный код генерирует рассылку, от имени несуществующих почтовых адресов, подключенных доменов.
Следует посмотреть объем неотправленных сообщений в директории /var/spool/exim4/input. Если сообщения содержат спам и их объём велик — следует выявить вредоносный код, генерирующий эти письма.
К примеру, если сервер используется для работы сайтов, написанных на PHP, то для обнаружения вредоносного кода следует изучить журнал /var/log/php-mail.log. По количеству генерируемых сообщений, обнаружить вредный сценарий довольно просто.
После устранения источника проблемы, следует остановить почтовый сервер командой killall -9 exim4 (команда service exim4 stop вероятнее всего не прервёт процесс отправки замороженных почтовых сообщений). И затем очистить директорию со скопившейся корреспонденцией, командой find /var/spool/exim4/input -delete. После чего, почтовый сервер можно запустить вновь: service exim4 start.
Для пресечения подобной проблемы в будущем, можно ограничить список адресов, корреспонденция с которых будет отправляться сервером Exim4.

GPG error — NO_PUBKEY

Бывают случаи, когда при выполнении команды apt-get update, выводится ошибка, где упоминается GPG:

W: A error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://www.deb-multimedia.org stable Release: The following signatures couldn’t be verified because the public key is not available: NO_PUBKEY 5C808C2B65558117

Номер публичного ключа при этом может быть иным.
Решением проблемы является добавление в систему публичного GnuPG-ключа репозитория, из которого осуществляется попытка установить пакет (который, в свою очередь, подписан данным ключом):

gpg --keyserver pgpkeys.mit.edu --recv-key 5C808C2B65558117
gpg -a --export 5C808C2B65558117 | apt-key add -