Skip to content

Commit

Permalink
Merge branch 'advanced-corosync-options'
Browse files Browse the repository at this point in the history
  • Loading branch information
tomjelinek committed Mar 15, 2022
2 parents d2ec07a + 65b659c commit e8b1e2f
Show file tree
Hide file tree
Showing 16 changed files with 656 additions and 32 deletions.
4 changes: 2 additions & 2 deletions .ansible-lint
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
---
skip_list:
- '106' # Role name does not match ^[a-z][a-z0-9_]+$ pattern
- '701' # ignore meta/requirements.yml
- '106' # Role name does not match ^[a-z][a-z0-9_]+$ pattern
- '701' # ignore meta/requirements.yml
165 changes: 157 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ An Ansible role for managing High Availability Clustering.
repositories accessible.
* The role replaces the configuration of HA Cluster on specified nodes. Any
settings not specified in the role variables will be lost.
* For now, the role is capable of configuring:
* a basic corosync cluster
* The role is capable of configuring:
* single-link or multi-link cluster
* Corosync transport options including compression and encryption
* Corosync totem options
* Corosync quorum options
* SBD
* pacemaker cluster properties
* Pacemaker cluster properties
* stonith and resources
* resource constraints

Expand Down Expand Up @@ -67,7 +70,7 @@ https://docs.ansible.com/ansible/latest/user_guide/vault.html for details.

#### `ha_cluster_corosync_key_src`

path to corosync authkey file, default: `null`
path to Corosync authkey file, default: `null`

Authentication and encryption key for Corosync communication. It is highly
recommended to have a unique value for each cluster. The key should be 256
Expand All @@ -85,7 +88,7 @@ If this variable is set, `ha_cluster_regenerate_keys` is ignored for this key.

#### `ha_cluster_pacemaker_key_src`

path to pacemaker authkey file, default: `null`
path to Pacemaker authkey file, default: `null`

Authentication and encryption key for Pacemaker communication. It is highly
recommended to have a unique value for each cluster. The key should be 256
Expand Down Expand Up @@ -178,6 +181,98 @@ string, default: `my-cluster`

Name of the cluster.

#### `ha_cluster_transport`

structure, default: no settings

```yaml
ha_cluster_transport:
type: knet
options:
- name: option1_name
value: option1_value
- name: option2_name
value: option2_value
links:
-
- name: option1_name
value: option1_value
- name: option2_name
value: option2_value
-
- name: option1_name
value: option1_value
- name: option2_name
value: option2_value
compression:
- name: option1_name
value: option1_value
- name: option2_name
value: option2_value
crypto:
- name: option1_name
value: option1_value
- name: option2_name
value: option2_value
```

* `type` (optional) - Transport type: `knet`, `udp` or `udpu`. Defaults to
`knet` if not specified.
* `options` (optional) - List of name-value dictionaries with transport options.
* `links` (optional) - List of lists of name-value dictionaries. Each list of
name-value dictionaries holds options for one Corosync link. It is
recommended to set `linknumber` value for each link. Otherwise, the first
list of dictionaries is assigned to the first link, the second one to the
second link and so on.
* `compression` (optional) - List of name-value dictionaries configuring
transport compression.
* `crypto` (optional) - List of name-value dictionaries configuring transport
encryption. By default, encryption is enabled.

For a list of allowed options, see `pcs -h cluster setup` or `pcs(8)` man page,
section 'cluster', command 'setup'. For a detailed description, see
`corosync.conf(5)` man page.

You may take a look at [an example](#advanced-corosync-configuration).

#### `ha_cluster_totem`

structure, default: no totem settings

```yaml
ha_cluster_totem:
options:
- name: option1_name
value: option1_value
- name: option2_name
value: option2_value
```

Corosync totem configuration. For a list of allowed options, see `pcs -h
cluster setup` or `pcs(8)` man page, section 'cluster', command 'setup'. For a
detailed description, see `corosync.conf(5)` man page.

You may take a look at [an example](#advanced-corosync-configuration).

#### `ha_cluster_quorum`

structure, default: no quorum settings

```yaml
ha_cluster_quorum:
options:
- name: option1_name
value: option1_value
- name: option2_name
value: option2_value
```

Cluster quorum configuration. For now, it is possible to configure quorum
options: `auto_tie_breaker`, `last_man_standing`, `last_man_standing_window`,
`wait_for_all`. Quorum options are documented in `votequorum(5)` man page.

You may take a look at [an example](#advanced-corosync-configuration).

#### `ha_cluster_sbd_enabled`

boolean, default: `no`
Expand Down Expand Up @@ -214,7 +309,7 @@ ha_cluster_cluster_properties:
value: property2_value
```

List of sets of cluster properties - pacemaker cluster-wide configuration.
List of sets of cluster properties - Pacemaker cluster-wide configuration.
Currently, only one set is supported.

You may take a look at [an example](#configuring-cluster-properties).
Expand Down Expand Up @@ -254,7 +349,7 @@ ha_cluster_resource_primitives:
value: operation2_attribute2_value
```

This variable defines pacemaker resources (including stonith) configured by the
This variable defines Pacemaker resources (including stonith) configured by the
role. The items are as follows:

* `id` (mandatory) - ID of a resource.
Expand All @@ -272,7 +367,7 @@ role. The items are as follows:
* `meta_attrs` (optional) - List of sets of the resource's meta attributes.
Currently, only one set is supported.
* `operations` (optional) - List of the resource's operations.
* `action` (mandatory) - Operation action as defined by pacemaker and the
* `action` (mandatory) - Operation action as defined by Pacemaker and the
resource or stonith agent.
* `attrs` (mandatory) - Operation options, at least one option must be
specified.
Expand Down Expand Up @@ -720,6 +815,9 @@ all:

## Example Playbooks

Following examples show what the structure of the role variables looks like.
They are not guides or best practices for configuring a cluster.

### Creating a cluster running no resources
```yaml
- hosts: node1 node2
Expand All @@ -731,6 +829,57 @@ all:
- linux-system-roles.ha_cluster
```

### Advanced Corosync configuration
```yaml
- hosts: node1 node2
vars:
ha_cluster_cluster_name: my-new-cluster
ha_cluster_hacluster_password: password
ha_cluster_transport:
type: knet
options:
- name: ip_version
value: ipv4-6
- name: link_mode
value: active
links:
-
- name: linknumber
value: 1
- name: link_priority
value: 5
-
- name: linknumber
value: 0
- name: link_priority
value: 10
compression:
- name: level
value: 5
- name: model
value: zlib
crypto:
- name: cipher
value: none
- name: hash
value: none
ha_cluster_totem:
options:
- name: block_unlisted_ips
value: 'yes'
- name: send_join
value: 0
ha_cluster_quorum:
options:
- name: auto_tie_breaker
value: 1
- name: wait_for_all
value: 1
roles:
- linux-system-roles.ha_cluster
```

### Configuring cluster to use SBD
```yaml
- hosts: node1 node2
Expand Down
4 changes: 4 additions & 0 deletions defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ ha_cluster_pcsd_private_key_src: null

ha_cluster_cluster_name: my-cluster

ha_cluster_transport: {}
ha_cluster_totem: {}
ha_cluster_quorum: {}

ha_cluster_sbd_enabled: no
ha_cluster_sbd_options: []

Expand Down
50 changes: 50 additions & 0 deletions examples/advanced-corosync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# SPDX-License-Identifier: MIT
---
- name: Example ha_cluster role invocation - advanced Corosync configuration
hosts: all
vars:
ha_cluster_cluster_name: my-new-cluster
ha_cluster_hacluster_password: password
ha_cluster_transport:
type: knet
options:
- name: ip_version
value: ipv4-6
- name: link_mode
value: active
links:
-
- name: linknumber # yamllint disable-line rule:hyphens
value: 1
- name: link_priority
value: 5
-
- name: linknumber # yamllint disable-line rule:hyphens
value: 0
- name: link_priority
value: 10
compression:
- name: level
value: 5
- name: model
value: zlib
crypto:
- name: cipher
value: none
- name: hash
value: none
ha_cluster_totem:
options:
- name: block_unlisted_ips
value: 'yes'
- name: send_join
value: 0
ha_cluster_quorum:
options:
- name: auto_tie_breaker
value: 1
- name: wait_for_all
value: 1

roles:
- linux-system-roles.ha_cluster
24 changes: 24 additions & 0 deletions tasks/check-and-prepare-role-variables.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,27 @@
| map('extract', hostvars, '__ha_cluster_node_name')
| list
}}"

- name: Figure out if ATB needs to be enabled for SBD
set_fact:
# SBD needs ATB enabled if all of these are true:
# - sbd does not use devices (In check-and-prepare-role-variables.yml it
# is verified that all nodes have the same number of devices defined.
# Therefore it is enough to check devices of any single node.)
# - number of nodes is even
# - qdevice is not used
__ha_cluster_sbd_needs_atb: "{{
ha_cluster_sbd_enabled
and not ha_cluster.sbd_devices | default([])
and __ha_cluster_all_node_names | length is even
and not __ha_cluster_qdevice_in_use
}}"

- name: Fail if SBD needs ATB enabled and the user configured ATB to be disabled
fail:
msg: Cannot set auto_tie_breaker to disabled when SBD needs it to be enabled
when:
- __ha_cluster_sbd_needs_atb | bool
- ha_cluster_quorum.options | default([])
| selectattr('name', 'match', '^auto_tie_breaker$')
| map(attribute='value') | select('in', ['0', 0]) | list | length > 0
51 changes: 49 additions & 2 deletions tasks/cluster-setup-pcs-0.10.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,55 @@
addr={{ addr | quote }}
{% endfor %}
{% endfor %}
{% if __ha_cluster_sbd_needs_atb | default(false) %}
quorum auto_tie_breaker=1
{% if ha_cluster_transport | default({}) %}
transport {{ ha_cluster_transport.type | default('knet') | quote }}
{% for option in ha_cluster_transport.options | default([]) %}
{{ option.name | quote }}={{ option.value | quote }}
{% endfor %}
{% for link in ha_cluster_transport.links | default([]) %}
link
{% for option in link %}
{{ option.name | quote }}={{ option.value | quote }}
{% endfor %}
{% endfor %}
{% if ha_cluster_transport.compression | default([]) %}
compression
{% for option in ha_cluster_transport.compression %}
{{ option.name | quote }}={{ option.value | quote }}
{% endfor %}
{% endif %}
{% if ha_cluster_transport.crypto | default([]) %}
crypto
{% for option in ha_cluster_transport.crypto %}
{{ option.name | quote }}={{ option.value | quote }}
{% endfor %}
{% endif %}
{% endif %}
{% if ha_cluster_totem.options | default([]) %}
totem
{% for option in ha_cluster_totem.options %}
{{ option.name | quote }}={{ option.value | quote }}
{% endfor %}
{% endif %}
{%
if __ha_cluster_sbd_needs_atb | default(false)
or ha_cluster_quorum.options | default([])
%}
quorum
{% for option in ha_cluster_quorum.options | default([]) %}
{% if
not __ha_cluster_sbd_needs_atb | default(false)
or option.name != 'auto_tie_breaker'
%}
{{ option.name | quote }}={{ option.value | quote }}
{% endif %}
{% endfor %}
{% if __ha_cluster_sbd_needs_atb | default(false) %}
auto_tie_breaker=1
{% endif %}
{% endif %}
run_once: yes
# We always need to create corosync.conf file to see whether it's the same as
Expand Down
6 changes: 0 additions & 6 deletions tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,6 @@
- name: Distribute fence-virt authkey
include_tasks: distribute-fence-virt-key.yml

# TODO: implement qdevice detection once qdevice is supported by the role
- name: Check if qdevice is configured
set_fact:
__ha_cluster_qdevice_in_use: no
run_once: yes

- name: Configure SBD
include_tasks: sbd.yml

Expand Down
Loading

0 comments on commit e8b1e2f

Please sign in to comment.