Scale-up functionality for etcd cluster

* Set ETCD_INITIAL_CLUSTER_STATE from `new` to `existing`,
because parameter `new` makes sense only on cluster assembly
stage.
* If cluster exists and current node is not a part
of the cluster, add it with command `etcdctl add member name url`.

Closes kubespray/kargo/#270
This commit is contained in:
Evgeny L 2016-05-27 12:55:52 +03:00
parent cb92b30c25
commit 0500f27db8
6 changed files with 56 additions and 19 deletions

View file

@ -1,5 +1,16 @@
--- ---
- name: Configure | Copy etcd.service systemd file - name: Configure | Check if member is in cluster
shell: "etcdctl --peers={{ etcd_access_addresses }} member list | grep -q {{ etcd_access_address }}"
register: etcd_member_in_cluster
ignore_errors: true
changed_when: false
when: is_etcd_master
- name: Configure | Add member to the cluster if it is not there
when: is_etcd_master and etcd_member_in_cluster.rc != 0 and etcd_cluster_is_healthy.rc == 0
shell: "etcdctl --peers={{ etcd_access_addresses }} member add {{ etcd_member_name }} {{ etcd_peer_url }}"
- name: Configure | Copy etcd.service systemd file
template: template:
src: etcd.service.j2 src: etcd.service.j2
dest: /etc/systemd/system/etcd.service dest: /etc/systemd/system/etcd.service
@ -7,7 +18,7 @@
when: ansible_service_mgr == "systemd" when: ansible_service_mgr == "systemd"
notify: restart etcd notify: restart etcd
- name: Configure | Write etcd initd script - name: Configure | Write etcd initd script
template: template:
src: deb-etcd.initd.j2 src: deb-etcd.initd.j2
dest: /etc/init.d/etcd dest: /etc/init.d/etcd
@ -15,9 +26,3 @@
mode: 0755 mode: 0755
when: ansible_service_mgr in ["sysvinit","upstart"] and ansible_os_family == "Debian" when: ansible_service_mgr in ["sysvinit","upstart"] and ansible_os_family == "Debian"
notify: restart etcd notify: restart etcd
- name: Configure | Create etcd config file
template:
src: etcd.j2
dest: /etc/etcd.env
notify: restart etcd

View file

@ -1,18 +1,26 @@
--- ---
- include: set_facts.yml
- include: install.yml - include: install.yml
- include: set_cluster_health.yml
- include: configure.yml - include: configure.yml
- include: refresh_config.yml
- name: Restart etcd if binary changed - name: Restart etcd if binary changed
command: /bin/true command: /bin/true
notify: restart etcd notify: restart etcd
when: etcd_copy.stdout_lines when: etcd_copy.stdout_lines
# reload systemd before starting service # Reload systemd before starting service
- meta: flush_handlers - meta: flush_handlers
- name: Ensure etcd is running - name: Ensure etcd is running
service: service:
name: etcd name: etcd
state: started state: started
enabled: yes enabled: yes
# After etcd cluster is assembled, make sure that
# initial state of the cluster is in `existing`
# state insted of `new`.
- include: set_cluster_health.yml
- include: refresh_config.yml

View file

@ -0,0 +1,6 @@
---
- name: Refresh config | Create etcd config file
template:
src: etcd.j2
dest: /etc/etcd.env
notify: restart etcd

View file

@ -0,0 +1,7 @@
---
- name: Configure | Check if cluster is healthy
shell: "etcdctl --peers={{ etcd_access_addresses }} cluster-health | grep -q 'cluster is healthy'"
register: etcd_cluster_is_healthy
ignore_errors: true
changed_when: false
when: is_etcd_master

View file

@ -0,0 +1,16 @@
---
- set_fact: etcd_access_address="{{ access_ip | default(ip | default(ansible_default_ipv4['address'])) }}"
- set_fact: etcd_peer_url="http://{{ etcd_access_address }}:2380"
- set_fact: etcd_client_url="http://{{ etcd_access_address }}:2379"
- set_fact:
etcd_access_addresses: |-
{% for item in groups['etcd'] -%}
http://{{ hostvars[item].etcd_access_address }}:2379{% if not loop.last %},{% endif %}
{%- endfor %}
- set_fact:
etcd_member_name: |-
{% for host in groups['etcd'] %}
{% if inventory_hostname == host %}{{"etcd"+loop.index|string }}{% endif %}
{% endfor %}
- set_fact:
is_etcd_master: "{{ inventory_hostname in groups['etcd'] }}"

View file

@ -1,17 +1,12 @@
ETCD_DATA_DIR="/var/lib/etcd" ETCD_DATA_DIR="/var/lib/etcd"
{% if inventory_hostname in groups['etcd'] %} {% if inventory_hostname in groups['etcd'] %}
{% set etcd = {} %}
{% for host in groups['etcd'] %}
{% if inventory_hostname == host %}
{% set _dummy = etcd.update({'name':"etcd"+loop.index|string}) %}
{% endif %}
{% endfor %}
ETCD_ADVERTISE_CLIENT_URLS="http://{{ hostvars[inventory_hostname]['access_ip'] | default(hostvars[inventory_hostname]['ip'] | default( hostvars[inventory_hostname]['ansible_default_ipv4']['address'])) }}:2379" ETCD_ADVERTISE_CLIENT_URLS="http://{{ hostvars[inventory_hostname]['access_ip'] | default(hostvars[inventory_hostname]['ip'] | default( hostvars[inventory_hostname]['ansible_default_ipv4']['address'])) }}:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://{{ hostvars[inventory_hostname]['access_ip'] | default(hostvars[inventory_hostname]['ip'] | default( hostvars[inventory_hostname]['ansible_default_ipv4']['address'])) }}:2380" ETCD_INITIAL_ADVERTISE_PEER_URLS="http://{{ hostvars[inventory_hostname]['access_ip'] | default(hostvars[inventory_hostname]['ip'] | default( hostvars[inventory_hostname]['ansible_default_ipv4']['address'])) }}:2380"
ETCD_INITIAL_CLUSTER_STATE="new" ETCD_INITIAL_CLUSTER_STATE="{% if etcd_cluster_is_healthy.rc != 0 | bool %}new{% else %}existing{% endif %}"
ETCD_INITIAL_CLUSTER_TOKEN="k8s_etcd" ETCD_INITIAL_CLUSTER_TOKEN="k8s_etcd"
ETCD_LISTEN_PEER_URLS="http://{{ hostvars[inventory_hostname]['ip'] | default( hostvars[inventory_hostname]['ansible_default_ipv4']['address']) }}:2380" ETCD_LISTEN_PEER_URLS="http://{{ hostvars[inventory_hostname]['ip'] | default( hostvars[inventory_hostname]['ansible_default_ipv4']['address']) }}:2380"
ETCD_NAME="{{ etcd.name }}" ETCD_NAME="{{ etcd_member_name }}"
{% endif %} {% endif %}
ETCD_INITIAL_CLUSTER="{% for host in groups['etcd'] %}etcd{{ loop.index|string }}=http://{{ hostvars[host]['access_ip'] | default(hostvars[host]['ip'] | default(hostvars[host]['ansible_default_ipv4']['address'])) }}:2380{% if not loop.last %},{% endif %}{% endfor %}"
ETCD_INITIAL_CLUSTER="{% for host in groups['etcd'] %}etcd{{ loop.index|string }}={{ hostvars[host]['etcd_peer_url'] }}{% if not loop.last %},{% endif %}{% endfor %}"
ETCD_LISTEN_CLIENT_URLS="http://{{ hostvars[inventory_hostname]['ip'] | default( hostvars[inventory_hostname]['ansible_default_ipv4']['address']) }}:2379,http://127.0.0.1:2379" ETCD_LISTEN_CLIENT_URLS="http://{{ hostvars[inventory_hostname]['ip'] | default( hostvars[inventory_hostname]['ansible_default_ipv4']['address']) }}:2379,http://127.0.0.1:2379"