tripleo-heat-templates/deployment/database/redis-pacemaker-puppet.yaml
Michele Baldessari 84c85aaff3 Fix redis_tls_proxy
Since we merged the pcs-host patches we erroneously also removed
the sidecar container that does the tls stunneling for redis.
This is needed to allow the redis master stream the deplications to
its slaves via TLS.

Tested this and we now correctly get the working container and cluster
state:
[root@controller-0 ~]# podman ps -a |grep redis
4182a78811a2  undercloud-0.ctlplane.redhat.local:8787/openstack-redis:16.2_20210218.1-hotfixupdate2       /bin/bash /usr/lo...  3 minutes ago   Up 3 minutes ago                 redis-bundle-podman-0
604a086bb53c  undercloud-0.ctlplane.redhat.local:8787/openstack-redis:16.2_20210218.1-hotfixupdate2       kolla_start           8 minutes ago   Up 8 minutes ago                 redis_tls_proxy
[root@controller-0 ~]# pcs status |grep redis
  * GuestOnline: [ galera-bundle-0@database-1 galera-bundle-1@database-2 galera-bundle-2@database-0 ovn-dbs-bundle-0@controller-0 ovn-dbs-bundle-1@controller-1 ovn-dbs-bundle-2@controller-2 rabbitmq-bundle-0@messaging-0 rabbitmq-bundle-1@messaging-1 rabbitmq-bundle-2@messaging-2 redis-bundle-0@controller-0 redis-bundle-1@controller-1 redis-bundle-2@controller-2 ]
  * Container bundle set: redis-bundle [cluster.common.tag/openstack-redis:pcmklatest]:
    * redis-bundle-0    (ocf:💓redis):  Master controller-0
    * redis-bundle-1    (ocf:💓redis):  Slave controller-1
    * redis-bundle-2    (ocf:💓redis):  Slave controller-2

We also move the redis_tls_proxy from step_2/start_order: 3 to step_1
since it actually makes sense to have it run before we start the
redis pcmk bundle at step 2 (i.e. so the slave replica can work right
away from the start).

Closes-Bug: #1916873

Change-Id: I44df0ee32e5c35b87f74bdb75dcb384496dfb6ab
2021-02-25 11:41:36 +01:00

489 lines
21 KiB
YAML

heat_template_version: rocky
description: >
OpenStack containerized Redis services
parameters:
ContainerRedisImage:
description: image
type: string
ContainerRedisConfigImage:
description: The container image to use for the redis config_volume
type: string
ClusterCommonTag:
default: false
description: When set to false, a pacemaker service is configured
to use a floating tag for its container image name,
e.g. 'REGISTRY/NAMESPACE/IMAGENAME:pcmklatest'. When
set to true, the service uses a floating prefix as
well, e.g. 'cluster.common.tag/IMAGENAME:pcmklatest'.
type: boolean
ClusterFullTag:
default: false
description: When set to true, the pacemaker service uses a fully
constant tag for its container image name, e.g.
'cluster.common.tag/SERVICENAME:pcmklatest'.
type: boolean
EndpointMap:
default: {}
description: Mapping of service endpoint -> protocol. Typically set
via parameter_defaults in the resource registry.
type: json
ServiceData:
default: {}
description: Dictionary packing service data
type: json
ServiceNetMap:
default: {}
description: Mapping of service_name -> network name. Typically set
via parameter_defaults in the resource registry. This
mapping overrides those in ServiceNetMapDefaults.
type: json
RoleName:
default: ''
description: Role name on which the service is applied
type: string
RoleParameters:
default: {}
description: Parameters specific to the role
type: json
ConfigDebug:
default: false
description: Whether to run config management (e.g. Puppet) in debug mode.
type: boolean
EnableInternalTLS:
type: boolean
default: false
RedisIPv6:
default: false
description: Enable IPv6 in Redis
type: boolean
ContainerCli:
type: string
default: 'podman'
description: CLI tool used to manage containers.
constraints:
- allowed_values: ['docker', 'podman']
DeployIdentifier:
default: ''
type: string
description: >
Setting this to a unique value will re-run any deployment tasks which
perform configuration on a Heat stack-update.
parameter_groups:
- label: deprecated
description: |
The following parameters are deprecated and will be removed. They should not
be relied on for new deployments. If you have concerns regarding deprecated
parameters, please contact the TripleO development team on IRC or the
OpenStack mailing list.
parameters:
- RedisIPv6
conditions:
internal_tls_enabled: {equals: [{get_param: EnableInternalTLS}, true]}
docker_enabled: {equals: [{get_param: ContainerCli}, 'docker']}
common_tag_enabled: {equals: [{get_param: ClusterCommonTag}, true]}
common_tag_full: {equals: [{get_param: ClusterFullTag}, true]}
is_ipv6:
equals:
- {get_param: [ServiceData, net_ip_version_map, {get_param: [ServiceNetMap, RedisNetwork]}]}
- 6
resources:
ContainersCommon:
type: ../containers-common.yaml
RedisBase:
type: ./redis-container-puppet.yaml
properties:
EndpointMap: {get_param: EndpointMap}
ServiceData: {get_param: ServiceData}
ServiceNetMap: {get_param: ServiceNetMap}
RoleName: {get_param: RoleName}
RoleParameters: {get_param: RoleParameters}
outputs:
role_data:
description: Role data for the Redis API role.
value:
service_name: redis
firewall_rules:
'108 redis-bundle':
dport:
- 3124
- 6379
- 26379
config_settings:
map_merge:
- {get_attr: [RedisBase, role_data, config_settings]}
- redis::service_manage: false
redis::notify_service: false
redis::managed_by_cluster_manager: true
tripleo::profile::pacemaker::database::redis_bundle::redis_docker_image: &redis_image_pcmklatest
if:
- common_tag_full
- "cluster.common.tag/redis:pcmklatest"
- yaql:
data:
if:
- common_tag_enabled
- yaql:
data: {get_param: ContainerRedisImage}
expression: concat("cluster.common.tag/", $.data.rightSplit(separator => "/", maxSplits => 1)[1])
- {get_param: ContainerRedisImage}
expression: concat($.data.rightSplit(separator => ":", maxSplits => 1)[0], ":pcmklatest")
tripleo::profile::pacemaker::database::redis_bundle::control_port: 3124
tripleo::profile::pacemaker::database::redis_bundle::container_backend: {get_param: ContainerCli}
tripleo::stunnel::manage_service: false
tripleo::stunnel::foreground: 'yes'
tripleo::profile::pacemaker::database::redis_bundle::tls_proxy_bind_ip:
str_replace:
template:
"%{hiera('$NETWORK')}"
params:
$NETWORK: {get_param: [ServiceNetMap, RedisNetwork]}
tripleo::profile::pacemaker::database::redis_bundle::tls_proxy_fqdn:
str_replace:
template:
"%{hiera('fqdn_$NETWORK')}"
params:
$NETWORK: {get_param: [ServiceNetMap, RedisNetwork]}
tripleo::profile::pacemaker::database::redis_bundle::tls_proxy_port: 6379
tripleo::profile::pacemaker::database::redis::tls_proxy_bind_ip:
str_replace:
template:
"%{hiera('$NETWORK')}"
params:
$NETWORK: {get_param: [ServiceNetMap, RedisNetwork]}
tripleo::profile::pacemaker::database::redis::tls_proxy_fqdn:
str_replace:
template:
"%{hiera('fqdn_$NETWORK')}"
params:
$NETWORK: {get_param: [ServiceNetMap, RedisNetwork]}
tripleo::profile::pacemaker::database::redis::tls_proxy_port: 6379
- if:
- internal_tls_enabled
- redis::extra_config_file: "/etc/redis-tls.conf"
tripleo::profile::pacemaker::database::redis_bundle::extra_config_file: "/etc/redis-tls.conf"
tripleo::profile::pacemaker::database::redis_bundle::tls_tunnel_base_port: 6660
tripleo::profile::pacemaker::database::redis_bundle::tls_tunnel_local_name:
if:
- is_ipv6
- '::1'
- '127.0.0.1'
- {}
service_config_settings: {get_attr: [RedisBase, role_data, service_config_settings]}
# BEGIN DOCKER SETTINGS
puppet_config:
config_volume: 'redis'
# NOTE: we need the exec tag to copy /etc/redis.conf.puppet to
# /etc/redis.conf
# https://github.com/arioch/puppet-redis/commit/1c004143223e660cbd433422ff8194508aab9763
puppet_tags: 'exec'
step_config: |
include tripleo::profile::pacemaker::database::redis_bundle
config_image: &redis_config_image {get_param: ContainerRedisConfigImage}
kolla_config:
/var/lib/kolla/config_files/redis.json:
command: /usr/sbin/pacemaker_remoted
config_files:
- dest: /etc/libqb/force-filesystem-sockets
source: /dev/null
owner: root
perm: '0644'
- source: "/var/lib/kolla/config_files/src/*"
dest: "/"
merge: true
preserve_properties: true
optional: true
permissions:
- path: /run/redis
owner: redis:redis
recurse: true
- path: /var/lib/redis
owner: redis:redis
recurse: true
- path: /var/log/redis
owner: redis:redis
recurse: true
/var/lib/kolla/config_files/redis_tls_proxy.json:
command:
# Note: kolla doesn't process string arguments as expected,
# so use a bash idiom to achieve the same result
str_replace:
template:
bash -c $* -- eval /wait-port-and-run.sh $(hiera fqdn_$NETWORK) 6379 stunnel /etc/stunnel/stunnel.conf
params:
$NETWORK: {get_param: [ServiceNetMap, RedisNetwork]}
config_files:
- source: "/var/lib/kolla/config_files/src/*"
dest: "/"
merge: true
preserve_properties: true
- source: "/var/lib/kolla/config_files/src-tls/*"
dest: "/"
merge: true
optional: true
preserve_properties: true
permissions:
- path: /etc/pki/tls/certs/redis.crt
owner: root:root
perm: '0600'
optional: true
- path: /etc/pki/tls/private/redis.key
owner: root:root
perm: '0600'
optional: true
container_config_scripts: {get_attr: [ContainersCommon, container_config_scripts]}
docker_config:
step_1:
if:
- internal_tls_enabled
- redis_tls_proxy:
start_order: 0
image: {get_param: ContainerRedisImage}
net: host
user: root
restart: always
volumes:
list_concat:
- {get_attr: [ContainersCommon, volumes]}
-
- /var/lib/kolla/config_files/redis_tls_proxy.json:/var/lib/kolla/config_files/config.json:ro
- /var/lib/config-data/puppet-generated/redis:/var/lib/kolla/config_files/src:ro
- /etc/pki/tls/certs/redis.crt:/var/lib/kolla/config_files/src-tls/etc/pki/tls/certs/redis.crt:ro
- /etc/pki/tls/private/redis.key:/var/lib/kolla/config_files/src-tls/etc/pki/tls/private/redis.key:ro
- /var/lib/container-config-scripts/wait-port-and-run.sh:/wait-port-and-run.sh:ro
environment:
KOLLA_CONFIG_STRATEGY: COPY_ALWAYS
- {}
metadata_settings:
get_attr: [RedisBase, role_data, metadata_settings]
host_prep_tasks:
- name: create persistent directories
file:
path: "{{ item.path }}"
state: directory
setype: "{{ item.setype }}"
mode: "{{ item.mode|default(omit) }}"
with_items:
- { 'path': /var/lib/redis, 'setype': container_file_t }
- { 'path': /var/log/containers/redis, 'setype': container_file_t, 'mode': '0750' }
- { 'path': /run/redis, 'setype': container_file_t }
- name: ensure /run/redis is present upon reboot
copy:
dest: /etc/tmpfiles.d/run-redis.conf
content: |
d /run/redis 0755 root root - -
deploy_steps_tasks:
- name: Redis tag container image for pacemaker
when: step|int == 1
import_role:
name: tripleo_container_tag
vars:
container_image: {get_param: ContainerRedisImage}
container_image_latest: *redis_image_pcmklatest
- name: Redis HA Wrappers Step
when: step|int == 2
block: &redis_puppet_bundle
- name: Redis puppet bundle
import_role:
name: tripleo_ha_wrapper
vars:
tripleo_ha_wrapper_service_name: redis
tripleo_ha_wrapper_resource_name: redis
tripleo_ha_wrapper_bundle_name: redis-bundle
tripleo_ha_wrapper_resource_state: Slave Master
tripleo_ha_wrapper_puppet_config_volume: redis
tripleo_ha_wrapper_puppet_execute: 'include ::tripleo::profile::base::pacemaker; include ::tripleo::profile::pacemaker::database::redis_bundle'
tripleo_ha_wrapper_puppet_tags: 'pacemaker::resource::bundle,pacemaker::property,pacemaker::resource::ocf,pacemaker::constraint::order,pacemaker::constraint::colocation'
tripleo_ha_wrapper_puppet_debug: {get_param: ConfigDebug}
update_tasks:
- name: redis_pacemaker_puppet_tmpfile_cleanup
when: step|int == 1
block: &redis_pacemaker_puppet_tmpfile_cleanup
- name: Clean old tmpfile configuration
file:
path: /etc/tmpfiles.d/var-run-redis.conf
state: absent
- name: Tear-down non-HA redis container
when:
- step|int == 1
block: &redis_teardown_nonha
- name: Remove non-HA redis container
include_role:
name: tripleo_container_rm
vars:
tripleo_container_cli: "{{ container_cli }}"
tripleo_containers_to_rm:
- redis
- name: Redis fetch and retag container image for pacemaker
when: step|int == 2
block: &redis_fetch_retag_container_tasks
- name: Get container redis image
set_fact:
redis_image: {get_param: ContainerRedisImage}
redis_image_latest: *redis_image_pcmklatest
- name: Pull latest redis images
command: "{{container_cli}} pull {{redis_image}}"
register: result
retries: 3
delay: 3
until: result.rc == 0
- name: Get previous redis image id
shell: "{{container_cli}} inspect --format '{{'{{'}}.Id{{'}}'}}' {{redis_image_latest}}"
register: old_redis_image_id
failed_when: false
- name: Get new redis image id
shell: "{{container_cli}} inspect --format '{{'{{'}}.Id{{'}}'}}' {{redis_image}}"
register: new_redis_image_id
- name: Retag pcmklatest to latest redis image
include_role:
name: tripleo_container_tag
vars:
container_image: "{{redis_image}}"
container_image_latest: "{{redis_image_latest}}"
when:
- old_redis_image_id.stdout != new_redis_image_id.stdout
post_update_tasks:
- name: Redis bundle post update
when: step|int == 1
block: *redis_puppet_bundle
vars:
tripleo_ha_wrapper_minor_update: true
upgrade_tasks:
- name: redis_pacemaker_puppet_tmpfile_cleanup
when: step|int == 1
block: *redis_pacemaker_puppet_tmpfile_cleanup
- name: Tear-down non-HA redis container
when:
- step|int == 0
block: *redis_teardown_nonha
- name: Prepare switch of redis image name
when:
- step|int == 0
block:
- name: Get redis image id currently used by pacemaker
shell: "pcs resource config redis-bundle | grep -Eo 'image=[^ ]+' | awk -F= '{print $2;}'"
register: redis_image_current_res
failed_when: false
- name: Image facts for redis
set_fact:
redis_image_latest: *redis_image_pcmklatest
redis_image_current: "{{redis_image_current_res.stdout}}"
- name: Temporarily tag the current redis image id with the upgraded image name
import_role:
name: tripleo_container_tag
vars:
container_image: "{{redis_image_current}}"
container_image_latest: "{{redis_image_latest}}"
pull_image: false
when:
- redis_image_current != ''
- redis_image_current != redis_image_latest
# During an OS Upgrade, the cluster may not exist so we use
# the shell module instead.
# TODO(odyssey4me):
# Fix the pacemaker_resource module to handle the exception
# for a non-existant cluster more gracefully.
- name: Check redis cluster resource status
shell: pcs resource config redis-bundle
failed_when: false
changed_when: false
register: redis_pcs_res_result
- name: Set upgrade redis facts
set_fact:
redis_pcs_res: "{{redis_pcs_res_result.rc == 0}}"
is_redis_bootstrap_node: "{{redis_short_bootstrap_node_name|lower == ansible_facts['hostname']|lower}}"
- name: Update redis-bundle pcs resource bundle for new container image
when:
- step|int == 1
- is_redis_bootstrap_node|bool
- redis_pcs_res|bool
- redis_image_current != redis_image_latest
block:
- name: Disable the redis cluster resource before container upgrade
pacemaker_resource:
resource: redis-bundle
state: disable
wait_for_resource: true
register: output
retries: 5
until: output.rc == 0
- name: Move redis logging to /var/log/containers
block:
- name: Check redis logging configuration in pacemaker
command: cibadmin --query --xpath "//storage-mapping[@id='redis-log' and @source-dir='/var/log/containers/redis']"
failed_when: false
register: redis_logs_moved
- name: Change redis logging configuration in pacemaker
# rc == 6 means the configuration doesn't exist in the CIB
when: redis_logs_moved.rc == 6
block:
- name: Remove old bind mount for logging in the redis bundle
command: pcs resource bundle update redis-bundle storage-map remove redis-log
- name: Add a bind mount for logging in the redis bundle
command: pcs resource bundle update redis-bundle storage-map add id=redis-log source-dir=/var/log/containers/redis target-dir=/var/log/redis options=rw
- name: Update the redis bundle to use the new container image name
command: "pcs resource bundle update redis-bundle container image={{redis_image_latest}}"
- name: Create hiera data to upgrade redis in a stepwise manner.
when:
- step|int == 1
- cluster_recreate|bool
block:
- name: set redis upgrade node facts in a single-node environment
set_fact:
redis_short_node_names_upgraded: "{{ redis_short_node_names }}"
cacheable: no
when: groups['redis'] | length <= 1
- name: set redis upgrade node facts from the limit option
set_fact:
redis_short_node_names_upgraded: "{{ redis_short_node_names_upgraded|default([]) + [item.split('.')[0]] }}"
cacheable: no
when:
- groups['redis'] | length > 1
- item.split('.')[0] in ansible_limit.split(':')
loop: "{{ redis_short_node_names | default([]) }}"
- fail:
msg: >
You can't upgrade redis without staged
upgrade. You need to use the limit option in order
to do so.
when: >-
redis_short_node_names_upgraded is not defined or
redis_short_node_names_upgraded | length == 0
- debug:
msg: "Prepare redis upgrade for {{ redis_short_node_names_upgraded }}"
- name: remove redis init container on upgrade-scaleup to force re-init
include_role:
name: tripleo_container_rm
vars:
tripleo_containers_to_rm:
- redis_init_bundle
when:
- redis_short_node_names_upgraded | length > 1
- name: add the redis short name to hiera data for the upgrade.
include_role:
name: tripleo_upgrade_hiera
tasks_from: set.yml
vars:
tripleo_upgrade_key: redis_short_node_names_override
tripleo_upgrade_value: "{{redis_short_node_names_upgraded}}"
- name: remove the extra hiera data needed for the upgrade.
include_role:
name: tripleo_upgrade_hiera
tasks_from: remove.yml
vars:
tripleo_upgrade_key: redis_short_node_names_override
when: redis_short_node_names_upgraded | length == redis_short_node_names | length
- name: Retag the pacemaker image if containerized
when:
- step|int == 3
block: *redis_fetch_retag_container_tasks