From d57c27ffcfd9cd85ef518efb11a8ac107d87ef73 Mon Sep 17 00:00:00 2001 From: Aleksandr Didenko <adidenko@mirantis.com> Date: Thu, 8 Dec 2016 17:48:54 +0100 Subject: [PATCH] Add calico/routereflector support Add BGP route reflectors support in order to optimize BGP topology for deployments with Calico network plugin. Also bump version of calico/ctl for some bug fixes. --- cluster.yml | 5 ++ docs/calico.md | 79 +++++++++++++++++- docs/figures/kargo-calico-rr.png | Bin 0 -> 40710 bytes roles/download/defaults/main.yml | 11 ++- .../kubernetes/preinstall/tasks/set_facts.yml | 2 + roles/kubernetes/secrets/tasks/gen_certs.yml | 6 +- roles/network_plugin/calico/defaults/main.yml | 3 + .../calico/rr/defaults/main.yml | 7 ++ .../calico/rr/handlers/main.yml | 15 ++++ roles/network_plugin/calico/rr/meta/main.yml | 6 ++ roles/network_plugin/calico/rr/tasks/main.yml | 63 ++++++++++++++ .../calico/rr/templates/calico-rr.env.j2 | 6 ++ .../calico/rr/templates/calico-rr.service.j2 | 27 ++++++ roles/network_plugin/calico/tasks/main.yml | 43 +++++++++- 14 files changed, 264 insertions(+), 9 deletions(-) create mode 100644 docs/figures/kargo-calico-rr.png create mode 100644 roles/network_plugin/calico/rr/defaults/main.yml create mode 100644 roles/network_plugin/calico/rr/handlers/main.yml create mode 100644 roles/network_plugin/calico/rr/meta/main.yml create mode 100644 roles/network_plugin/calico/rr/tasks/main.yml create mode 100644 roles/network_plugin/calico/rr/templates/calico-rr.env.j2 create mode 100644 roles/network_plugin/calico/rr/templates/calico-rr.service.j2 diff --git a/cluster.yml b/cluster.yml index 6f8e63505..cf7efb4bb 100644 --- a/cluster.yml +++ b/cluster.yml @@ -41,6 +41,11 @@ - { role: kubernetes-apps/lib, tags: apps } - { role: kubernetes-apps/network_plugin, tags: network } +- hosts: calico-rr + any_errors_fatal: true + roles: + - { role: network_plugin/calico/rr, tags: network } + - hosts: k8s-cluster any_errors_fatal: true roles: diff --git a/docs/calico.md b/docs/calico.md index 81bf4c5b4..954cce0c6 100644 --- a/docs/calico.md +++ b/docs/calico.md @@ -50,7 +50,7 @@ or for versions prior *v1.0.0*: calicoctl endpoint show --detail ``` -##### Optionnal : Define network backend +##### Optional : Define network backend In some cases you may want to define Calico network backend. Allowed values are 'bird', 'gobgp' or 'none'. Bird is a default value. @@ -60,7 +60,7 @@ To re-define you need to edit the inventory and add a group variable `calico_net calico_network_backend: none ``` -##### Optionnal : BGP Peering with border routers +##### Optional : BGP Peering with border routers In some cases you may want to route the pods subnet and so NAT is not needed on the nodes. For instance if you have a cluster spread on different locations and you want your pods to talk each other no matter where they are located. @@ -72,6 +72,81 @@ you'll need to edit the inventory and add a and a hostvar `local_as` by node. node1 ansible_ssh_host=95.54.0.12 local_as=xxxxxx ``` +##### Optional : Define global AS number + +Optional parameter `global_as_num` defines Calico global AS number (`/calico/bgp/v1/global/as_num` etcd key). +It defaults to "64512". + +##### Optional : BGP Peering with route reflectors + +At large scale you may want to disable full node-to-node mesh in order to +optimize your BGP topology and improve `calico-node` containers' start times. + +To do so you can deploy BGP route reflectors and peer `calico-node` with them as +recommended here: + +* https://hub.docker.com/r/calico/routereflector/ +* http://docs.projectcalico.org/v2.0/reference/private-cloud/l3-interconnect-fabric + +You need to edit your inventory and add: + +* `calico-rr` group with nodes in it. At the moment it's incompatible with + `kube-node` due to BGP port conflict with `calico-node` container. So you + should not have nodes in both `calico-rr` and `kube-node` groups. +* `cluster_id` by route reflector node/group (see details +[here](https://hub.docker.com/r/calico/routereflector/)) + +Here's an example of Kargo inventory with route reflectors: + +``` +[all] +rr0 ansible_ssh_host=10.210.1.10 ip=10.210.1.10 +rr1 ansible_ssh_host=10.210.1.11 ip=10.210.1.11 +node2 ansible_ssh_host=10.210.1.12 ip=10.210.1.12 +node3 ansible_ssh_host=10.210.1.13 ip=10.210.1.13 +node4 ansible_ssh_host=10.210.1.14 ip=10.210.1.14 +node5 ansible_ssh_host=10.210.1.15 ip=10.210.1.15 + +[kube-master] +node2 +node3 + +[etcd] +node2 +node3 +node4 + +[kube-node] +node2 +node3 +node4 +node5 + +[k8s-cluster:children] +kube-node +kube-master + +[calico-rr] +rr0 +rr1 + +[rack0] +rr0 +rr1 +node2 +node3 +node4 +node5 + +[rack0:vars] +cluster_id="1.0.0.1" +``` + +The inventory above will deploy the following topology assuming that calico's +`global_as_num` is set to `65400`: + + + Cloud providers configuration ============================= diff --git a/docs/figures/kargo-calico-rr.png b/docs/figures/kargo-calico-rr.png new file mode 100644 index 0000000000000000000000000000000000000000..2dacdb5156d3a963b84d12a55138ba1b8a8680a3 GIT binary patch literal 40710 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 literal 0 HcmV?d00001 diff --git a/roles/download/defaults/main.yml b/roles/download/defaults/main.yml index 0fdb97897..3e3d42d08 100644 --- a/roles/download/defaults/main.yml +++ b/roles/download/defaults/main.yml @@ -42,13 +42,17 @@ flannel_image_tag: "{{ flannel_version }}" calicoctl_image_repo: "calico/ctl" # TODO(apanchenko): v1.0.0-beta can't execute `node run` from Docker container # for details see https://github.com/projectcalico/calico-containers/issues/1291 -calicoctl_image_tag: "v1.0.0-beta-18-gf72bc1d" +calicoctl_image_tag: "v1.0.0-rc3" calico_node_image_repo: "calico/node" calico_node_image_tag: "{{ calico_version }}" calico_cni_image_repo: "calico/cni" calico_cni_image_tag: "{{ calico_cni_version }}" calico_policy_image_repo: "calico/kube-policy-controller" calico_policy_image_tag: latest +# TODO(adidenko): switch to "calico/routereflector" when +# https://github.com/projectcalico/calico-bird/pull/27 is merged +calico_rr_image_repo: "quay.io/l23network/routereflector" +calico_rr_image_tag: "v0.1" exechealthz_version: 1.1 exechealthz_image_repo: "gcr.io/google_containers/exechealthz-amd64" exechealthz_image_tag: "{{ exechealthz_version }}" @@ -142,6 +146,11 @@ downloads: repo: "{{ calico_policy_image_repo }}" tag: "{{ calico_policy_image_tag }}" enabled: "{{ kube_network_plugin == 'canal' }}" + calico_rr: + container: true + repo: "{{ calico_rr_image_repo }}" + tag: "{{ calico_rr_image_tag }}" + enabled: "{{ peer_with_calico_rr }} and kube_network_plugin == 'calico'" pod_infra: container: true repo: "{{ pod_infra_image_repo }}" diff --git a/roles/kubernetes/preinstall/tasks/set_facts.yml b/roles/kubernetes/preinstall/tasks/set_facts.yml index cbe4d9203..f57cd702e 100644 --- a/roles/kubernetes/preinstall/tasks/set_facts.yml +++ b/roles/kubernetes/preinstall/tasks/set_facts.yml @@ -49,6 +49,8 @@ etcd_after_v3: etcd_version | version_compare("v3.0.0", ">=") - set_fact: etcd_container_bin_dir: "{% if etcd_after_v3 %}/usr/local/bin/{% else %}/{% endif %}" +- set_fact: + peer_with_calico_rr: "{{ 'calico-rr' in groups and groups['calico-rr']|length > 0 }}" - include: set_resolv_facts.yml tags: [bootstrap-os, resolvconf, facts] diff --git a/roles/kubernetes/secrets/tasks/gen_certs.yml b/roles/kubernetes/secrets/tasks/gen_certs.yml index ace2a3ba4..f951bb368 100644 --- a/roles/kubernetes/secrets/tasks/gen_certs.yml +++ b/roles/kubernetes/secrets/tasks/gen_certs.yml @@ -51,8 +51,10 @@ - name: Gen_certs | Copy certs on nodes shell: "echo '{{node_cert_data.stdout|quote}}' | base64 -d | tar xz -C {{ kube_cert_dir }}" changed_when: false - when: inventory_hostname in groups['kube-node'] and sync_certs|default(false) and - inventory_hostname != groups['kube-master'][0] + when: (inventory_hostname in groups['kube-node'] or + (peer_with_calico_rr and inventory_hostname in groups['calico-rr'])) and + sync_certs|default(false) and + inventory_hostname != groups['kube-master'][0] - name: Gen_certs | check certificate permissions file: diff --git a/roles/network_plugin/calico/defaults/main.yml b/roles/network_plugin/calico/defaults/main.yml index f0f91d39e..391e7c53e 100644 --- a/roles/network_plugin/calico/defaults/main.yml +++ b/roles/network_plugin/calico/defaults/main.yml @@ -12,6 +12,9 @@ overwrite_hyperkube_cni: true calico_cert_dir: /etc/calico/certs etcd_cert_dir: /etc/ssl/etcd/ssl +# Global as_num (/calico/bgp/v1/global/as_num) +global_as_num: "64512" + # You can set MTU value here. If left undefined or empty, it will # not be specified in calico CNI config, so Calico will use built-in # defaults. The value should be a number, not a string. diff --git a/roles/network_plugin/calico/rr/defaults/main.yml b/roles/network_plugin/calico/rr/defaults/main.yml new file mode 100644 index 000000000..116b9cc8c --- /dev/null +++ b/roles/network_plugin/calico/rr/defaults/main.yml @@ -0,0 +1,7 @@ +--- +# Global as_num (/calico/bgp/v1/global/as_num) +# should be the same as in calico role +global_as_num: "64512" + +calico_cert_dir: /etc/calico/certs +etcd_cert_dir: /etc/ssl/etcd/ssl diff --git a/roles/network_plugin/calico/rr/handlers/main.yml b/roles/network_plugin/calico/rr/handlers/main.yml new file mode 100644 index 000000000..edfb1ad71 --- /dev/null +++ b/roles/network_plugin/calico/rr/handlers/main.yml @@ -0,0 +1,15 @@ +--- +- name: restart calico-rr + command: /bin/true + notify: + - Calico-rr | reload systemd + - Calico-rr | reload calico-rr + +- name : Calico-rr | reload systemd + shell: systemctl daemon-reload + when: ansible_service_mgr == "systemd" + +- name: Calico-rr | reload calico-rr + service: + name: calico-rr + state: restarted diff --git a/roles/network_plugin/calico/rr/meta/main.yml b/roles/network_plugin/calico/rr/meta/main.yml new file mode 100644 index 000000000..38fc506cc --- /dev/null +++ b/roles/network_plugin/calico/rr/meta/main.yml @@ -0,0 +1,6 @@ +dependencies: + - role: kubernetes/secrets + - role: docker + when: ansible_os_family != "CoreOS" + - role: download + file: "{{ downloads.calico_rr }}" diff --git a/roles/network_plugin/calico/rr/tasks/main.yml b/roles/network_plugin/calico/rr/tasks/main.yml new file mode 100644 index 000000000..c43851f84 --- /dev/null +++ b/roles/network_plugin/calico/rr/tasks/main.yml @@ -0,0 +1,63 @@ +--- +# Required from inventory: +# calico_rr_ip - which specific IP to use for RR, defaults to +# "ip" from inventory or "ansible_default_ipv4.address" + +- name: Calico-rr | Set IP fact + set_fact: + rr_ip: "{{ calico_rr_ip | default(ip) | default(ansible_default_ipv4.address) }}" + +- name: Calico | Create calico certs directory + file: + dest: "{{ calico_cert_dir }}" + state: directory + mode: 0750 + owner: root + group: root + +- name: Calico | Link etcd certificates for calico-node + file: + src: "{{ kube_cert_dir }}/{{ item.s }}" + dest: "{{ calico_cert_dir }}/{{ item.d }}" + state: hard + force: yes + with_items: + - {s: "ca.pem", d: "ca_cert.crt"} + - {s: "node.pem", d: "cert.crt"} + - {s: "node-key.pem", d: "key.pem"} + +- name: Calico-rr | Create dir for logs + file: + path: /var/log/calico-rr + state: directory + mode: 0755 + owner: root + group: root + +- name: Calico-rr | Write calico-rr.env for systemd init file + template: src=calico-rr.env.j2 dest=/etc/calico/calico-rr.env + when: ansible_service_mgr == "systemd" + notify: restart calico-rr + +- name: Calico-rr | Write calico-rr systemd init file + template: src=calico-rr.service.j2 dest=/etc/systemd/system/calico-rr.service + when: ansible_service_mgr == "systemd" + notify: restart calico-rr + +- name: Calico-rr | Configure route reflector + command: |- + {{ bin_dir }}/etcdctl --peers={{ etcd_access_addresses }} \ + set /calico/bgp/v1/rr_v4/{{ rr_ip }} \ + '{ + "ip": "{{ rr_ip }}", + "cluster_id": "{{ cluster_id }}" + }' + delegate_to: "{{groups['etcd'][0]}}" + +- meta: flush_handlers + +- name: Calico-rr | Enable calico-rr + service: + name: calico-rr + state: started + enabled: yes diff --git a/roles/network_plugin/calico/rr/templates/calico-rr.env.j2 b/roles/network_plugin/calico/rr/templates/calico-rr.env.j2 new file mode 100644 index 000000000..201caecfe --- /dev/null +++ b/roles/network_plugin/calico/rr/templates/calico-rr.env.j2 @@ -0,0 +1,6 @@ +ETCD_ENDPOINTS="{{ etcd_access_endpoint }}" +ETCD_CA_CERT_FILE="{{ calico_cert_dir }}/ca_cert.crt" +ETCD_CERT_FILE="{{ calico_cert_dir }}/cert.crt" +ETCD_KEY_FILE="{{ calico_cert_dir }}/key.pem" +IP="{{ rr_ip }}" +IP6="" diff --git a/roles/network_plugin/calico/rr/templates/calico-rr.service.j2 b/roles/network_plugin/calico/rr/templates/calico-rr.service.j2 new file mode 100644 index 000000000..1a4b3e977 --- /dev/null +++ b/roles/network_plugin/calico/rr/templates/calico-rr.service.j2 @@ -0,0 +1,27 @@ +[Unit] +Description=calico-rr +After=docker.service +Requires=docker.service + +[Service] +EnvironmentFile=/etc/calico/calico-rr.env +ExecStartPre=-/usr/bin/docker rm -f calico-rr +ExecStart=/usr/bin/docker run --net=host --privileged \ + --name=calico-rr \ + -e IP=${IP} \ + -e IP6=${IP6} \ + -e ETCD_ENDPOINTS=${ETCD_ENDPOINTS} \ + -e ETCD_CA_CERT_FILE=${ETCD_CA_CERT_FILE} \ + -e ETCD_CERT_FILE=${ETCD_CERT_FILE} \ + -e ETCD_KEY_FILE=${ETCD_KEY_FILE} \ + -v /var/log/calico-rr:/var/log/calico \ + -v {{ calico_cert_dir }}:{{ calico_cert_dir }}:ro \ + {{ calico_rr_image_repo }}:{{ calico_rr_image_tag }} + +Restart=always +RestartSec=10s + +ExecStop=-/usr/bin/docker stop calico-rr + +[Install] +WantedBy=multi-user.target diff --git a/roles/network_plugin/calico/tasks/main.yml b/roles/network_plugin/calico/tasks/main.yml index 0480354e8..19d74759c 100644 --- a/roles/network_plugin/calico/tasks/main.yml +++ b/roles/network_plugin/calico/tasks/main.yml @@ -152,6 +152,16 @@ run_once: true tags: facts +- name: Calico | Set global as_num + command: "{{ bin_dir}}/calicoctl config set asNumber {{ global_as_num }}" + run_once: true + when: not legacy_calicoctl + +- name: Calico (old) | Set global as_num + command: "{{ bin_dir}}/calicoctl bgp default-node-as {{ global_as_num }}" + run_once: true + when: legacy_calicoctl + - name: Calico | Write /etc/network-environment template: src=network-environment.j2 dest=/etc/network-environment when: ansible_service_mgr in ["sysvinit","upstart"] @@ -191,8 +201,9 @@ - name: Calico | Disable node mesh shell: "{{ bin_dir }}/calicoctl config set nodeToNodeMesh off" - when: (not legacy_calicoctl and - peer_with_router|default(false) and inventory_hostname in groups['kube-node']) + when: ((peer_with_router|default(false) or peer_with_calico_rr|default(false)) + and inventory_hostname in groups['kube-node'] + and not legacy_calicoctl) run_once: true - name: Calico | Configure peering with router(s) @@ -208,10 +219,27 @@ when: (not legacy_calicoctl and peer_with_router|default(false) and inventory_hostname in groups['kube-node']) +- name: Calico | Configure peering with route reflectors + shell: > + echo '{ + "kind": "bgpPeer", + "spec": {"asNumber": "{{ local_as | default(global_as_num)}}"}, + "apiVersion": "v1", + "metadata": {"node": "{{ inventory_hostname }}", + "scope": "node", + "peerIP": "{{ hostvars[item]["calico_rr_ip"]|default(hostvars[item]["ip"]) }}"} + }' + | {{ bin_dir }}/calicoctl create --skip-exists -f - + with_items: "{{ groups['calico-rr'] | default([]) }}" + when: (not legacy_calicoctl and + peer_with_calico_rr|default(false) and inventory_hostname in groups['kube-node'] + and hostvars[item]['cluster_id'] == cluster_id) + - name: Calico (old) | Disable node mesh shell: "{{ bin_dir }}/calicoctl bgp node-mesh off" - when: (legacy_calicoctl and - peer_with_router|default(false) and inventory_hostname in groups['kube-node']) + when: ((peer_with_router|default(false) or peer_with_calico_rr|default(false)) + and inventory_hostname in groups['kube-node'] + and legacy_calicoctl) run_once: true - name: Calico (old) | Configure peering with router(s) @@ -219,3 +247,10 @@ with_items: "{{ peers|default([]) }}" when: (legacy_calicoctl and peer_with_router|default(false) and inventory_hostname in groups['kube-node']) + +- name: Calico (old) | Configure peering with route reflectors + shell: "{{ bin_dir }}/calicoctl node bgp peer add {{ hostvars[item]['calico_rr_ip']|default(hostvars[item]['ip']) }} as {{ local_as | default(global_as_num) }}" + with_items: "{{ groups['calico-rr'] | default([]) }}" + when: (legacy_calicoctl and + peer_with_calico_rr|default(false) and inventory_hostname in groups['kube-node'] + and hostvars[item]['cluster_id'] == cluster_id) -- GitLab