diff --git a/ansible/group_vars/all.yml b/ansible/group_vars/all.yml index 16443a2872..5e521f8aac 100644 --- a/ansible/group_vars/all.yml +++ b/ansible/group_vars/all.yml @@ -228,6 +228,9 @@ rabbitmq_management_port: "15672" rabbitmq_cluster_port: "25672" rabbitmq_epmd_port: "4369" +redis_port: "6379" +redis_sentinel_port: "26379" + rdp_port: "8001" rgw_port: "6780" @@ -375,6 +378,7 @@ enable_openvswitch: "{{ neutron_plugin_agent != 'linuxbridge' | bool }}" enable_osprofiler: "no" enable_panko: "no" enable_rally: "no" +enable_redis: "no" enable_sahara: "no" enable_searchlight: "no" enable_senlin: "no" diff --git a/ansible/inventory/all-in-one b/ansible/inventory/all-in-one index 04f8b01313..01258a164a 100644 --- a/ansible/inventory/all-in-one +++ b/ansible/inventory/all-in-one @@ -209,6 +209,9 @@ control [skydive:children] monitoring +[redis:children] +control + # Additional control implemented here. These groups allow you to control which # services run on which hosts at a per-service level. # diff --git a/ansible/inventory/multinode b/ansible/inventory/multinode index 66ff970d6a..4adaf7732f 100644 --- a/ansible/inventory/multinode +++ b/ansible/inventory/multinode @@ -227,6 +227,9 @@ control [skydive:children] monitoring +[redis:children] +control + # Additional control implemented here. These groups allow you to control which # services run on which hosts at a per-service level. # diff --git a/ansible/roles/redis/defaults/main.yml b/ansible/roles/redis/defaults/main.yml new file mode 100644 index 0000000000..3ff30a8c3c --- /dev/null +++ b/ansible/roles/redis/defaults/main.yml @@ -0,0 +1,34 @@ +--- +project_name: "redis" + +redis_services: + redis: + container_name: redis + group: redis + enabled: true + image: "{{ redis_image_full }}" + volumes: + - "{{ node_config_directory }}/redis/:{{ container_config_directory }}/:ro" + - "/etc/localtime:/etc/localtime:ro" + - "{{ project_name }}:/var/lib/redis/" + - "kolla_logs:/var/log/kolla/" + redis-sentinel: + container_name: redis_sentinel + group: redis + enabled: true + image: "{{ redis_sentinel_image_full }}" + volumes: + - "{{ node_config_directory }}/redis-sentinel/:{{ container_config_directory }}/:ro" + - "/etc/localtime:/etc/localtime:ro" + - "kolla_logs:/var/log/kolla/" + +#################### +# Docker +#################### +redis_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ kolla_install_type }}-redis" +redis_tag: "{{ openstack_release }}" +redis_image_full: "{{ redis_image }}:{{ redis_tag }}" + +redis_sentinel_image: "{{ docker_registry ~ '/' if docker_registry else '' }}{{ docker_namespace }}/{{ kolla_base_distro }}-{{ kolla_install_type }}-redis-sentinel" +redis_sentinel_tag: "{{ openstack_release }}" +redis_sentinel_image_full: "{{ redis_sentinel_image }}:{{ redis_tag }}" diff --git a/ansible/roles/redis/handlers/main.yml b/ansible/roles/redis/handlers/main.yml new file mode 100644 index 0000000000..a2dbf0a9c1 --- /dev/null +++ b/ansible/roles/redis/handlers/main.yml @@ -0,0 +1,42 @@ +--- +- name: Restart redis container + vars: + service_name: "redis" + service: "{{ redis_services[service_name] }}" + config_json: "{{ redis_config_jsons.results|selectattr('item.key', 'equalto', service_name)|first }}" + redis_conf: "{{ redis_confs.results|selectattr('item.key', 'equalto', service_name)|first }}" + redis_container: "{{ check_redis_containers.results|selectattr('item.key', 'equalto', service_name)|first }}" + kolla_docker: + action: "recreate_or_restart_container" + common_options: "{{ docker_common_options }}" + name: "{{ service.container_name }}" + image: "{{ service.image }}" + volumes: "{{ service.volumes }}" + when: + - action != "config" + - inventory_hostname in groups[service.group] + - service.enabled | bool + - config_json.changed | bool + or redis_confs.changed |bool + or redis_container.changed | bool + +- name: Restart redis-sentinel container + vars: + service_name: "redis-sentinel" + service: "{{ redis_services[service_name] }}" + config_json: "{{ redis_config_jsons.results|selectattr('item.key', 'equalto', service_name)|first }}" + redis_conf: "{{ redis_confs.results|selectattr('item.key', 'equalto', service_name)|first }}" + redis_container: "{{ check_redis_containers.results|selectattr('item.key', 'equalto', service_name)|first }}" + kolla_docker: + action: "recreate_or_restart_container" + common_options: "{{ docker_common_options }}" + name: "{{ service.container_name }}" + image: "{{ service.image }}" + volumes: "{{ service.volumes }}" + when: + - action != "config" + - inventory_hostname in groups[service.group] + - service.enabled | bool + - config_json.changed | bool + or redis_confs.changed |bool + or redis_container.changed | bool diff --git a/ansible/roles/redis/meta/main.yml b/ansible/roles/redis/meta/main.yml new file mode 100644 index 0000000000..6b4fff8fef --- /dev/null +++ b/ansible/roles/redis/meta/main.yml @@ -0,0 +1,3 @@ +--- +dependencies: + - { role: common } diff --git a/ansible/roles/redis/tasks/config.yml b/ansible/roles/redis/tasks/config.yml new file mode 100644 index 0000000000..7ae888ba31 --- /dev/null +++ b/ansible/roles/redis/tasks/config.yml @@ -0,0 +1,50 @@ +--- +- name: Ensuring config directories exist + file: + path: "{{ node_config_directory }}/{{ item.key }}" + state: "directory" + recurse: yes + when: + - inventory_hostname in groups[item.value.group] + - item.value.enabled | bool + with_dict: "{{ redis_services }}" + +- name: Copying over default config.json files + template: + src: "{{ item.key }}.json.j2" + dest: "{{ node_config_directory }}/{{ item.key }}/config.json" + register: redis_config_jsons + when: + - inventory_hostname in groups[item.value.group] + - item.value.enabled | bool + with_dict: "{{ redis_services }}" + notify: + - Restart {{ item.key }} container + +- name: Copying over redis config files + template: + src: "{{ item.key }}.conf.j2" + dest: "{{ node_config_directory }}/{{ item.key }}/redis.conf" + register: redis_confs + when: + - inventory_hostname in groups[item.value.group] + - item.value.enabled | bool + with_dict: "{{ redis_services }}" + notify: + - Restart {{ item.key }} container + +- name: Check redis containers + kolla_docker: + action: "compare_container" + common_options: "{{ docker_common_options }}" + name: "{{ item.value.container_name }}" + image: "{{ item.value.image }}" + volumes: "{{ item.value.volumes }}" + register: check_redis_containers + when: + - action != "config" + - inventory_hostname in groups[item.value.group] + - item.value.enabled | bool + with_dict: "{{ redis_services }}" + notify: + - Restart {{ item.key }} container diff --git a/ansible/roles/redis/tasks/deploy.yml b/ansible/roles/redis/tasks/deploy.yml new file mode 100644 index 0000000000..dd26ecc34d --- /dev/null +++ b/ansible/roles/redis/tasks/deploy.yml @@ -0,0 +1,5 @@ +--- +- include: config.yml + +- name: Flush handlers + meta: flush_handlers diff --git a/ansible/roles/redis/tasks/main.yml b/ansible/roles/redis/tasks/main.yml new file mode 100644 index 0000000000..b017e8b4ad --- /dev/null +++ b/ansible/roles/redis/tasks/main.yml @@ -0,0 +1,2 @@ +--- +- include: "{{ action }}.yml" diff --git a/ansible/roles/redis/tasks/precheck.yml b/ansible/roles/redis/tasks/precheck.yml new file mode 100644 index 0000000000..ec94321cdb --- /dev/null +++ b/ansible/roles/redis/tasks/precheck.yml @@ -0,0 +1,20 @@ +--- +- name: Get container facts + kolla_container_facts: + name: + - redis + register: container_facts + +- name: Checking free port for Redis + vars: + redis: "{{ redis_services['redis'] }}" + wait_for: + host: "{{ api_interface_address }}" + port: "{{ redis_port }}" + connect_timeout: 1 + timeout: 1 + state: stopped + when: + - container_facts['redis'] is not defined + - inventory_hostname in groups[redis.group] + - redis.enabled | bool diff --git a/ansible/roles/redis/tasks/pull.yml b/ansible/roles/redis/tasks/pull.yml new file mode 100644 index 0000000000..6fefbdbf2c --- /dev/null +++ b/ansible/roles/redis/tasks/pull.yml @@ -0,0 +1,10 @@ +--- +- name: Pulling redis images + kolla_docker: + action: "pull_image" + common_options: "{{ docker_common_options }}" + image: "{{ item.value.image }}" + when: + - inventory_hostname in groups[item.value.group] + - item.value.enabled | bool + with_dict: "{{ redis_services }}" diff --git a/ansible/roles/redis/tasks/reconfigure.yml b/ansible/roles/redis/tasks/reconfigure.yml new file mode 100644 index 0000000000..56169f9727 --- /dev/null +++ b/ansible/roles/redis/tasks/reconfigure.yml @@ -0,0 +1,2 @@ +--- +- include: "deploy.yml" diff --git a/ansible/roles/redis/tasks/upgrade.yml b/ansible/roles/redis/tasks/upgrade.yml new file mode 100644 index 0000000000..dd26ecc34d --- /dev/null +++ b/ansible/roles/redis/tasks/upgrade.yml @@ -0,0 +1,5 @@ +--- +- include: config.yml + +- name: Flush handlers + meta: flush_handlers diff --git a/ansible/roles/redis/templates/redis-sentinel.conf.j2 b/ansible/roles/redis/templates/redis-sentinel.conf.j2 new file mode 100644 index 0000000000..0e034e9a33 --- /dev/null +++ b/ansible/roles/redis/templates/redis-sentinel.conf.j2 @@ -0,0 +1,11 @@ +{% set redis_master_address = hostvars[groups['redis'][0]]['ansible_' + hostvars[groups['redis'][0]]['api_interface']]['ipv4']['address'] %} +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 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 diff --git a/ansible/roles/redis/templates/redis-sentinel.json.j2 b/ansible/roles/redis/templates/redis-sentinel.json.j2 new file mode 100644 index 0000000000..b8df171bb0 --- /dev/null +++ b/ansible/roles/redis/templates/redis-sentinel.json.j2 @@ -0,0 +1,18 @@ +{ + "command": "redis-sentinel /etc/redis/redis.conf", + "config_files": [ + { + "source": "{{ container_config_directory }}/redis.conf", + "dest": "/etc/redis/redis.conf", + "owner": "redis", + "perm": "0600" + } + ], + "permissions": [ + { + "path": "/var/log/kolla/redis", + "owner": "redis:redis", + "recurse": true + } + ] +} diff --git a/ansible/roles/redis/templates/redis.conf.j2 b/ansible/roles/redis/templates/redis.conf.j2 new file mode 100644 index 0000000000..e96f359d59 --- /dev/null +++ b/ansible/roles/redis/templates/redis.conf.j2 @@ -0,0 +1,55 @@ +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 +slave-serve-stale-data yes +slave-read-only yes +repl-diskless-sync no +repl-diskless-sync-delay 5 +repl-disable-tcp-nodelay no +slave-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 slave 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 = hostvars[groups['redis'][0]]['ansible_' + hostvars[groups['redis'][0]]['api_interface']]['ipv4']['address'] %} +slaveof {{ redis_master_address }} 6379 +{% endif %} diff --git a/ansible/roles/redis/templates/redis.json.j2 b/ansible/roles/redis/templates/redis.json.j2 new file mode 100644 index 0000000000..063c2ad69f --- /dev/null +++ b/ansible/roles/redis/templates/redis.json.j2 @@ -0,0 +1,18 @@ +{ + "command": "redis-server /etc/redis/redis.conf", + "config_files": [ + { + "source": "{{ container_config_directory }}/redis.conf", + "dest": "/etc/redis/redis.conf", + "owner": "redis", + "perm": "0600" + } + ], + "permissions": [ + { + "path": "/var/log/kolla/redis", + "owner": "redis:redis", + "recurse": true + } + ] +} diff --git a/ansible/site.yml b/ansible/site.yml index f8f1cc3505..4e3ec623f8 100644 --- a/ansible/site.yml +++ b/ansible/site.yml @@ -103,6 +103,16 @@ tags: telegraf, when: enable_telegraf | bool } +- name: Apply role redis + gather_facts: false + hosts: + - redis + serial: '{{ serial|default("0") }}' + roles: + - { role: redis, + tags: redis, + when: enable_redis | bool } + - name: Apply role haproxy gather_facts: false hosts: diff --git a/etc/kolla/globals.yml b/etc/kolla/globals.yml index bff5bb94fa..87cc095fe9 100644 --- a/etc/kolla/globals.yml +++ b/etc/kolla/globals.yml @@ -186,6 +186,7 @@ kolla_internal_vip_address: "10.10.10.254" #enable_osprofiler: "no" #enable_panko: "no" #enable_rally: "no" +#enable_redis: "no" #enable_sahara: "no" #enable_searchlight: "no" #enable_senlin: "no" diff --git a/etc/kolla/passwords.yml b/etc/kolla/passwords.yml index 50b99c5351..97d1e34570 100644 --- a/etc/kolla/passwords.yml +++ b/etc/kolla/passwords.yml @@ -198,3 +198,8 @@ kibana_password: # etcd options #################### etcd_cluster_token: + +#################### +# redis options +#################### +redis_master_password: