diff --git a/inventory/sample/group_vars/k8s-cluster/k8s-cluster.yml b/inventory/sample/group_vars/k8s-cluster/k8s-cluster.yml index c3ec03e7ff2..fe1c184e60e 100644 --- a/inventory/sample/group_vars/k8s-cluster/k8s-cluster.yml +++ b/inventory/sample/group_vars/k8s-cluster/k8s-cluster.yml @@ -329,5 +329,6 @@ persistent_volumes_enabled: false ## Amount of time to retain events. (default 1h0m0s) event_ttl_duration: "1h0m0s" -## Force regeneration of kubernetes control plane certificates without the need of bumping the cluster version -force_certificate_regeneration: false + +## Automatically renew K8S control plane certificates on first Monday of each month +auto_renew_certificates: false diff --git a/roles/kubernetes/control-plane/defaults/main/main.yml b/roles/kubernetes/control-plane/defaults/main/main.yml index 24c1ddff0c8..c671326dd7c 100644 --- a/roles/kubernetes/control-plane/defaults/main/main.yml +++ b/roles/kubernetes/control-plane/defaults/main/main.yml @@ -194,5 +194,6 @@ secrets_encryption_query: "resources[*].providers[0].{{kube_encryption_algorithm ## Amount of time to retain events. (default 1h0m0s) event_ttl_duration: "1h0m0s" -## Force regeneration of kubernetes control plane certificates without the need of bumping the cluster version -force_certificate_regeneration: false + +## Automatically renew K8S control plane certificates on first Monday of each month +auto_renew_certificates: false diff --git a/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml b/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml index eab2fff1a90..5a51a24be83 100644 --- a/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml +++ b/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml @@ -99,7 +99,7 @@ when: - inventory_hostname == groups['kube-master']|first - kubeadm_already_run.stat.exists - - apiserver_sans_check.changed or force_certificate_regeneration + - apiserver_sans_check.changed - name: kubeadm | regenerate apiserver cert 2/2 command: >- @@ -109,7 +109,7 @@ when: - inventory_hostname == groups['kube-master']|first - kubeadm_already_run.stat.exists - - apiserver_sans_check.changed or force_certificate_regeneration + - apiserver_sans_check.changed - name: kubeadm | Initialize first master command: >- diff --git a/roles/kubernetes/control-plane/tasks/main.yml b/roles/kubernetes/control-plane/tasks/main.yml index 8bfc8d75d8d..6fba951c28d 100644 --- a/roles/kubernetes/control-plane/tasks/main.yml +++ b/roles/kubernetes/control-plane/tasks/main.yml @@ -66,3 +66,27 @@ - name: Include kubelet client cert rotation fixes include_tasks: kubelet-fix-client-cert-rotation.yml when: kubelet_rotate_certificates + +- name: Install script to renew K8S control plane certificates + template: + src: k8s-certs-renew.sh.j2 + dest: "{{ bin_dir }}/k8s-certs-renew.sh" + mode: '755' + +- name: Renew K8S control plane certificates monthly 1/2 + template: + src: "{{ item }}.j2" + dest: "/etc/systemd/system/{{ item }}" + with_items: + - k8s-certs-renew.service + - k8s-certs-renew.timer + register: k8s_certs_units + when: auto_renew_certificates + +- name: Renew K8S control plane certificates monthly 2/2 + systemd: + name: k8s-certs-renew.timer + enabled: yes + state: started + daemon-reload: "{{ k8s_certs_units is changed }}" + when: auto_renew_certificates diff --git a/roles/kubernetes/control-plane/templates/k8s-certs-renew.service.j2 b/roles/kubernetes/control-plane/templates/k8s-certs-renew.service.j2 new file mode 100644 index 00000000000..64610c2bc02 --- /dev/null +++ b/roles/kubernetes/control-plane/templates/k8s-certs-renew.service.j2 @@ -0,0 +1,6 @@ +[Unit] +Description=Renew K8S control plane certificates + +[Service] +Type=oneshot +ExecStart={{ bin_dir }}/k8s-certs-renew.sh diff --git a/roles/kubernetes/control-plane/templates/k8s-certs-renew.sh.j2 b/roles/kubernetes/control-plane/templates/k8s-certs-renew.sh.j2 new file mode 100644 index 00000000000..41656e3bb2c --- /dev/null +++ b/roles/kubernetes/control-plane/templates/k8s-certs-renew.sh.j2 @@ -0,0 +1,23 @@ +#!/bin/bash + +echo "## Expiration before renewal ##" +{{ bin_dir }}/kubeadm certs check-expiration + +echo "## Renewing certificates managed by kubeadm ##" +{{ bin_dir }}/kubeadm certs renew all + +echo "## Restarting control plane pods managed by kubeadm ##" +{% if container_manager == "docker" %} +{{ docker_bin_dir }}/docker ps -af 'name=k8s_POD_(kube-apiserver|kube-controller-manager|kube-scheduler|etcd)-*' -q | /usr/bin/xargs {{ docker_bin_dir }}/docker rm -f" +{% else %} +{{ bin_dir }}/crictl pods --namespace kube-system --name 'kube-scheduler-*|kube-controller-manager-*|kube-apiserver-*|etcd-*' -q | /usr/bin/xargs {{ bin_dir }}/crictl rmp -f +{% endif %} + +echo "## Updating /root/.kube/config ##" +/usr/bin/cp {{ kube_config_dir }}/admin.conf /root/.kube/config + +echo "## Waiting for apiserver to be up again ##" +until printf "" 2>>/dev/null >>/dev/tcp/127.0.0.1/6443; do sleep 1; done + +echo "## Expiration after renewal ##" +{{ bin_dir }}/kubeadm certs check-expiration diff --git a/roles/kubernetes/control-plane/templates/k8s-certs-renew.timer.j2 b/roles/kubernetes/control-plane/templates/k8s-certs-renew.timer.j2 new file mode 100644 index 00000000000..3c5e0c18f3d --- /dev/null +++ b/roles/kubernetes/control-plane/templates/k8s-certs-renew.timer.j2 @@ -0,0 +1,9 @@ +[Unit] +Description=Timer to renew K8S control plane certificates + +[Timer] +# First Monday of each month +OnCalendar=Mon *-*-1..7 03:{{ groups['kube-master'].index(inventory_hostname) }}0:00 + +[Install] +WantedBy=multi-user.target diff --git a/roles/reset/tasks/main.yml b/roles/reset/tasks/main.yml index 1a78788f7b2..9a65c113547 100644 --- a/roles/reset/tasks/main.yml +++ b/roles/reset/tasks/main.yml @@ -21,6 +21,8 @@ - containerd.service.d/http-proxy.conf - crio.service.d/http-proxy.conf - vault.service.d/http-proxy.conf + - k8s-certs-renew.service + - k8s-certs-renew.timer register: services_removed tags: - services @@ -292,6 +294,7 @@ - "{{ bin_dir }}/weave" - "{{ bin_dir }}/crictl" - "{{ bin_dir }}/netctl" + - "{{ bin_dir }}/k8s-certs-renew.sh" - /var/lib/cni - /etc/openvswitch - /run/openvswitch