mirror of
https://github.com/kubernetes-sigs/kubespray.git
synced 2025-12-13 21:34:40 +03:00
* Disable control plane allocating podCIDR for nodes when using calico Calico does not use the .spec.podCIDR field for its IP address management. Furthermore, it can false positives from the kube controller manager if kube_network_node_prefix and calico_pool_blocksize are unaligned, which is the case with the default shipped by kubespray. If the subnets obtained from using kube_network_node_prefix are bigger, this would result at some point in the control plane thinking it does not have subnets left for a new node, while calico will work without problems. Explicitely set a default value of false for calico_ipam_host_local to facilitate its use in templates. * Don't default to kube_network_node_prefix for calico_pool_blocksize They have different semantics: kube_network_node_prefix is intended to be the size of the subnet for all pods on a node, while there can be more than on calico block of the specified size (they are allocated on demand). Besides, this commit does not actually change anything, because the current code is buggy: we don't ever default to kube_network_node_prefix, since the variable is defined in the role defaults.
480 lines
17 KiB
YAML
480 lines
17 KiB
YAML
---
|
|
- name: Calico | Install Wireguard packages
|
|
package:
|
|
name: "{{ item }}"
|
|
state: present
|
|
with_items: "{{ calico_wireguard_packages }}"
|
|
register: calico_package_install
|
|
until: calico_package_install is succeeded
|
|
retries: 4
|
|
when: calico_wireguard_enabled
|
|
|
|
- name: Calico | Copy calicoctl binary from download dir
|
|
copy:
|
|
src: "{{ downloads.calicoctl.dest }}"
|
|
dest: "{{ bin_dir }}/calicoctl"
|
|
mode: 0755
|
|
remote_src: yes
|
|
|
|
- name: Calico | Create calico certs directory
|
|
file:
|
|
dest: "{{ calico_cert_dir }}"
|
|
state: directory
|
|
mode: 0750
|
|
owner: root
|
|
group: root
|
|
when: calico_datastore == "etcd"
|
|
|
|
- name: Calico | Link etcd certificates for calico-node
|
|
file:
|
|
src: "{{ etcd_cert_dir }}/{{ item.s }}"
|
|
dest: "{{ calico_cert_dir }}/{{ item.d }}"
|
|
state: hard
|
|
mode: 0640
|
|
force: yes
|
|
with_items:
|
|
- {s: "{{ kube_etcd_cacert_file }}", d: "ca_cert.crt"}
|
|
- {s: "{{ kube_etcd_cert_file }}", d: "cert.crt"}
|
|
- {s: "{{ kube_etcd_key_file }}", d: "key.pem"}
|
|
when: calico_datastore == "etcd"
|
|
|
|
- name: Calico | Generate typha certs
|
|
include_tasks: typha_certs.yml
|
|
when:
|
|
- typha_secure
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
|
|
- name: Calico | Generate apiserver certs
|
|
include_tasks: calico_apiserver_certs.yml
|
|
when:
|
|
- calico_apiserver_enabled
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
|
|
- name: Calico | Install calicoctl wrapper script
|
|
template:
|
|
src: "calicoctl.{{ calico_datastore }}.sh.j2"
|
|
dest: "{{ bin_dir }}/calicoctl.sh"
|
|
mode: 0755
|
|
owner: root
|
|
group: root
|
|
|
|
- name: Calico | wait for etcd
|
|
uri:
|
|
url: "{{ etcd_access_addresses.split(',') | first }}/health"
|
|
validate_certs: no
|
|
client_cert: "{{ calico_cert_dir }}/cert.crt"
|
|
client_key: "{{ calico_cert_dir }}/key.pem"
|
|
register: result
|
|
until: result.status == 200 or result.status == 401
|
|
retries: 10
|
|
delay: 5
|
|
run_once: true
|
|
when: calico_datastore == "etcd"
|
|
|
|
- name: Calico | Check if calico network pool has already been configured
|
|
# noqa risky-shell-pipe - grep will exit 1 if no match found
|
|
shell: >
|
|
{{ bin_dir }}/calicoctl.sh get ippool | grep -w "{{ calico_pool_cidr | default(kube_pods_subnet) }}" | wc -l
|
|
args:
|
|
executable: /bin/bash
|
|
register: calico_conf
|
|
retries: 4
|
|
until: calico_conf.rc == 0
|
|
delay: "{{ retry_stagger | random + 3 }}"
|
|
changed_when: false
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
|
|
- name: Calico | Ensure that calico_pool_cidr is within kube_pods_subnet when defined
|
|
assert:
|
|
that: "[calico_pool_cidr] | ipaddr(kube_pods_subnet) | length == 1"
|
|
msg: "{{ calico_pool_cidr }} is not within or equal to {{ kube_pods_subnet }}"
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
- 'calico_conf.stdout == "0"'
|
|
- calico_pool_cidr is defined
|
|
|
|
- name: Calico | Check if calico IPv6 network pool has already been configured
|
|
# noqa risky-shell-pipe - grep will exit 1 if no match found
|
|
shell: >
|
|
{{ bin_dir }}/calicoctl.sh get ippool | grep -w "{{ calico_pool_cidr_ipv6 | default(kube_pods_subnet_ipv6) }}" | wc -l
|
|
args:
|
|
executable: /bin/bash
|
|
register: calico_conf_ipv6
|
|
retries: 4
|
|
until: calico_conf_ipv6.rc == 0
|
|
delay: "{{ retry_stagger | random + 3 }}"
|
|
changed_when: false
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
- enable_dual_stack_networks
|
|
|
|
- name: Calico | Ensure that calico_pool_cidr_ipv6 is within kube_pods_subnet_ipv6 when defined
|
|
assert:
|
|
that: "[calico_pool_cidr_ipv6] | ipaddr(kube_pods_subnet_ipv6) | length == 1"
|
|
msg: "{{ calico_pool_cidr_ipv6 }} is not within or equal to {{ kube_pods_subnet_ipv6 }}"
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
- calico_conf_ipv6.stdout is defined and calico_conf_ipv6.stdout == "0"
|
|
- calico_pool_cidr_ipv6 is defined
|
|
- enable_dual_stack_networks
|
|
|
|
- name: Calico | kdd specific configuration
|
|
when:
|
|
- inventory_hostname in groups['kube_control_plane']
|
|
- calico_datastore == "kdd"
|
|
block:
|
|
- name: Calico | Check if extra directory is needed
|
|
stat:
|
|
path: "{{ local_release_dir }}/calico-{{ calico_version }}-kdd-crds/{{ 'kdd' if (calico_version is version('v3.22.3', '<')) else 'crd' }}"
|
|
register: kdd_path
|
|
- name: Calico | Set kdd path when calico < v3.22.3
|
|
set_fact:
|
|
calico_kdd_path: "{{ local_release_dir }}/calico-{{ calico_version }}-kdd-crds{{ '/kdd' if kdd_path.stat.exists is defined and kdd_path.stat.exists }}"
|
|
when:
|
|
- calico_version is version('v3.22.3', '<')
|
|
- name: Calico | Set kdd path when calico > v3.22.2
|
|
set_fact:
|
|
calico_kdd_path: "{{ local_release_dir }}/calico-{{ calico_version }}-kdd-crds{{ '/crd' if kdd_path.stat.exists is defined and kdd_path.stat.exists }}"
|
|
when:
|
|
- calico_version is version('v3.22.2', '>')
|
|
- name: Calico | Create calico manifests for kdd
|
|
assemble:
|
|
src: "{{ calico_kdd_path }}"
|
|
dest: "{{ kube_config_dir }}/kdd-crds.yml"
|
|
mode: 0644
|
|
delimiter: "---\n"
|
|
regexp: ".*\\.yaml"
|
|
remote_src: true
|
|
|
|
- name: Calico | Create Calico Kubernetes datastore resources
|
|
kube:
|
|
kubectl: "{{ bin_dir }}/kubectl"
|
|
filename: "{{ kube_config_dir }}/kdd-crds.yml"
|
|
state: "latest"
|
|
register: kubectl_result
|
|
until: kubectl_result is succeeded
|
|
retries: 5
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
|
|
- name: Calico | Configure Felix
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
block:
|
|
- name: Calico | Get existing FelixConfiguration
|
|
command: "{{ bin_dir }}/calicoctl.sh get felixconfig default -o json"
|
|
register: _felix_cmd
|
|
ignore_errors: True
|
|
changed_when: False
|
|
|
|
- name: Calico | Set kubespray FelixConfiguration
|
|
set_fact:
|
|
_felix_config: >
|
|
{
|
|
"kind": "FelixConfiguration",
|
|
"apiVersion": "projectcalico.org/v3",
|
|
"metadata": {
|
|
"name": "default",
|
|
},
|
|
"spec": {
|
|
"ipipEnabled": {{ calico_ipip_mode != 'Never' }},
|
|
"reportingInterval": "{{ calico_felix_reporting_interval }}",
|
|
"bpfLogLevel": "{{ calico_bpf_log_level }}",
|
|
"bpfEnabled": {{ calico_bpf_enabled | bool }},
|
|
"bpfExternalServiceMode": "{{ calico_bpf_service_mode }}",
|
|
"wireguardEnabled": {{ calico_wireguard_enabled | bool }},
|
|
"logSeverityScreen": "{{ calico_felix_log_severity_screen }}",
|
|
"vxlanEnabled": {{ calico_vxlan_mode != 'Never' }},
|
|
"featureDetectOverride": "{{ calico_feature_detect_override }}",
|
|
"floatingIPs": "{{ calico_felix_floating_ips }}"
|
|
}
|
|
}
|
|
|
|
- name: Calico | Process FelixConfiguration
|
|
set_fact:
|
|
_felix_config: "{{ _felix_cmd.stdout | from_json | combine(_felix_config, recursive=True) }}"
|
|
when:
|
|
- _felix_cmd is success
|
|
|
|
- name: Calico | Configure calico FelixConfiguration
|
|
command:
|
|
cmd: "{{ bin_dir }}/calicoctl.sh apply -f -"
|
|
stdin: "{{ _felix_config is string | ternary(_felix_config, _felix_config | to_json) }}"
|
|
changed_when: False
|
|
|
|
- name: Calico | Configure Calico IP Pool
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
block:
|
|
- name: Calico | Get existing calico network pool
|
|
command: "{{ bin_dir }}/calicoctl.sh get ippool {{ calico_pool_name }} -o json"
|
|
register: _calico_pool_cmd
|
|
ignore_errors: True
|
|
changed_when: False
|
|
|
|
- name: Calico | Set kubespray calico network pool
|
|
set_fact:
|
|
_calico_pool: >
|
|
{
|
|
"kind": "IPPool",
|
|
"apiVersion": "projectcalico.org/v3",
|
|
"metadata": {
|
|
"name": "{{ calico_pool_name }}",
|
|
},
|
|
"spec": {
|
|
"blockSize": {{ calico_pool_blocksize }},
|
|
"cidr": "{{ calico_pool_cidr | default(kube_pods_subnet) }}",
|
|
"ipipMode": "{{ calico_ipip_mode }}",
|
|
"vxlanMode": "{{ calico_vxlan_mode }}",
|
|
"natOutgoing": {{ nat_outgoing | default(false) }}
|
|
}
|
|
}
|
|
|
|
- name: Calico | Process calico network pool
|
|
set_fact:
|
|
_calico_pool: "{{ _calico_pool_cmd.stdout | from_json | combine(_calico_pool, recursive=True) }}"
|
|
when:
|
|
- _calico_pool_cmd is success
|
|
|
|
- name: Calico | Configure calico network pool
|
|
command:
|
|
cmd: "{{ bin_dir }}/calicoctl.sh apply -f -"
|
|
stdin: "{{ _calico_pool is string | ternary(_calico_pool, _calico_pool | to_json) }}"
|
|
changed_when: False
|
|
|
|
- name: Calico | Configure Calico IPv6 Pool
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
- enable_dual_stack_networks | bool
|
|
block:
|
|
- name: Calico | Get existing calico ipv6 network pool
|
|
command: "{{ bin_dir }}/calicoctl.sh get ippool {{ calico_pool_name }}-ipv6 -o json"
|
|
register: _calico_pool_ipv6_cmd
|
|
ignore_errors: True
|
|
changed_when: False
|
|
|
|
- name: Calico | Set kubespray calico network pool
|
|
set_fact:
|
|
_calico_pool_ipv6: >
|
|
{
|
|
"kind": "IPPool",
|
|
"apiVersion": "projectcalico.org/v3",
|
|
"metadata": {
|
|
"name": "{{ calico_pool_name }}-ipv6",
|
|
},
|
|
"spec": {
|
|
"blockSize": {{ calico_pool_blocksize_ipv6 }},
|
|
"cidr": "{{ calico_pool_cidr_ipv6 | default(kube_pods_subnet_ipv6) }}",
|
|
"ipipMode": "{{ calico_ipip_mode_ipv6 }}",
|
|
"vxlanMode": "{{ calico_vxlan_mode_ipv6 }}",
|
|
"natOutgoing": {{ nat_outgoing_ipv6 | default(false) }}
|
|
}
|
|
}
|
|
|
|
- name: Calico | Process calico ipv6 network pool
|
|
set_fact:
|
|
_calico_pool_ipv6: "{{ _calico_pool_ipv6_cmd.stdout | from_json | combine(_calico_pool_ipv6, recursive=True) }}"
|
|
when:
|
|
- _calico_pool_ipv6_cmd is success
|
|
|
|
- name: Calico | Configure calico ipv6 network pool
|
|
command:
|
|
cmd: "{{ bin_dir }}/calicoctl.sh apply -f -"
|
|
stdin: "{{ _calico_pool_ipv6 is string | ternary(_calico_pool_ipv6, _calico_pool_ipv6 | to_json) }}"
|
|
changed_when: False
|
|
|
|
- name: Populate Service External IPs
|
|
set_fact:
|
|
_service_external_ips: "{{ _service_external_ips | default([]) + [{'cidr': item}] }}"
|
|
with_items: "{{ calico_advertise_service_external_ips }}"
|
|
run_once: yes
|
|
|
|
- name: Populate Service LoadBalancer IPs
|
|
set_fact:
|
|
_service_loadbalancer_ips: "{{ _service_loadbalancer_ips | default([]) + [{'cidr': item}] }}"
|
|
with_items: "{{ calico_advertise_service_loadbalancer_ips }}"
|
|
run_once: yes
|
|
|
|
- name: "Determine nodeToNodeMesh needed state"
|
|
set_fact:
|
|
nodeToNodeMeshEnabled: "false"
|
|
when:
|
|
- peer_with_router | default(false) or peer_with_calico_rr | default(false)
|
|
- inventory_hostname in groups['k8s_cluster']
|
|
run_once: yes
|
|
|
|
- name: Calico | Configure Calico BGP
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
block:
|
|
- name: Calico | Get existing BGP Configuration
|
|
command: "{{ bin_dir }}/calicoctl.sh get bgpconfig default -o json"
|
|
register: _bgp_config_cmd
|
|
ignore_errors: True
|
|
changed_when: False
|
|
|
|
- name: Calico | Set kubespray BGP Configuration
|
|
set_fact:
|
|
# noqa: jinja[spacing]
|
|
_bgp_config: >
|
|
{
|
|
"kind": "BGPConfiguration",
|
|
"apiVersion": "projectcalico.org/v3",
|
|
"metadata": {
|
|
"name": "default",
|
|
},
|
|
"spec": {
|
|
"listenPort": {{ calico_bgp_listen_port }},
|
|
"logSeverityScreen": "Info",
|
|
{% if not calico_no_global_as_num | default(false) %}"asNumber": {{ global_as_num }},{% endif %}
|
|
"nodeToNodeMeshEnabled": {{ nodeToNodeMeshEnabled | default('true') }} ,
|
|
{% if calico_advertise_cluster_ips | default(false) %}
|
|
"serviceClusterIPs": [{"cidr": "{{ kube_service_addresses }}" } {{ ',{"cidr":"' + kube_service_addresses_ipv6 + '"}' if enable_dual_stack_networks else '' }}],{% endif %}
|
|
{% if calico_advertise_service_loadbalancer_ips | length > 0 %}"serviceLoadBalancerIPs": {{ _service_loadbalancer_ips }},{% endif %}
|
|
"serviceExternalIPs": {{ _service_external_ips | default([]) }}
|
|
}
|
|
}
|
|
|
|
- name: Calico | Process BGP Configuration
|
|
set_fact:
|
|
_bgp_config: "{{ _bgp_config_cmd.stdout | from_json | combine(_bgp_config, recursive=True) }}"
|
|
when:
|
|
- _bgp_config_cmd is success
|
|
|
|
- name: Calico | Set up BGP Configuration
|
|
command:
|
|
cmd: "{{ bin_dir }}/calicoctl.sh apply -f -"
|
|
stdin: "{{ _bgp_config is string | ternary(_bgp_config, _bgp_config | to_json) }}"
|
|
changed_when: False
|
|
|
|
- name: Calico | Create calico manifests
|
|
template:
|
|
src: "{{ item.file }}.j2"
|
|
dest: "{{ kube_config_dir }}/{{ item.file }}"
|
|
mode: 0644
|
|
with_items:
|
|
- {name: calico-config, file: calico-config.yml, type: cm}
|
|
- {name: calico-node, file: calico-node.yml, type: ds}
|
|
- {name: calico, file: calico-node-sa.yml, type: sa}
|
|
- {name: calico, file: calico-cr.yml, type: clusterrole}
|
|
- {name: calico, file: calico-crb.yml, type: clusterrolebinding}
|
|
- {name: kubernetes-services-endpoint, file: kubernetes-services-endpoint.yml, type: cm }
|
|
register: calico_node_manifests
|
|
when:
|
|
- inventory_hostname in groups['kube_control_plane']
|
|
- rbac_enabled or item.type not in rbac_resources
|
|
|
|
- name: Calico | Create calico manifests for typha
|
|
template:
|
|
src: "{{ item.file }}.j2"
|
|
dest: "{{ kube_config_dir }}/{{ item.file }}"
|
|
mode: 0644
|
|
with_items:
|
|
- {name: calico, file: calico-typha.yml, type: typha}
|
|
register: calico_node_typha_manifest
|
|
when:
|
|
- inventory_hostname in groups['kube_control_plane']
|
|
- typha_enabled
|
|
|
|
- name: Calico | get calico apiserver caBundle
|
|
command: "{{ bin_dir }}/kubectl get secret -n calico-apiserver calico-apiserver-certs -o jsonpath='{.data.apiserver\\.crt}'"
|
|
changed_when: false
|
|
register: calico_apiserver_cabundle
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
- calico_apiserver_enabled
|
|
|
|
- name: Calico | set calico apiserver caBundle fact
|
|
set_fact:
|
|
calico_apiserver_cabundle: "{{ calico_apiserver_cabundle.stdout }}"
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
- calico_apiserver_enabled
|
|
|
|
- name: Calico | Create calico manifests for apiserver
|
|
template:
|
|
src: "{{ item.file }}.j2"
|
|
dest: "{{ kube_config_dir }}/{{ item.file }}"
|
|
mode: 0644
|
|
with_items:
|
|
- {name: calico, file: calico-apiserver.yml, type: calico-apiserver}
|
|
register: calico_apiserver_manifest
|
|
when:
|
|
- inventory_hostname in groups['kube_control_plane']
|
|
- calico_apiserver_enabled
|
|
|
|
- name: Start Calico resources
|
|
kube:
|
|
name: "{{ item.item.name }}"
|
|
namespace: "kube-system"
|
|
kubectl: "{{ bin_dir }}/kubectl"
|
|
resource: "{{ item.item.type }}"
|
|
filename: "{{ kube_config_dir }}/{{ item.item.file }}"
|
|
state: "latest"
|
|
with_items:
|
|
- "{{ calico_node_manifests.results }}"
|
|
- "{{ calico_node_typha_manifest.results }}"
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
- not item is skipped
|
|
loop_control:
|
|
label: "{{ item.item.file }}"
|
|
|
|
- name: Start Calico apiserver resources
|
|
kube:
|
|
name: "{{ item.item.name }}"
|
|
namespace: "calico-apiserver"
|
|
kubectl: "{{ bin_dir }}/kubectl"
|
|
resource: "{{ item.item.type }}"
|
|
filename: "{{ kube_config_dir }}/{{ item.item.file }}"
|
|
state: "latest"
|
|
with_items:
|
|
- "{{ calico_apiserver_manifest.results }}"
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
- not item is skipped
|
|
loop_control:
|
|
label: "{{ item.item.file }}"
|
|
|
|
- name: Wait for calico kubeconfig to be created
|
|
wait_for:
|
|
path: /etc/cni/net.d/calico-kubeconfig
|
|
timeout: "{{ calico_kubeconfig_wait_timeout }}"
|
|
when:
|
|
- inventory_hostname not in groups['kube_control_plane']
|
|
- calico_datastore == "kdd"
|
|
|
|
- name: Calico | Create Calico ipam manifests
|
|
template:
|
|
src: "{{ item.file }}.j2"
|
|
dest: "{{ kube_config_dir }}/{{ item.file }}"
|
|
mode: 0644
|
|
with_items:
|
|
- {name: calico, file: calico-ipamconfig.yml, type: ipam}
|
|
when:
|
|
- inventory_hostname in groups['kube_control_plane']
|
|
- calico_datastore == "kdd"
|
|
|
|
- name: Calico | Create ipamconfig resources
|
|
kube:
|
|
kubectl: "{{ bin_dir }}/kubectl"
|
|
filename: "{{ kube_config_dir }}/calico-ipamconfig.yml"
|
|
state: "latest"
|
|
register: resource_result
|
|
until: resource_result is succeeded
|
|
retries: 4
|
|
when:
|
|
- inventory_hostname == groups['kube_control_plane'][0]
|
|
- calico_datastore == "kdd"
|
|
|
|
- name: Calico | Peer with Calico Route Reflector
|
|
include_tasks: peer_with_calico_rr.yml
|
|
when:
|
|
- peer_with_calico_rr | default(false)
|
|
|
|
- name: Calico | Peer with the router
|
|
include_tasks: peer_with_router.yml
|
|
when:
|
|
- peer_with_router | default(false)
|