Replace Redis with Valkey
This change replaces Redis with Valkey, which is non-existent on Rocky Linux 10 / CentOS Stream 10 due to licensing issues. Co-Authored-By: Bartosz Bezak <bartosz@stackhpc.com> Co-Authored-By: Michal Nasiadka <mnasiadka@gmail.com> Change-Id: Ifcc6ec6e943c20867d969b0bdb0e4cbac53eea1e Signed-off-by: Grzegorz Koper <grzegorzk@stackhpc.com> Signed-off-by: Bartosz Bezak <bartosz@stackhpc.com> Signed-off-by: Michal Nasiadka <mnasiadka@gmail.com>
This commit is contained in:
committed by
Bartosz Bezak
parent
6885249219
commit
86c732dfab
@@ -93,7 +93,7 @@ Kolla Ansible deploys containers for the following infrastructure components:
|
||||
- `Open vSwitch <https://www.openvswitch.org/>`__ for use with Neutron.
|
||||
- `RabbitMQ <https://www.rabbitmq.com/>`__ as a messaging backend for
|
||||
communication between services.
|
||||
- `Redis <https://redis.io/>`__ an in-memory data structure store.
|
||||
- `Valkey <https://valkey.io/>`__ an in-memory data structure store.
|
||||
|
||||
Directories
|
||||
===========
|
||||
|
||||
@@ -19,8 +19,8 @@ cinder_backend_huawei: "no"
|
||||
cinder_backend_huawei_xml_files: []
|
||||
cinder_volume_group: "cinder-volumes"
|
||||
cinder_target_helper: "{{ 'lioadm' if ansible_facts.os_family == 'RedHat' else 'tgtadm' }}"
|
||||
# Valid options are [ '', redis, etcd ]
|
||||
cinder_coordination_backend: "{{ 'redis' if enable_redis | bool else 'etcd' if enable_etcd | bool else '' }}"
|
||||
# Valid options are [ '', valkey, etcd ]
|
||||
cinder_coordination_backend: "{{ 'valkey' if enable_valkey | bool else 'etcd' if enable_etcd | bool else '' }}"
|
||||
|
||||
# Valid options are [ nfs, ceph, s3 ]
|
||||
cinder_backup_driver: "ceph"
|
||||
|
||||
@@ -331,7 +331,7 @@ enable_osprofiler: "no"
|
||||
# valid values: ["elasticsearch", "redis"]
|
||||
osprofiler_backend: "elasticsearch"
|
||||
opensearch_connection_string: "elasticsearch://{{ opensearch_address | put_address_in_context('url') }}:{{ opensearch_port }}"
|
||||
osprofiler_backend_connection_string: "{{ redis_connection_string if osprofiler_backend == 'redis' else opensearch_connection_string }}"
|
||||
osprofiler_backend_connection_string: "{{ valkey_connection_string if osprofiler_backend in ['redis', 'valkey'] else opensearch_connection_string }}"
|
||||
|
||||
######################
|
||||
# Backend TLS options
|
||||
|
||||
@@ -12,8 +12,8 @@ designate_ns_record:
|
||||
- "ns1.example.org"
|
||||
designate_backend_external: "no"
|
||||
designate_backend_external_bind9_nameservers: ""
|
||||
# Valid options are [ '', redis ]
|
||||
designate_coordination_backend: "{{ 'redis' if enable_redis | bool else '' }}"
|
||||
# Valid options are [ '', valkey ]
|
||||
designate_coordination_backend: "{{ 'valkey' if enable_valkey | bool else '' }}"
|
||||
|
||||
designate_enable_notifications_sink: "no"
|
||||
designate_notifications_topic_name: "notifications_designate"
|
||||
|
||||
@@ -8,8 +8,8 @@ enable_gnocchi_statsd: "no"
|
||||
# Valid options are [ file, ceph ]
|
||||
gnocchi_backend_storage: "file"
|
||||
|
||||
# Valid options are [redis, '']
|
||||
gnocchi_incoming_storage: "{{ 'redis' if enable_redis | bool else '' }}"
|
||||
# Valid options are [valkey, '']
|
||||
gnocchi_incoming_storage: "{{ 'valkey' if enable_valkey | bool else '' }}"
|
||||
gnocchi_metric_datadir_volume: "gnocchi"
|
||||
|
||||
gnocchi_internal_fqdn: "{{ kolla_internal_fqdn }}"
|
||||
|
||||
@@ -9,7 +9,7 @@ enable_ironic_pxe_filter: "no"
|
||||
ironic_keystone_user: "ironic"
|
||||
|
||||
# Coordination backend
|
||||
ironic_coordination_backend: "{{ 'redis' if enable_redis | bool else 'etcd' if enable_etcd | bool else '' }}"
|
||||
ironic_coordination_backend: "{{ 'valkey' if enable_valkey | bool else 'etcd' if enable_etcd | bool else '' }}"
|
||||
|
||||
# Network interfaces
|
||||
ironic_http_interface: "{{ api_interface }}"
|
||||
|
||||
@@ -10,4 +10,4 @@ masakari_public_endpoint: "{{ masakari_external_fqdn | kolla_url(public_protocol
|
||||
masakari_api_port: "15868"
|
||||
masakari_api_public_port: "{{ haproxy_single_external_frontend_public_port if haproxy_single_external_frontend | bool else masakari_api_port }}"
|
||||
masakari_api_listen_port: "{{ masakari_api_port }}"
|
||||
masakari_coordination_backend: "{{ 'redis' if enable_redis | bool else 'etcd' if enable_etcd | bool else '' }}"
|
||||
masakari_coordination_backend: "{{ 'valkey' if enable_valkey | bool else 'etcd' if enable_etcd | bool else '' }}"
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
enable_redis: "no"
|
||||
|
||||
####################
|
||||
# Redis options
|
||||
####################
|
||||
redis_connection_string: "redis://{% for host in groups['redis'] %}{% if host == groups['redis'][0] %}default:{{ redis_master_password }}@{{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ redis_sentinel_port }}?sentinel=kolla{% else %}&sentinel_fallback={{ 'api' | kolla_address(host) | put_address_in_context('url') }}:{{ redis_sentinel_port }}{% endif %}{% endfor %}{{ redis_connection_string_extras }}"
|
||||
redis_connection_string_extras: "&db=0&socket_timeout=60&retry_on_timeout=yes"
|
||||
|
||||
redis_port: "6379"
|
||||
redis_sentinel_port: "26379"
|
||||
30
ansible/group_vars/all/valkey.yml
Normal file
30
ansible/group_vars/all/valkey.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
enable_valkey: "no"
|
||||
|
||||
valkey_connection_string: >-
|
||||
redis://{%-
|
||||
for host in groups['valkey'] -%}
|
||||
{%- if host == groups['valkey'][0] -%}
|
||||
default:{{- valkey_master_password -}}@{{-
|
||||
'api' | kolla_address(host) | put_address_in_context('url')
|
||||
-}}:{{- valkey_sentinel_port -}}?sentinel={{- valkey_sentinel_monitor_name -}}
|
||||
{%- else -%}
|
||||
&sentinel_fallback={{-
|
||||
'api' | kolla_address(host) | put_address_in_context('url')
|
||||
-}}:{{- valkey_sentinel_port -}}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
{{- valkey_connection_string_extras -}}
|
||||
|
||||
valkey_connection_string_extras: "&db=0&socket_timeout=60&retry_on_timeout=yes"
|
||||
|
||||
# TODO(mnasiadka): Remove in G/2026.1
|
||||
# NOTE(mnasiadka): These can't reference valkey_server_port or valkey_sentinel_port since these
|
||||
# are changed during migration
|
||||
redis_port: "6379"
|
||||
redis_sentinel_port: "26379"
|
||||
|
||||
valkey_server_port: "6379"
|
||||
valkey_sentinel_port: "26379"
|
||||
valkey_sentinel_monitor_name: "kolla"
|
||||
valkey_sentinel_quorum: 2 # TODO (gkoper) Discuss and settle on some sane defaults here
|
||||
@@ -159,7 +159,7 @@ control
|
||||
[skyline:children]
|
||||
control
|
||||
|
||||
[redis:children]
|
||||
[valkey:children]
|
||||
control
|
||||
|
||||
[blazar:children]
|
||||
|
||||
@@ -177,7 +177,7 @@ control
|
||||
[skyline:children]
|
||||
control
|
||||
|
||||
[redis:children]
|
||||
[valkey:children]
|
||||
control
|
||||
|
||||
[blazar:children]
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
- name: Checking for coordination backend if Ceph backend is enabled
|
||||
run_once: True
|
||||
fail:
|
||||
msg: "Please enable redis or etcd when using Cinder Ceph backend"
|
||||
msg: "Please enable valkey or etcd when using Cinder Ceph backend"
|
||||
when:
|
||||
- not skip_cinder_backend_check | bool
|
||||
- cinder_backend_ceph | bool
|
||||
|
||||
@@ -247,8 +247,8 @@ verify_ssl_path = {{ openstack_cacert }}
|
||||
{% endif %}
|
||||
|
||||
[coordination]
|
||||
{% if cinder_coordination_backend == 'redis' %}
|
||||
backend_url = {{ redis_connection_string }}
|
||||
{% if cinder_coordination_backend == 'valkey' %}
|
||||
backend_url = {{ valkey_connection_string }}
|
||||
{% elif cinder_coordination_backend == 'etcd' %}
|
||||
# NOTE(yoctozepto): we must use etcd3gw (aka etcd3+http) due to issues with alternative (etcd3) and eventlet (as used by cinder)
|
||||
# see https://bugs.launchpad.net/kolla-ansible/+bug/1854932
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
- { name: "prometheus", enabled: "{{ enable_prometheus | bool }}" }
|
||||
- { name: "proxysql", enabled: "{{ enable_proxysql | bool }}" }
|
||||
- { name: "rabbitmq", enabled: "{{ enable_rabbitmq | bool }}" }
|
||||
- { name: "redis", enabled: "{{ enable_redis | bool }}" }
|
||||
- { name: "valkey", enabled: "{{ enable_valkey | bool }}" }
|
||||
- { name: "skyline", enabled: "{{ enable_skyline | bool }}" }
|
||||
- { name: "tacker", enabled: "{{ enable_tacker | bool }}" }
|
||||
- { name: "trove", enabled: "{{ enable_trove | bool }}" }
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
"/var/log/kolla/redis/*.log"
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
"/var/log/kolla/valkey/*.log"
|
||||
{
|
||||
}
|
||||
@@ -118,8 +118,8 @@ policy_file = {{ designate_policy_file }}
|
||||
{% endif %}
|
||||
|
||||
[coordination]
|
||||
{% if designate_coordination_backend == 'redis' %}
|
||||
backend_url = {{ redis_connection_string }}
|
||||
{% if designate_coordination_backend == 'valkey' %}
|
||||
backend_url = {{ valkey_connection_string }}
|
||||
{% endif %}
|
||||
{#
|
||||
NOTE(yoctozepto): etcd is not supported due to lack of group membership
|
||||
|
||||
@@ -98,6 +98,8 @@
|
||||
enabled: "{{ enable_fluentd_systemd | bool }}"
|
||||
- name: "conf/input/13-uwsgi.conf.j2"
|
||||
enabled: true
|
||||
- name: "conf/input/14-valkey.conf.j2"
|
||||
enabled: "{{ enable_valkey | bool }}"
|
||||
customised_input_files: "{{ find_custom_fluentd_inputs.files | map(attribute='path') | list }}"
|
||||
# Filters
|
||||
fluentd_filter_files: "{{ default_filter_files | customise_fluentd(customised_filter_files) }}"
|
||||
|
||||
16
ansible/roles/fluentd/templates/conf/input/14-valkey.conf.j2
Normal file
16
ansible/roles/fluentd/templates/conf/input/14-valkey.conf.j2
Normal file
@@ -0,0 +1,16 @@
|
||||
#jinja2: trim_blocks: False
|
||||
<source>
|
||||
@type tail
|
||||
path /var/log/kolla/valkey/valkey.log,/var/log/kolla/valkey/valkey-sentinel.log
|
||||
pos_file /var/run/fluentd/kolla-valkey.pos
|
||||
tag infra.valkey
|
||||
ignore_repeated_permission_error true
|
||||
enable_watch_timer {{ fluentd_enable_watch_timer }}
|
||||
<parse>
|
||||
@type regexp
|
||||
expression /^(?<Pid>\d+):(?<Role>[A-Za-z-]+) (?:(?<Timestamp>\d+ \w+ \d+ \d+:\d+:\d+\.\d+) (?<LogLevel>.) )?(?<Payload>.*)$/
|
||||
time_key Timestamp
|
||||
keep_time_key true
|
||||
time_format %c
|
||||
</parse>
|
||||
</source>
|
||||
@@ -3,8 +3,8 @@ debug = {{ gnocchi_logging_debug }}
|
||||
|
||||
log_dir = /var/log/kolla/gnocchi
|
||||
|
||||
{% if enable_redis | bool %}
|
||||
coordination_url = {{ redis_connection_string }}
|
||||
{% if enable_valkey | bool %}
|
||||
coordination_url = {{ valkey_connection_string }}
|
||||
{% endif %}
|
||||
|
||||
{% if service_name == 'gnocchi-api' %}
|
||||
@@ -66,9 +66,9 @@ policy_file = {{ gnocchi_policy_file }}
|
||||
{% endif %}
|
||||
|
||||
[incoming]
|
||||
{% if gnocchi_incoming_storage == 'redis' %}
|
||||
{% if gnocchi_incoming_storage == 'valkey' %}
|
||||
driver = redis
|
||||
redis_url = {{ redis_connection_string }}
|
||||
redis_url = {{ valkey_connection_string }}
|
||||
{% endif %}
|
||||
|
||||
[storage]
|
||||
|
||||
@@ -25,3 +25,11 @@
|
||||
when:
|
||||
- container_facts.containers['masakari_api'] is not defined
|
||||
- inventory_hostname in groups['masakari-api']
|
||||
|
||||
- name: Checking for coordination backend if running in multinode setup
|
||||
run_once: True
|
||||
fail:
|
||||
msg: "Please enable Valkey or etcd when running in multinode scenario."
|
||||
when:
|
||||
- masakari_coordination_backend == ''
|
||||
- groups['masakari'] | length > 1
|
||||
|
||||
@@ -84,8 +84,8 @@ connection = mysql+pymysql://{{ masakari_database_user }}:{{ masakari_database_p
|
||||
|
||||
{% if service_name == 'masakari-api' %}
|
||||
[coordination]
|
||||
{% if masakari_coordination_backend == 'redis' %}
|
||||
backend_url = {{ redis_connection_string }}
|
||||
{% if masakari_coordination_backend == 'valkey' %}
|
||||
backend_url = {{ valkey_connection_string }}
|
||||
{% elif masakari_coordination_backend == 'etcd' %}
|
||||
# NOTE(jan.gutter): etcd v3.4 removed the default `v3alpha` api_version. Until
|
||||
# tooz defaults to a newer version, we should explicitly specify `v3`
|
||||
|
||||
@@ -100,7 +100,7 @@ connection_string = {{ osprofiler_backend_connection_string }}
|
||||
{% endif %}
|
||||
|
||||
[coordination]
|
||||
backend_url = {{ redis_connection_string }}
|
||||
backend_url = {{ valkey_connection_string }}
|
||||
|
||||
[oslo_concurrency]
|
||||
lock_path = /var/lib/mistral/tmp
|
||||
|
||||
@@ -65,10 +65,10 @@
|
||||
- octavia_network_type == "tenant"
|
||||
- neutron_plugin_agent != 'openvswitch'
|
||||
|
||||
- name: Checking whether Redis is enabled for octavia jobboard
|
||||
- name: Checking whether Valkey is enabled for Octavia Jobboard
|
||||
assert:
|
||||
that: enable_redis | bool
|
||||
fail_msg: "Redis must be enabled when using octavia jobboard"
|
||||
that: enable_valkey | bool
|
||||
fail_msg: "Valkey must be enabled when using Octavia Jobboard"
|
||||
run_once: True
|
||||
when:
|
||||
- enable_octavia_jobboard | bool
|
||||
|
||||
@@ -168,16 +168,15 @@ ca_certificates_file = {{ openstack_cacert }}
|
||||
{% if enable_octavia_jobboard | bool %}
|
||||
|
||||
[task_flow]
|
||||
jobboard_backend_hosts = {% for host in groups['redis'] %}{{ 'api' | kolla_address(host) | put_address_in_context('url') }}{% if not loop.last %},{% endif %}{% endfor %}
|
||||
jobboard_backend_password = {{ redis_master_password }}
|
||||
jobboard_backend_port = {{ redis_sentinel_port }}
|
||||
jobboard_backend_hosts = {% for host in groups['valkey'] %}{{ 'api' | kolla_address(host) | put_address_in_context('url') }}{% if not loop.last %},{% endif %}{% endfor %}
|
||||
jobboard_backend_password = {{ valkey_master_password }}
|
||||
jobboard_backend_port = {{ valkey_sentinel_port }}
|
||||
jobboard_backend_username = default
|
||||
jobboard_enabled = true
|
||||
jobboard_redis_backend_ssl_options = ssl:False
|
||||
jobboard_redis_sentinel = kolla
|
||||
jobboard_redis_sentinel = {{ valkey_sentinel_monitor_name }}
|
||||
jobboard_redis_sentinel_ssl_options = ssl:False
|
||||
persistence_connection = mysql+pymysql://{{ octavia_persistence_database_user }}:{{ octavia_persistence_database_password }}@{{ octavia_persistence_database_address }}/{{ octavia_persistence_database_name }}{{ '?ssl_ca=' ~ openstack_cacert if octavia_database_enable_tls_internal | bool }}
|
||||
jobboard_enabled = true
|
||||
{% endif %}
|
||||
|
||||
[oslo_concurrency]
|
||||
|
||||
@@ -63,3 +63,10 @@
|
||||
msg: "We are sorry but enable_ceph is no longer supported. Please use external ceph support."
|
||||
when:
|
||||
- (enable_ceph | default()) | bool
|
||||
|
||||
- name: Validate that enable_redis is disabled
|
||||
run_once: True
|
||||
assert:
|
||||
that:
|
||||
- not (enable_redis | default(false)) | bool
|
||||
msg: "Redis support has been replaced with Valkey, please set enable_redis to no and enable_valkey to yes"
|
||||
|
||||
@@ -318,8 +318,8 @@ prometheus_blackbox_exporter_endpoints_default:
|
||||
enabled: "{{ enable_prometheus_alertmanager | bool }}"
|
||||
- endpoints: "{% set rabbitmq_endpoints = [] %}{% for host in groups.get('rabbitmq', []) %}{{ rabbitmq_endpoints.append('rabbitmq_' + host + (':tls_connect:' if rabbitmq_enable_tls | bool else ':tcp_connect:') + ('api' | kolla_address(host) | put_address_in_context('url')) + ':' + hostvars[host]['rabbitmq_port'] ) }}{% endfor %}{{ rabbitmq_endpoints }}"
|
||||
enabled: "{{ enable_rabbitmq | bool }}"
|
||||
- endpoints: "{% set redis_endpoints = [] %}{% for host in groups.get('redis', []) %}{{ redis_endpoints.append('redis_' + host + ':tcp_connect:' + ('api' | kolla_address(host) | put_address_in_context('url')) + ':' + hostvars[host]['redis_port']) }}{% endfor %}{{ redis_endpoints }}"
|
||||
enabled: "{{ enable_redis | bool }}"
|
||||
- endpoints: "{% set valkey_endpoints = [] %}{% for host in groups.get('valkey', []) %}{{ valkey_endpoints.append('valkey_' + host + ':tcp_connect:' + ('api' | kolla_address(host) | put_address_in_context('url')) + ':' + hostvars[host]['valkey_server_port']) }}{% endfor %}{{ valkey_endpoints }}"
|
||||
enabled: "{{ enable_valkey | bool }}"
|
||||
|
||||
prometheus_blackbox_exporter_endpoints_custom: []
|
||||
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
---
|
||||
redis_services:
|
||||
redis:
|
||||
container_name: redis
|
||||
group: redis
|
||||
enabled: true
|
||||
image: "{{ redis_image_full }}"
|
||||
volumes: "{{ redis_default_volumes + redis_extra_volumes }}"
|
||||
dimensions: "{{ redis_dimensions }}"
|
||||
healthcheck: "{{ redis_healthcheck }}"
|
||||
redis-sentinel:
|
||||
container_name: redis_sentinel
|
||||
group: redis
|
||||
environment:
|
||||
REDIS_CONF: "{{ redis_conf_path }}"
|
||||
REDIS_GEN_CONF: "{{ redis_generated_conf_path }}"
|
||||
enabled: true
|
||||
image: "{{ redis_sentinel_image_full }}"
|
||||
volumes: "{{ redis_sentinel_default_volumes + redis_sentinel_extra_volumes }}"
|
||||
dimensions: "{{ redis_sentinel_dimensions }}"
|
||||
healthcheck: "{{ redis_sentinel_healthcheck }}"
|
||||
|
||||
####################
|
||||
# Docker
|
||||
####################
|
||||
redis_image: "{{ docker_image_url }}redis"
|
||||
redis_tag: "{{ openstack_tag }}"
|
||||
redis_image_full: "{{ redis_image }}:{{ redis_tag }}"
|
||||
|
||||
redis_sentinel_image: "{{ docker_image_url }}redis-sentinel"
|
||||
redis_sentinel_tag: "{{ openstack_tag }}"
|
||||
redis_sentinel_image_full: "{{ redis_sentinel_image }}:{{ redis_tag }}"
|
||||
redis_dimensions: "{{ default_container_dimensions }}"
|
||||
redis_sentinel_dimensions: "{{ default_container_dimensions }}"
|
||||
|
||||
redis_enable_healthchecks: "{{ enable_container_healthchecks }}"
|
||||
redis_healthcheck_interval: "{{ default_container_healthcheck_interval }}"
|
||||
redis_healthcheck_retries: "{{ default_container_healthcheck_retries }}"
|
||||
redis_healthcheck_start_period: "{{ default_container_healthcheck_start_period }}"
|
||||
redis_healthcheck_test: ["CMD-SHELL", "healthcheck_listen redis-server {{ redis_port }}"]
|
||||
redis_healthcheck_timeout: "{{ default_container_healthcheck_timeout }}"
|
||||
redis_healthcheck:
|
||||
interval: "{{ redis_healthcheck_interval }}"
|
||||
retries: "{{ redis_healthcheck_retries }}"
|
||||
start_period: "{{ redis_healthcheck_start_period }}"
|
||||
test: "{% if redis_enable_healthchecks | bool %}{{ redis_healthcheck_test }}{% else %}NONE{% endif %}"
|
||||
timeout: "{{ redis_healthcheck_timeout }}"
|
||||
|
||||
redis_sentinel_enable_healthchecks: "{{ enable_container_healthchecks }}"
|
||||
redis_sentinel_healthcheck_interval: "{{ default_container_healthcheck_interval }}"
|
||||
redis_sentinel_healthcheck_retries: "{{ default_container_healthcheck_retries }}"
|
||||
redis_sentinel_healthcheck_start_period: "{{ default_container_healthcheck_start_period }}"
|
||||
redis_sentinel_healthcheck_test: ["CMD-SHELL", "healthcheck_listen redis-sentinel {{ redis_sentinel_port }}"]
|
||||
redis_sentinel_healthcheck_timeout: "{{ default_container_healthcheck_timeout }}"
|
||||
redis_sentinel_healthcheck:
|
||||
interval: "{{ redis_sentinel_healthcheck_interval }}"
|
||||
retries: "{{ redis_sentinel_healthcheck_retries }}"
|
||||
start_period: "{{ redis_sentinel_healthcheck_start_period }}"
|
||||
test: "{% if redis_sentinel_enable_healthchecks | bool %}{{ redis_sentinel_healthcheck_test }}{% else %}NONE{% endif %}"
|
||||
timeout: "{{ redis_sentinel_healthcheck_timeout }}"
|
||||
|
||||
redis_default_volumes:
|
||||
- "{{ node_config_directory }}/redis/:{{ container_config_directory }}/:ro"
|
||||
- "/etc/localtime:/etc/localtime:ro"
|
||||
- "{{ '/etc/timezone:/etc/timezone:ro' if ansible_facts.os_family == 'Debian' else '' }}"
|
||||
- "{{ project_name }}:/var/lib/redis/"
|
||||
- "kolla_logs:/var/log/kolla/"
|
||||
redis_sentinel_default_volumes:
|
||||
- "{{ node_config_directory }}/redis-sentinel/:{{ container_config_directory }}/:ro"
|
||||
- "/etc/localtime:/etc/localtime:ro"
|
||||
- "{{ '/etc/timezone:/etc/timezone:ro' if ansible_facts.os_family == 'Debian' else '' }}"
|
||||
- "kolla_logs:/var/log/kolla/"
|
||||
|
||||
redis_extra_volumes: "{{ default_extra_volumes }}"
|
||||
redis_sentinel_extra_volumes: "{{ default_extra_volumes }}"
|
||||
|
||||
redis_conf_path: "/etc/redis/redis.conf"
|
||||
redis_generated_conf_path: "/etc/redis/redis-regenerated-by-config-rewrite.conf"
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
- name: Checking Redis containers
|
||||
import_role:
|
||||
role: service-check
|
||||
|
||||
- name: Redis ping pong check
|
||||
become: true
|
||||
command: "{{ kolla_container_engine }} exec redis redis-cli -h {{ api_interface_address }} -a {{ redis_master_password }} ping"
|
||||
register: redis_check
|
||||
changed_when: "redis_check.stdout != 'PONG'"
|
||||
failed_when: "redis_check.stdout != 'PONG'"
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
- import_role:
|
||||
name: service-precheck
|
||||
vars:
|
||||
service_precheck_services: "{{ redis_services }}"
|
||||
service_name: "{{ project_name }}"
|
||||
|
||||
- name: Get container facts
|
||||
become: true
|
||||
kolla_container_facts:
|
||||
action: get_containers
|
||||
container_engine: "{{ kolla_container_engine }}"
|
||||
name:
|
||||
- redis
|
||||
check_mode: false
|
||||
register: container_facts
|
||||
|
||||
- name: Checking free port for Redis
|
||||
vars:
|
||||
service: "{{ redis_services['redis'] }}"
|
||||
wait_for:
|
||||
host: "{{ api_interface_address }}"
|
||||
port: "{{ redis_port }}"
|
||||
connect_timeout: 1
|
||||
timeout: 1
|
||||
state: stopped
|
||||
when:
|
||||
- container_facts.containers['redis'] is not defined
|
||||
- service | service_enabled_and_mapped_to_host
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
- import_tasks: config.yml
|
||||
|
||||
- import_tasks: check-containers.yml
|
||||
|
||||
- name: Flush handlers
|
||||
meta: flush_handlers
|
||||
@@ -1,12 +0,0 @@
|
||||
{% set redis_master_address = 'api' | kolla_address(groups['redis'][0]) %}
|
||||
daemonize no
|
||||
pidfile "/var/run/redis/redis-sentinel.pid"
|
||||
logfile "/var/log/kolla/redis/redis-sentinel.log"
|
||||
bind {{ api_interface_address }}
|
||||
port {{ redis_sentinel_port }}
|
||||
sentinel myid {{ inventory_hostname | hash('sha1') }}
|
||||
sentinel monitor kolla {{ redis_master_address }} {{ redis_port }} 2
|
||||
sentinel auth-pass kolla {{ redis_master_password }}
|
||||
sentinel down-after-milliseconds kolla 5000
|
||||
sentinel failover-timeout kolla 60000
|
||||
sentinel parallel-syncs kolla 1
|
||||
@@ -1,22 +0,0 @@
|
||||
{
|
||||
"command": "redis-sentinel {{ redis_generated_conf_path }}",
|
||||
"config_files": [
|
||||
{
|
||||
"source": "{{ container_config_directory }}/redis.conf",
|
||||
"dest": "{{ redis_conf_path }}",
|
||||
"owner": "redis",
|
||||
"perm": "0600"
|
||||
}
|
||||
],
|
||||
"permissions": [
|
||||
{
|
||||
"path": "/var/log/kolla/redis",
|
||||
"owner": "redis:redis",
|
||||
"recurse": true
|
||||
},
|
||||
{
|
||||
"path": "/etc/redis",
|
||||
"owner": "redis:redis"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
bind {{ api_interface_address }}
|
||||
port {{ redis_port }}
|
||||
tcp-backlog 511
|
||||
timeout 0
|
||||
tcp-keepalive 300
|
||||
daemonize no
|
||||
pidfile /var/run/redis/redis-server.pid
|
||||
loglevel notice
|
||||
logfile /var/log/kolla/redis/redis.log
|
||||
databases 16
|
||||
save 900 1
|
||||
save 300 10
|
||||
save 60 10000
|
||||
stop-writes-on-bgsave-error yes
|
||||
rdbcompression yes
|
||||
rdbchecksum yes
|
||||
dbfilename dump.rdb
|
||||
dir /var/lib/redis
|
||||
replica-serve-stale-data yes
|
||||
replica-read-only yes
|
||||
repl-diskless-sync no
|
||||
repl-diskless-sync-delay 5
|
||||
repl-disable-tcp-nodelay no
|
||||
replica-priority 100
|
||||
appendonly yes
|
||||
appendfilename "redis-staging-ao.aof"
|
||||
appendfsync everysec
|
||||
no-appendfsync-on-rewrite no
|
||||
auto-aof-rewrite-percentage 100
|
||||
auto-aof-rewrite-min-size 64mb
|
||||
aof-load-truncated yes
|
||||
lua-time-limit 5000
|
||||
slowlog-log-slower-than 10000
|
||||
slowlog-max-len 128
|
||||
latency-monitor-threshold 0
|
||||
notify-keyspace-events ""
|
||||
hash-max-ziplist-entries 512
|
||||
hash-max-ziplist-value 64
|
||||
set-max-intset-entries 512
|
||||
zset-max-ziplist-entries 128
|
||||
zset-max-ziplist-value 64
|
||||
hll-sparse-max-bytes 3000
|
||||
activerehashing yes
|
||||
client-output-buffer-limit normal 0 0 0
|
||||
client-output-buffer-limit replica 256mb 64mb 60
|
||||
client-output-buffer-limit pubsub 32mb 8mb 60
|
||||
hz 10
|
||||
aof-rewrite-incremental-fsync yes
|
||||
requirepass {{ redis_master_password }}
|
||||
masterauth {{ redis_master_password }}
|
||||
|
||||
{% if inventory_hostname != groups['redis'][0] %}
|
||||
{% set redis_master_address = 'api' | kolla_address(groups['redis'][0]) %}
|
||||
replicaof {{ redis_master_address }} 6379
|
||||
{% endif %}
|
||||
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"command": "redis-server {{ redis_conf_path }}",
|
||||
"config_files": [
|
||||
{
|
||||
"source": "{{ container_config_directory }}/redis.conf",
|
||||
"dest": "{{ redis_conf_path }}",
|
||||
"owner": "redis",
|
||||
"perm": "0600"
|
||||
}
|
||||
],
|
||||
"permissions": [
|
||||
{
|
||||
"path": "/var/log/kolla/redis",
|
||||
"owner": "redis:redis",
|
||||
"recurse": true
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
---
|
||||
project_name: "redis"
|
||||
@@ -67,9 +67,9 @@
|
||||
username = "{{ rabbitmq_user }}"
|
||||
password = "{{ rabbitmq_password }}"
|
||||
{% endif %}
|
||||
{% if inventory_hostname in groups['redis'] and enable_redis | bool %}
|
||||
{% if inventory_hostname in groups['valkey'] and enable_valkey | bool %}
|
||||
[[inputs.redis]]
|
||||
servers = ["tcp://:{{ redis_master_password }}@{{ api_interface_address | put_address_in_context('url') }}:{{ redis_port }}"]
|
||||
servers = ["tcp://:{{ valkey_master_password }}@{{ api_interface_address | put_address_in_context('url') }}:{{ valkey_server_port }}"]
|
||||
{% endif %}
|
||||
{% if inventory_hostname in groups['mariadb'] and (enable_mariadb or enable_external_mariadb_load_balancer) | bool %}
|
||||
[[inputs.mysql]]
|
||||
|
||||
78
ansible/roles/valkey/defaults/main.yml
Normal file
78
ansible/roles/valkey/defaults/main.yml
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
valkey_services:
|
||||
valkey-server:
|
||||
container_name: valkey_server
|
||||
group: valkey
|
||||
enabled: true
|
||||
image: "{{ valkey_image_full }}"
|
||||
volumes: "{{ valkey_default_volumes + valkey_extra_volumes }}"
|
||||
dimensions: "{{ valkey_dimensions }}"
|
||||
healthcheck: "{{ valkey_healthcheck }}"
|
||||
valkey-sentinel:
|
||||
container_name: valkey_sentinel
|
||||
group: valkey
|
||||
environment:
|
||||
VALKEY_CONF: "{{ valkey_conf_path }}"
|
||||
VALKEY_GEN_CONF: "{{ valkey_generated_conf_path }}"
|
||||
enabled: true
|
||||
image: "{{ valkey_sentinel_image_full }}"
|
||||
volumes: "{{ valkey_sentinel_default_volumes + valkey_sentinel_extra_volumes }}"
|
||||
dimensions: "{{ valkey_sentinel_dimensions }}"
|
||||
healthcheck: "{{ valkey_sentinel_healthcheck }}"
|
||||
|
||||
####################
|
||||
# Docker
|
||||
####################
|
||||
valkey_image: "{{ docker_image_url }}valkey-server"
|
||||
valkey_tag: "{{ openstack_tag }}"
|
||||
valkey_image_full: "{{ valkey_image }}:{{ valkey_tag }}"
|
||||
|
||||
valkey_sentinel_image: "{{ docker_image_url }}valkey-sentinel"
|
||||
valkey_sentinel_tag: "{{ openstack_tag }}"
|
||||
valkey_sentinel_image_full: "{{ valkey_sentinel_image }}:{{ valkey_tag }}"
|
||||
valkey_dimensions: "{{ default_container_dimensions }}"
|
||||
valkey_sentinel_dimensions: "{{ default_container_dimensions }}"
|
||||
|
||||
valkey_enable_healthchecks: "{{ enable_container_healthchecks }}"
|
||||
valkey_healthcheck_interval: "{{ default_container_healthcheck_interval }}"
|
||||
valkey_healthcheck_retries: "{{ default_container_healthcheck_retries }}"
|
||||
valkey_healthcheck_start_period: "{{ default_container_healthcheck_start_period }}"
|
||||
valkey_healthcheck_test: ["CMD-SHELL", "healthcheck_listen valkey-server {{ valkey_server_port }}"]
|
||||
valkey_healthcheck_timeout: "{{ default_container_healthcheck_timeout }}"
|
||||
valkey_healthcheck:
|
||||
interval: "{{ valkey_healthcheck_interval }}"
|
||||
retries: "{{ valkey_healthcheck_retries }}"
|
||||
start_period: "{{ valkey_healthcheck_start_period }}"
|
||||
test: "{% if valkey_enable_healthchecks | bool %}{{ valkey_healthcheck_test }}{% else %}NONE{% endif %}"
|
||||
timeout: "{{ valkey_healthcheck_timeout }}"
|
||||
|
||||
valkey_sentinel_enable_healthchecks: "{{ enable_container_healthchecks }}"
|
||||
valkey_sentinel_healthcheck_interval: "{{ default_container_healthcheck_interval }}"
|
||||
valkey_sentinel_healthcheck_retries: "{{ default_container_healthcheck_retries }}"
|
||||
valkey_sentinel_healthcheck_start_period: "{{ default_container_healthcheck_start_period }}"
|
||||
valkey_sentinel_healthcheck_test: ["CMD-SHELL", "healthcheck_listen valkey-sentinel {{ valkey_sentinel_port }}"]
|
||||
valkey_sentinel_healthcheck_timeout: "{{ default_container_healthcheck_timeout }}"
|
||||
valkey_sentinel_healthcheck:
|
||||
interval: "{{ valkey_sentinel_healthcheck_interval }}"
|
||||
retries: "{{ valkey_sentinel_healthcheck_retries }}"
|
||||
start_period: "{{ valkey_sentinel_healthcheck_start_period }}"
|
||||
test: "{% if valkey_sentinel_enable_healthchecks | bool %}{{ valkey_sentinel_healthcheck_test }}{% else %}NONE{% endif %}"
|
||||
timeout: "{{ valkey_sentinel_healthcheck_timeout }}"
|
||||
|
||||
valkey_default_volumes:
|
||||
- "{{ node_config_directory }}/valkey-server/:{{ container_config_directory }}/:ro"
|
||||
- "/etc/localtime:/etc/localtime:ro"
|
||||
- "{{ '/etc/timezone:/etc/timezone:ro' if ansible_facts.os_family == 'Debian' else '' }}"
|
||||
- "{{ project_name }}:/var/lib/valkey/"
|
||||
- "kolla_logs:/var/log/kolla/"
|
||||
valkey_sentinel_default_volumes:
|
||||
- "{{ node_config_directory }}/valkey-sentinel/:{{ container_config_directory }}/:ro"
|
||||
- "/etc/localtime:/etc/localtime:ro"
|
||||
- "{{ '/etc/timezone:/etc/timezone:ro' if ansible_facts.os_family == 'Debian' else '' }}"
|
||||
- "kolla_logs:/var/log/kolla/"
|
||||
|
||||
valkey_extra_volumes: "{{ default_extra_volumes }}"
|
||||
valkey_sentinel_extra_volumes: "{{ default_extra_volumes }}"
|
||||
|
||||
valkey_conf_path: "/etc/valkey/valkey.conf"
|
||||
valkey_generated_conf_path: "/etc/valkey/valkey-regenerated-by-config-rewrite.conf"
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
- name: Restart redis container
|
||||
- name: Restart valkey-server container
|
||||
vars:
|
||||
service_name: "redis"
|
||||
service: "{{ redis_services[service_name] }}"
|
||||
service_name: "valkey-server"
|
||||
service: "{{ valkey_services[service_name] }}"
|
||||
become: true
|
||||
kolla_container:
|
||||
action: "recreate_or_restart_container"
|
||||
@@ -13,10 +13,10 @@
|
||||
dimensions: "{{ service.dimensions }}"
|
||||
healthcheck: "{{ service.healthcheck | default(omit) }}"
|
||||
|
||||
- name: Restart redis-sentinel container
|
||||
- name: Restart valkey-sentinel container
|
||||
vars:
|
||||
service_name: "redis-sentinel"
|
||||
service: "{{ redis_services[service_name] }}"
|
||||
service_name: "valkey-sentinel"
|
||||
service: "{{ valkey_services[service_name] }}"
|
||||
become: true
|
||||
kolla_container:
|
||||
action: "recreate_or_restart_container"
|
||||
13
ansible/roles/valkey/tasks/check.yml
Normal file
13
ansible/roles/valkey/tasks/check.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Checking valkey containers
|
||||
import_role:
|
||||
role: service-check
|
||||
|
||||
- name: Valkey ping pong check
|
||||
become: true
|
||||
shell: >-
|
||||
{{ kolla_container_engine }} exec valkey_server valkey-cli -h {{ api_interface_address }}
|
||||
-a {{ valkey_master_password }} ping
|
||||
register: valkey_check
|
||||
changed_when: "'PONG' in valkey_check.stdout"
|
||||
failed_when: "'PONG' not in valkey_check.stdout"
|
||||
@@ -7,7 +7,7 @@
|
||||
group: "{{ config_owner_group }}"
|
||||
mode: "0770"
|
||||
become: true
|
||||
with_dict: "{{ redis_services | select_services_enabled_and_mapped_to_host }}"
|
||||
with_dict: "{{ valkey_services | select_services_enabled_and_mapped_to_host }}"
|
||||
|
||||
- name: Copying over default config.json files
|
||||
template:
|
||||
@@ -15,12 +15,12 @@
|
||||
dest: "{{ node_config_directory }}/{{ item.key }}/config.json"
|
||||
mode: "0660"
|
||||
become: true
|
||||
with_dict: "{{ redis_services | select_services_enabled_and_mapped_to_host }}"
|
||||
with_dict: "{{ valkey_services | select_services_enabled_and_mapped_to_host }}"
|
||||
|
||||
- name: Copying over redis config files
|
||||
- name: Copying over valkey config files
|
||||
template:
|
||||
src: "{{ item.key }}.conf.j2"
|
||||
dest: "{{ node_config_directory }}/{{ item.key }}/redis.conf"
|
||||
dest: "{{ node_config_directory }}/{{ item.key }}/valkey.conf"
|
||||
mode: "0660"
|
||||
become: true
|
||||
with_dict: "{{ redis_services | select_services_enabled_and_mapped_to_host }}"
|
||||
with_dict: "{{ valkey_services | select_services_enabled_and_mapped_to_host }}"
|
||||
45
ansible/roles/valkey/tasks/precheck.yml
Normal file
45
ansible/roles/valkey/tasks/precheck.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
# TODO(gkoper) Remove redis checks after G/2026.1 release
|
||||
- name: Check if Redis is running
|
||||
become: true
|
||||
kolla_container_facts:
|
||||
action: get_containers
|
||||
container_engine: "{{ kolla_container_engine }}"
|
||||
name:
|
||||
- redis
|
||||
check_mode: false
|
||||
register: redis_container_facts
|
||||
|
||||
- name: Set migration flag if Redis is present
|
||||
set_fact:
|
||||
valkey_is_migrating: "{{ redis_container_facts.containers['redis'] is defined }}"
|
||||
|
||||
- import_role:
|
||||
name: service-precheck
|
||||
vars:
|
||||
service_precheck_services: "{{ valkey_services }}"
|
||||
service_name: "{{ project_name }}"
|
||||
|
||||
- name: Get container facts
|
||||
become: true
|
||||
kolla_container_facts:
|
||||
action: get_containers
|
||||
container_engine: "{{ kolla_container_engine }}"
|
||||
name:
|
||||
- valkey_server
|
||||
check_mode: false
|
||||
register: container_facts
|
||||
|
||||
- name: Checking free port for Valkey
|
||||
vars:
|
||||
service: "{{ valkey_services['valkey-server'] }}"
|
||||
wait_for:
|
||||
host: "{{ api_interface_address }}"
|
||||
port: "{{ valkey_server_port }}"
|
||||
connect_timeout: 1
|
||||
timeout: 1
|
||||
state: stopped
|
||||
when:
|
||||
- container_facts.containers['valkey_server'] is not defined
|
||||
- service | service_enabled_and_mapped_to_host
|
||||
- not (valkey_is_migrating | default(false) | bool)
|
||||
@@ -2,5 +2,5 @@
|
||||
- import_role:
|
||||
name: service-stop
|
||||
vars:
|
||||
project_services: "{{ redis_services }}"
|
||||
project_services: "{{ valkey_services }}"
|
||||
service_name: "{{ project_name }}"
|
||||
134
ansible/roles/valkey/tasks/upgrade.yml
Normal file
134
ansible/roles/valkey/tasks/upgrade.yml
Normal file
@@ -0,0 +1,134 @@
|
||||
---
|
||||
# TODO(bbezak): Remove in G/2026.1 release as Redis migration is no longer required
|
||||
- name: Check if Redis is running
|
||||
become: true
|
||||
kolla_container_facts:
|
||||
action: get_containers
|
||||
container_engine: "{{ kolla_container_engine }}"
|
||||
name:
|
||||
- redis
|
||||
check_mode: false
|
||||
register: redis_container_facts
|
||||
|
||||
- name: Set migration flag if Redis is present
|
||||
set_fact:
|
||||
_valkey_migration: "{{ redis_container_facts.containers['redis'] is defined }}"
|
||||
|
||||
- name: Perform Redis to Valkey migration steps
|
||||
block:
|
||||
|
||||
- name: Set temporary Valkey migration vars
|
||||
set_fact:
|
||||
valkey_server_port: "6380"
|
||||
valkey_sentinel_port: "26380"
|
||||
valkey_sentinel_monitor_name: "kolla-temp"
|
||||
|
||||
- name: Set valkey master host to valkey[0]
|
||||
set_fact:
|
||||
valkey_master_host: "{{ groups['valkey'][0] }}"
|
||||
redis_slave_hosts: "{{ groups['redis'][1:] }}"
|
||||
run_once: true
|
||||
|
||||
- name: Start Valkey on temporary ports with temp sentinel monitor name
|
||||
import_tasks: deploy.yml
|
||||
|
||||
- name: Wait for Valkey replication sync
|
||||
become: true
|
||||
delegate_to: "{{ valkey_master_host }}"
|
||||
run_once: true
|
||||
shell: >-
|
||||
{{ kolla_container_engine }} exec valkey_server
|
||||
valkey-cli -h {{ api_interface_address }} -p {{ valkey_server_port }} info replication
|
||||
register: valkey_replication
|
||||
until: "'master_link_status:up' in valkey_replication.stdout"
|
||||
retries: 30
|
||||
delay: 2
|
||||
|
||||
- name: Set replica-priority=10 on valkey[0] to ensure it becomes master
|
||||
become: true
|
||||
delegate_to: "{{ valkey_master_host }}"
|
||||
run_once: true
|
||||
command: >-
|
||||
{{ kolla_container_engine }} exec valkey_server valkey-cli
|
||||
-h {{ api_interface_address }} -p {{ valkey_server_port }}
|
||||
CONFIG SET replica-priority 10
|
||||
|
||||
- name: Set replica-priority=0 on other valkey nodes to prevent promotion
|
||||
become: true
|
||||
command: >-
|
||||
{{ kolla_container_engine }} exec valkey_server valkey-cli
|
||||
-h {{ api_interface_address }} -p {{ valkey_server_port }} CONFIG SET replica-priority 0
|
||||
when: inventory_hostname != valkey_master_host
|
||||
|
||||
- name: Stop redis slaves (so they don't get promoted during failover)
|
||||
become: true
|
||||
kolla_container:
|
||||
name: redis
|
||||
action: stop_container
|
||||
when: inventory_hostname in redis_slave_hosts
|
||||
|
||||
- name: Trigger Sentinel failover (using one of redis-sentinels)
|
||||
become: true
|
||||
delegate_to: "{{ valkey_master_host }}"
|
||||
run_once: true
|
||||
command: >-
|
||||
{{ kolla_container_engine }} exec redis_sentinel redis-cli
|
||||
-h {{ api_interface_address }}
|
||||
-p {{ redis_sentinel_port }}
|
||||
SENTINEL failover kolla
|
||||
|
||||
- name: Wait until Valkey becomes master
|
||||
become: true
|
||||
delegate_to: "{{ valkey_master_host }}"
|
||||
run_once: true
|
||||
shell: >-
|
||||
{{ kolla_container_engine }} exec valkey_server
|
||||
valkey-cli -h {{ api_interface_address }} -p {{ valkey_server_port }} info replication
|
||||
register: valkey_role
|
||||
until: "'role:master' in valkey_role.stdout"
|
||||
retries: 30
|
||||
delay: 2
|
||||
|
||||
- name: Stop all Redis containers
|
||||
become: true
|
||||
kolla_container:
|
||||
name: redis
|
||||
action: stop_and_remove_container
|
||||
when: inventory_hostname in groups['redis']
|
||||
|
||||
- name: Stop all Sentinel containers
|
||||
become: true
|
||||
kolla_container:
|
||||
name: redis_sentinel
|
||||
action: stop_and_remove_container
|
||||
when: inventory_hostname in groups['redis']
|
||||
|
||||
- name: Remove Redis data volume
|
||||
become: true
|
||||
kolla_container:
|
||||
action: remove_volume
|
||||
name: redis
|
||||
when: inventory_hostname in groups['redis']
|
||||
|
||||
when: redis_container_facts.containers['redis'] is defined
|
||||
|
||||
# These tasks run always, regardless of Redis presence
|
||||
|
||||
- name: Reset Valkey port to default (6379) after migration
|
||||
set_fact:
|
||||
valkey_server_port: "6379"
|
||||
valkey_sentinel_port: "26379"
|
||||
valkey_sentinel_monitor_name: "kolla"
|
||||
_valkey_migration: false
|
||||
|
||||
|
||||
- name: Reconfigure/Redeploy Valkey on default ports
|
||||
import_tasks: reconfigure.yml
|
||||
|
||||
- name: Verify Valkey responds on port 6379
|
||||
import_tasks: check.yml
|
||||
|
||||
- import_tasks: check-containers.yml
|
||||
|
||||
- name: Flush handlers
|
||||
meta: flush_handlers
|
||||
12
ansible/roles/valkey/templates/valkey-sentinel.conf.j2
Normal file
12
ansible/roles/valkey/templates/valkey-sentinel.conf.j2
Normal file
@@ -0,0 +1,12 @@
|
||||
{% set valkey_master_address = 'api' | kolla_address(groups['valkey'][0]) %}
|
||||
daemonize no
|
||||
pidfile "/var/run/valkey/valkey-sentinel.pid"
|
||||
logfile "/var/log/kolla/valkey/valkey-sentinel.log"
|
||||
bind {{ api_interface_address }}
|
||||
port {{ valkey_sentinel_port }}
|
||||
sentinel myid {{ inventory_hostname | hash('sha1') }}
|
||||
sentinel monitor {{ valkey_sentinel_monitor_name }} {{ valkey_master_address }} {{ valkey_server_port }} {{ valkey_sentinel_quorum }}
|
||||
sentinel auth-pass {{ valkey_sentinel_monitor_name }} {{ valkey_master_password }}
|
||||
sentinel down-after-milliseconds {{ valkey_sentinel_monitor_name }} 5000
|
||||
sentinel failover-timeout {{ valkey_sentinel_monitor_name }} 60000
|
||||
sentinel parallel-syncs {{ valkey_sentinel_monitor_name }} 1
|
||||
22
ansible/roles/valkey/templates/valkey-sentinel.json.j2
Normal file
22
ansible/roles/valkey/templates/valkey-sentinel.json.j2
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"command": "valkey-sentinel {{ valkey_generated_conf_path }}",
|
||||
"config_files": [
|
||||
{
|
||||
"source": "{{ container_config_directory }}/valkey.conf",
|
||||
"dest": "{{ valkey_conf_path }}",
|
||||
"owner": "valkey",
|
||||
"perm": "0600"
|
||||
}
|
||||
],
|
||||
"permissions": [
|
||||
{
|
||||
"path": "/var/log/kolla/valkey",
|
||||
"owner": "valkey:valkey",
|
||||
"recurse": true
|
||||
},
|
||||
{
|
||||
"path": "/etc/valkey",
|
||||
"owner": "valkey:valkey"
|
||||
}
|
||||
]
|
||||
}
|
||||
29
ansible/roles/valkey/templates/valkey-server.conf.j2
Normal file
29
ansible/roles/valkey/templates/valkey-server.conf.j2
Normal file
@@ -0,0 +1,29 @@
|
||||
appendonly yes
|
||||
bind {{ api_interface_address }}
|
||||
dir /var/lib/valkey
|
||||
logfile /var/log/kolla/valkey/valkey.log
|
||||
pidfile /var/run/valkey/valkey-server.pid
|
||||
port {{ valkey_server_port }}
|
||||
|
||||
{# TODO(mnasiadka): Remove after Gazpacho/2026.1 #}
|
||||
{% if _valkey_migration | default(false) | bool %}
|
||||
protected-mode no
|
||||
{% if inventory_hostname == groups['valkey'][0] %}
|
||||
{# Migration mode: valkey[0] replicates from Redis #}
|
||||
replicaof {{ 'api' | kolla_address(groups['redis'][0]) }} {{ redis_port }}
|
||||
masterauth {{ redis_master_password }}
|
||||
{% elif not inventory_hostname == groups['valkey'][0] %}
|
||||
{# Secondary valkey nodes replicate from valkey[0] #}
|
||||
replicaof {{ 'api' | kolla_address(groups['valkey'][0]) }} {{ valkey_server_port }}
|
||||
masterauth {{ valkey_master_password }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{# Normal mode: valkey[0] is master #}
|
||||
{# NOTE: Keep this part after removing the migration block above #}
|
||||
{% if not inventory_hostname == groups['valkey'][0] %}
|
||||
{# Secondary valkey nodes replicate from valkey[0] #}
|
||||
replicaof {{ 'api' | kolla_address(groups['valkey'][0]) }} {{ valkey_server_port }}
|
||||
{% endif %}
|
||||
requirepass {{ valkey_master_password }}
|
||||
masterauth {{ valkey_master_password }}
|
||||
{% endif %}
|
||||
18
ansible/roles/valkey/templates/valkey-server.json.j2
Normal file
18
ansible/roles/valkey/templates/valkey-server.json.j2
Normal file
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"command": "valkey-server {{ valkey_conf_path }}",
|
||||
"config_files": [
|
||||
{
|
||||
"source": "{{ container_config_directory }}/valkey.conf",
|
||||
"dest": "{{ valkey_conf_path }}",
|
||||
"owner": "valkey",
|
||||
"perm": "0600"
|
||||
}
|
||||
],
|
||||
"permissions": [
|
||||
{
|
||||
"path": "/var/log/kolla/valkey",
|
||||
"owner": "valkey:valkey",
|
||||
"recurse": true
|
||||
}
|
||||
]
|
||||
}
|
||||
2
ansible/roles/valkey/vars/main.yml
Normal file
2
ansible/roles/valkey/vars/main.yml
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
project_name: "valkey"
|
||||
@@ -63,7 +63,7 @@
|
||||
- enable_placement_{{ enable_placement | bool }}
|
||||
- enable_prometheus_{{ enable_prometheus | bool }}
|
||||
- enable_rabbitmq_{{ enable_rabbitmq | bool }}
|
||||
- enable_redis_{{ enable_redis | bool }}
|
||||
- enable_valkey_{{ enable_valkey | bool }}
|
||||
- enable_skyline_{{ enable_skyline | bool }}
|
||||
- enable_tacker_{{ enable_tacker | bool }}
|
||||
- enable_telegraf_{{ enable_telegraf | bool }}
|
||||
@@ -415,19 +415,19 @@
|
||||
- { role: telegraf,
|
||||
tags: telegraf }
|
||||
|
||||
- name: Apply role redis
|
||||
- name: Apply role valkey
|
||||
gather_facts: false
|
||||
hosts:
|
||||
- redis
|
||||
- '&enable_redis_True'
|
||||
- valkey
|
||||
- '&enable_valkey_True'
|
||||
serial: '{{ kolla_serial|default("0") }}'
|
||||
max_fail_percentage: >-
|
||||
{{ redis_max_fail_percentage |
|
||||
{{ valkey_max_fail_percentage |
|
||||
default(kolla_max_fail_percentage) |
|
||||
default(100) }}
|
||||
roles:
|
||||
- { role: redis,
|
||||
tags: redis }
|
||||
- { role: valkey,
|
||||
tags: valkey }
|
||||
|
||||
# MariaDB deployment is more complicated than other services, so is covered in
|
||||
# its own playbook.
|
||||
|
||||
@@ -58,7 +58,7 @@ applied this way.
|
||||
* ``osprofiler_secret``
|
||||
* ``prometheus_alertmanager_password``
|
||||
* ``qdrouterd_password``
|
||||
* ``redis_master_password``
|
||||
* ``valkey_master_password``
|
||||
|
||||
It is possible to change more secrets however some require manual steps. The
|
||||
manual steps vary depending on the secret. They are listed below in the order
|
||||
|
||||
@@ -51,10 +51,10 @@ Configure Designate options in ``/etc/kolla/globals.yml``
|
||||
.. important::
|
||||
|
||||
If multiple nodes are assigned to be Designate workers, then you must
|
||||
enable a supported coordination backend, currently only ``redis``
|
||||
enable a supported coordination backend, currently only ``valkey``
|
||||
is supported. The backend choice can be overridden via the
|
||||
``designate_coordination_backend`` variable. It defaults to ``redis``
|
||||
when ``redis`` is enabled (``enable_redis`` is set to ``yes``).
|
||||
``designate_coordination_backend`` variable. It defaults to ``valkey``
|
||||
when ``valkey`` is enabled (``enable_valkey`` is set to ``yes``).
|
||||
|
||||
The following additional variables are required depending on which backend you
|
||||
intend to use:
|
||||
|
||||
@@ -429,7 +429,7 @@ workaround_ansible_issue_8743: yes
|
||||
#enable_placement: "{{ enable_nova | bool or enable_zun | bool }}"
|
||||
#enable_prometheus: "no"
|
||||
#enable_proxysql: "yes"
|
||||
#enable_redis: "no"
|
||||
#enable_valkey: "no"
|
||||
#enable_skyline: "no"
|
||||
#enable_tacker: "no"
|
||||
#enable_telegraf: "no"
|
||||
@@ -540,7 +540,7 @@ workaround_ansible_issue_8743: yes
|
||||
####################
|
||||
# Osprofiler options
|
||||
####################
|
||||
# valid values: ["elasticsearch", "redis"]
|
||||
# valid values: ["elasticsearch", "valkey"]
|
||||
#osprofiler_backend: "elasticsearch"
|
||||
|
||||
##################
|
||||
@@ -556,8 +556,8 @@ workaround_ansible_issue_8743: yes
|
||||
# Valid options are [ file, ceph ]
|
||||
#gnocchi_backend_storage: "file"
|
||||
|
||||
# Valid options are [redis, '']
|
||||
#gnocchi_incoming_storage: "{{ 'redis' if enable_redis | bool else '' }}"
|
||||
# Valid options are [valkey, '']
|
||||
#gnocchi_incoming_storage: "{{ 'valkey' if enable_valkey | bool else '' }}"
|
||||
|
||||
################################
|
||||
# Cinder - Block Storage Options
|
||||
@@ -565,8 +565,8 @@ workaround_ansible_issue_8743: yes
|
||||
# Enable / disable Cinder backends
|
||||
#cinder_backend_ceph: "no"
|
||||
#cinder_volume_group: "cinder-volumes"
|
||||
# Valid options are [ '', redis, etcd ]
|
||||
#cinder_coordination_backend: "{{ 'redis' if enable_redis|bool else 'etcd' if enable_etcd|bool else '' }}"
|
||||
# Valid options are [ '', valkey, etcd ]
|
||||
#cinder_coordination_backend: "{{ 'valkey' if enable_valkey | bool else 'etcd' if enable_etcd | bool else '' }}"
|
||||
|
||||
# Valid options are [ nfs, ceph, s3 ]
|
||||
#cinder_backup_driver: "ceph"
|
||||
@@ -598,8 +598,8 @@ workaround_ansible_issue_8743: yes
|
||||
#designate_backend: "bind9"
|
||||
#designate_ns_record:
|
||||
# - "ns1.example.org"
|
||||
# Valid options are [ '', redis ]
|
||||
#designate_coordination_backend: "{{ 'redis' if enable_redis|bool else '' }}"
|
||||
# Valid options are [ '', valkey ]
|
||||
#designate_coordination_backend: "{{ 'valkey' if enable_valkey|bool else '' }}"
|
||||
|
||||
########################
|
||||
# Nova - Compute Options
|
||||
@@ -659,8 +659,8 @@ workaround_ansible_issue_8743: yes
|
||||
# List of extra kernel parameters passed to the kernel used during inspection
|
||||
#ironic_kernel_cmdline_extras: []
|
||||
|
||||
# Valid options are [ '', redis, etcd ]
|
||||
#ironic_coordination_backend: "{{ 'redis' if enable_redis|bool else 'etcd' if enable_etcd|bool else '' }}"
|
||||
# Valid options are [ '', valkey, etcd ]
|
||||
#ironic_coordination_backend: "{{ 'valkey' if enable_valkey | bool else 'etcd' if enable_etcd | bool else '' }}"
|
||||
|
||||
######################################
|
||||
# Manila - Shared File Systems Options
|
||||
|
||||
@@ -197,8 +197,10 @@ keepalived_password:
|
||||
etcd_cluster_token:
|
||||
|
||||
####################
|
||||
# redis options
|
||||
# valkey options
|
||||
####################
|
||||
valkey_master_password:
|
||||
# TODO(gkoper): Remove after G/2026.1 release
|
||||
redis_master_password:
|
||||
|
||||
####################
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Added a Valkey role with Sentinel so deployments use Valkey instead of
|
||||
Redis without changing coordination endpoints.
|
||||
upgrade:
|
||||
- |
|
||||
Redis has been replaced with Valkey. Before running ``kolla-ansible
|
||||
upgrade``, set ``enable_redis: "no"`` and ``enable_valkey: "yes"``
|
||||
in ``globals.yml``. The upgrade playbooks automatically migrate Redis
|
||||
data into Valkey using temporary ports and then switch back to the
|
||||
defaults.
|
||||
@@ -88,6 +88,7 @@ function check_fluentd_missing_logs {
|
||||
/var/log/kolla/rabbitmq/*upgrade.log)
|
||||
continue
|
||||
;;
|
||||
# TODO(gkoper) Remove after G/2026.1 release
|
||||
/var/log/kolla/redis/*)
|
||||
continue
|
||||
;;
|
||||
|
||||
@@ -118,11 +118,15 @@ enable_prometheus_openstack_exporter: "no"
|
||||
enable_tacker: "yes"
|
||||
enable_neutron_sfc: "yes"
|
||||
enable_mistral: "yes"
|
||||
enable_redis: "yes"
|
||||
enable_valkey: "yes"
|
||||
enable_barbican: "yes"
|
||||
enable_heat: "yes"
|
||||
# NOTE(yoctozepto): see https://bugs.launchpad.net/kolla-ansible/+bug/1906299
|
||||
enable_aodh: "yes"
|
||||
# TODO(gkoper): Remove after G/2026.1 release
|
||||
{% if is_previous_release %}
|
||||
enable_redis: "yes"
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if scenario == "ironic" %}
|
||||
@@ -136,6 +140,7 @@ ironic_dnsmasq_dhcp_ranges:
|
||||
|
||||
{% if scenario == "masakari" %}
|
||||
enable_masakari: "yes"
|
||||
enable_valkey: "yes"
|
||||
{% endif %}
|
||||
|
||||
{% if scenario == "cells" %}
|
||||
@@ -156,7 +161,7 @@ enable_mariabackup: "yes"
|
||||
# kolla-ansible vars
|
||||
enable_cinder: "yes"
|
||||
enable_neutron_agent_ha: "yes"
|
||||
enable_redis: "yes"
|
||||
enable_valkey: "yes"
|
||||
cinder_cluster_name: "kolla_ceph"
|
||||
# External Ceph
|
||||
glance_backend_ceph: "yes"
|
||||
@@ -166,8 +171,10 @@ nova_backend_ceph: "yes"
|
||||
rabbitmq_cluster_partition_handling: "autoheal"
|
||||
rabbitmq_extra_config:
|
||||
cluster_keepalive_interval: 50000
|
||||
# Redis for coordination
|
||||
# TODO(gkoper): Remove after G/2026.1 release
|
||||
{% if is_previous_release %}
|
||||
enable_redis: "yes"
|
||||
{% endif %}
|
||||
|
||||
enable_ceph_rgw: "yes"
|
||||
ceph_rgw_hosts:
|
||||
@@ -201,8 +208,11 @@ neutron_enable_ovn_agent: "yes"
|
||||
enable_octavia: "yes"
|
||||
octavia_provider_drivers: "ovn:OVN provider"
|
||||
octavia_provider_agents: "ovn"
|
||||
enable_redis: "yes"
|
||||
neutron_dns_domain: "example.org."
|
||||
# TODO(gkoper): Remove after G/2026.1 release
|
||||
{% if is_previous_release %}
|
||||
enable_redis: "yes"
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if scenario == "prometheus-opensearch" %}
|
||||
@@ -234,8 +244,12 @@ octavia_amp_flavor:
|
||||
ram: 1024
|
||||
disk: 5
|
||||
octavia_network_type: "tenant"
|
||||
enable_valkey: "yes"
|
||||
# TODO(gkoper): Remove after G/2026.1 release
|
||||
{% if is_previous_release %}
|
||||
enable_redis: "yes"
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if groups['all'] | length == 1 %}
|
||||
keepalived_track_script_enabled: "no"
|
||||
@@ -281,6 +295,7 @@ skyline_enable_sso: "yes"
|
||||
enable_aodh: "yes"
|
||||
enable_ceilometer: "yes"
|
||||
enable_gnocchi: "yes"
|
||||
enable_valkey: "yes"
|
||||
{% endif %}
|
||||
|
||||
mariadb_monitor_read_only_interval: "30000"
|
||||
|
||||
@@ -225,9 +225,13 @@ deployment
|
||||
[zun:children]
|
||||
control
|
||||
|
||||
# TODO(gkoper): Remove redis group after G/2026.1 release
|
||||
[redis:children]
|
||||
control
|
||||
|
||||
[valkey:children]
|
||||
control
|
||||
|
||||
[blazar:children]
|
||||
control
|
||||
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
parent: kolla-ansible-base
|
||||
voting: false
|
||||
files:
|
||||
- ^ansible/group_vars/all/(ceph|ceph-rgw|common|fluentd|glance|heat|horizon|keepalived|keystone|loadbalancer|neutron|nova|openvswitch|placement|proxysql|rabbitmq).yml
|
||||
- ^ansible/group_vars/all/(ceph|ceph-rgw|common|fluentd|glance|heat|horizon|keepalived|keystone|loadbalancer|neutron|nova|openvswitch|placement|proxysql|rabbitmq|valkey).yml
|
||||
- ^ansible/group_vars/baremetal/ansible-python-interpreter.yml
|
||||
- ^ansible/roles/(ceph-rgw|common|fluentd|glance|haproxy-config|heat|horizon|keystone|loadbalancer|loadbalancer-config|neutron|nova|openvswitch|placement|proxysql|rabbitmq)/
|
||||
- ^ansible/roles/(ceph-rgw|common|fluentd|glance|haproxy-config|heat|horizon|keystone|loadbalancer|loadbalancer-config|neutron|nova|openvswitch|placement|proxysql|rabbitmq|valkey)/
|
||||
- ^roles/cephadm/
|
||||
vars:
|
||||
kolla_ansible_setup_disks_file_path: "/var/lib/ceph-osd.img"
|
||||
@@ -16,7 +16,7 @@
|
||||
scenario: cephadm
|
||||
scenario_images_extra:
|
||||
- ^cinder
|
||||
- ^redis
|
||||
- ^valkey
|
||||
|
||||
- job:
|
||||
name: kolla-ansible-debian-bookworm-cephadm
|
||||
|
||||
@@ -4,14 +4,15 @@
|
||||
parent: kolla-ansible-base
|
||||
voting: false
|
||||
files: !inherit
|
||||
- ^ansible/group_vars/all/(hacluster|masakari).yml
|
||||
- ^ansible/roles/(hacluster|masakari)/
|
||||
- ^ansible/group_vars/all/(hacluster|masakari|valkey).yml
|
||||
- ^ansible/roles/(hacluster|masakari|valkey)/
|
||||
- ^tests/test-masakari.sh
|
||||
vars:
|
||||
scenario: masakari
|
||||
scenario_images_extra:
|
||||
- ^masakari
|
||||
- ^hacluster
|
||||
- ^valkey
|
||||
# TODO: Remove once Masakari has TLS support
|
||||
tls_enabled: false
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
parent: kolla-ansible-base
|
||||
voting: false
|
||||
files: !inherit
|
||||
- ^ansible/group_vars/all/(aodh|barbican|heat|mistral|redis|tacker).yml
|
||||
- ^ansible/roles/(aodh|barbican|heat|mistral|redis|tacker)/
|
||||
- ^ansible/group_vars/all/(aodh|barbican|heat|mistral|valkey|tacker).yml
|
||||
- ^ansible/roles/(aodh|barbican|heat|mistral|valkey|tacker)/
|
||||
- ^tests/test-scenario-nfv.sh
|
||||
vars:
|
||||
scenario: nfv
|
||||
@@ -13,7 +13,7 @@
|
||||
- ^aodh
|
||||
- ^tacker
|
||||
- ^mistral
|
||||
- ^redis
|
||||
- ^valkey
|
||||
- ^barbican
|
||||
tls_enabled: false
|
||||
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
parent: kolla-ansible-base
|
||||
voting: false
|
||||
files: !inherit
|
||||
- ^ansible/group_vars/all/octavia.yml
|
||||
- ^ansible/roles/(octavia|octavia-certificates)/
|
||||
- ^ansible/group_vars/all/(octavia|valkey).yml
|
||||
- ^ansible/roles/(octavia|octavia-certificates|valkey)/
|
||||
- ^tests/test-octavia.sh
|
||||
vars:
|
||||
scenario: octavia
|
||||
scenario_images_extra:
|
||||
- ^redis
|
||||
- ^valkey
|
||||
- ^octavia
|
||||
tls_enabled: false
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
vars:
|
||||
scenario: ovn
|
||||
scenario_images_extra:
|
||||
- ^redis
|
||||
- ^octavia
|
||||
- ^ovn
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
parent: kolla-ansible-base
|
||||
voting: false
|
||||
files:
|
||||
- ^ansible/group_vars/all/(aodh|ceilometer|gnocchi).yml
|
||||
- ^ansible/roles/(aodh|ceilometer|gnocchi)/
|
||||
- ^ansible/group_vars/all/(aodh|ceilometer|gnocchi|valkey).yml
|
||||
- ^ansible/roles/(aodh|ceilometer|gnocchi|valkey)/
|
||||
- ^tests/test-telemetry.sh
|
||||
vars:
|
||||
scenario: telemetry
|
||||
@@ -13,6 +13,7 @@
|
||||
- ^aodh
|
||||
- ^ceilometer
|
||||
- ^gnocchi
|
||||
- ^valkey
|
||||
|
||||
- job:
|
||||
name: kolla-ansible-debian-bookworm-telemetry
|
||||
|
||||
Reference in New Issue
Block a user