[ English | English (United Kingdom) | Deutsch | русский ]
HAProxy и Keepalived внутри LXC контейнеров¶
Может быть вариант использования, когда вы захотите запустить HAProxy и Keepalived внутри контейнеров LXC. Например, запуск этих служб на физических серверах предполагает, что маршрут по умолчанию для хостов должен быть установлен в направлении публичной сети. Этот сценарий может быть непредпочтительным для некоторых развертываний, особенно в случаях, когда у вас нет отдельных балансировщиков нагрузки, но они размещены вместе с другими инфраструктурными службами.
Определение inventory¶
Чтобы указать dynamic_inventory сгенерировать набор контейнеров для HAProxy, необходимо создать файл /etc/openstack_deploy/env.d/haproxy.yml
со следующим содержимым:
---
# This file contains an example to show how to set
# the cinder-volume service to run in a container.
#
# Important note:
# In most cases you need to ensure that default route inside of the
# container doesn't go through eth0, which is part of lxcbr0 and
# SRC nat-ed. You need to pass "public" VIP interface inside of the
# container and ensure "default" route presence on it.
container_skel:
haproxy_container:
properties:
is_metal: false
Настройка сети хоста¶
Чтобы сделать публичную сеть доступной, вам необходимо обеспечить наличие соответствующего моста на ваших хостах, к которому будут подключены контейнеры HAProxy с одной стороны пары veth. Мост также должен содержать интерфейс VLAN, обеспечивающий «публичное» подключение.
Вы можете создать мост вручную или использовать нашу роль systemd_networkd, которая способна настраивать необходимые сетевые подключения на хостах.
Для примера ниже давайте назовем наш мост br-public-api
и публичный vlan с идентификатором 40
. В вашем user_variables.yml
определите следующие переменные:
_systemd_networkd_generic_devices:
- NetDev:
Name: bond0
Kind: bond
Bond:
Mode: 802.3ad
TransmitHashPolicy: layer3+4
LACPTransmitRate: fast
MIIMonitorSec: 100
filename: 05-generic-bond0
_systemd_networkd_public_api_devices:
- NetDev:
Name: vlan-public-api
Kind: vlan
VLAN:
Id: 40
filename: 10-openstack-vlan-public-api
- NetDev:
Name: br-public-api
Kind: bridge
Bridge:
ForwardDelaySec: 0
HelloTimeSec: 2
MaxAgeSec: 12
STP: off
filename: 11-openstack-br-public-api
openstack_hosts_systemd_networkd_devices: |-
{% set devices = [] %}
{% if is_metal %}
{% set _ = devices.extend(_systemd_networkd_generic_devices) %}
{% if inventory_hostname in groups['haproxy_hosts'] %}
{% set _ = devices.extend(_systemd_networkd_public_api_devices) %}
{% endif %}
{% endif %}
{{ devices }}
_systemd_networkd_bonded_networks:
- interface: ens3
filename: 05-generic-ens3
bond: bond0
link_config_overrides:
Match:
MACAddress: df:25:83:e1:77:c8
- interface: ens6
filename: 05-generic-ens6
bond: bond0
link_config_overrides:
Match:
MACAddress: df:25:83:e1:77:c9
- interface: bond0
filename: 05-general-bond0
vlan:
- vlan-public-api
_systemd_networkd_public_api_networks:
- interface: "vlan-public-api"
bridge: "br-public-api"
filename: 10-openstack-vlan-public-api
- interface: "br-public-api"
filename: "11-openstack-br-public-api"
openstack_hosts_systemd_networkd_networks: |-
{% set networks = [] %}
{% if is_metal %}
{% set _ = networks.extend(_systemd_networkd_bonded_networks) %}
{% if inventory_hostname in groups['haproxy_hosts'] %}
{% set _ = networks.extend(_systemd_networkd_public_api_networks) %}
{% endif %}
{% endif %}
{{ networks }}
Настройка сети контейнера¶
В случае развертывания HAProxy внутри LXC необходимо обеспечить подключение к публичной сети и то, что haproxy_bind_external_lb_vip_address
будет присутствовать внутри контейнера, а external_lb_vip_address
будет доступен.
Для этого нам необходимо выполнить следующие изменения в файле openstack_user_config.yml
.
В
cidr_networks
добавьте сеть, которая должна использоваться как «публичная» сеть для доступа к API. Например, мы будем использовать 203.0.113.128/28:
cidr_networks: ... public_api: 203.0.113.128/28
В
used_ips
вам необходимо зарезервировать IP-адрес для вашего шлюза иhaproxy_keepalived_external_vip_cidr
/external_lb_vip_address
used_ips: ... - "203.0.113.129" - "203.0.113.140-203.0.113.142"
В
provider_networks
необходимо определить новую сеть контейнеров и назначить ее группе HAproxy.global_overrides: ... provider_networks: ... - network: group_binds: - haproxy type: "raw" container_bridge: "br-public-api" container_interface: "eth20" container_type: "veth" ip_from_q: public_api static_routes: - cidr: 0.0.0.0/0 gateway: 203.0.113.129
Хотя все эти изменения необходимо внести в openstack_user_config.yml
, необходимо применить еще одно переопределение.
Как вы могли заметить, мы определяем маршрут по умолчанию для контейнера через eth20. Однако по умолчанию все контейнеры имеют свой маршрут по умолчанию через eth0, который является локальным мостом LXC, где адрес получается через DHCP. Чтобы избежать конфликта, вам нужно убедиться, что маршрут по умолчанию не будет установлен для eth0 внутри контейнера. Для этого создайте файл /etc/openstack_deploy/group_vars/haproxy со следующим содержимым:
---
lxc_container_networks:
lxcbr0_address:
bridge: "{{ lxc_net_bridge | default('lxcbr0') }}"
bridge_type: "{{ lxc_net_bridge_type | default('linuxbridge') }}"
interface: eth0
type: veth
dhcp_use_routes: False
Настройка привязки HAProxy внутри контейнеров¶
Поскольку предоставление IP-адресов внутри контейнеров довольно случайно, не всегда может быть удобно привязывать HAProxy к определенному IP-адресу. Если это так, вы можете привязать HAProxy к интерфейсу, поскольку мы всегда знаем имена интерфейсов внутри контейнеров. При этом предполагается, что публичные/внутренние VIP-адреса keepalived будут добавлены в used_ips
, поэтому вы по-прежнему можете свободно их определять.
В примере ниже показано возможное содержимое user_variables.yml
:
haproxy_bind_external_lb_vip_interface: eth20
haproxy_bind_internal_lb_vip_interface: eth1
haproxy_bind_external_lb_vip_address: "*"
haproxy_bind_internal_lb_vip_address: "*"
haproxy_keepalived_external_vip_cidr: 203.0.113.140/32
haproxy_keepalived_internal_vip_cidr: 172.29.236.9/32
haproxy_keepalived_external_interface: "{{ haproxy_bind_external_lb_vip_interface }}"
haproxy_keepalived_internal_interface: "{{ haproxy_bind_internal_lb_vip_interface }}"
В качестве альтернативы вы можете обнаружить IP-адреса, используемые внутри ваших контейнеров для настройки привязок HAProxy. Это можно сделать, обратившись к сопоставлению container_networks
:
haproxy_bind_external_lb_vip_address: "{{ container_networks['public_api_address']['address'] }}"
haproxy_bind_internal_lb_vip_address: "{{ container_networks['management_address']['address'] }}"
Создание контейнеров¶
После того, как все шаги выше выполнены, пришло время создать наши новые контейнеры HAProxy. Для этого выполните следующую команду:
# openstack-ansible playbooks/lxc-containers-create.yml --limit haproxy,lxc_hosts