Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements for changing K8s certificates expiration date #1803

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CHANGELOG-0.6.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Changelog 0.6

## [0.6.1] 2020-XX-XX
## [0.6.1] 2020-10-14

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,19 +46,24 @@
block:
- name: Create certificates_opt_mapping fact
block:
- set_fact:
- name: Set non-default certificates_opt_mapping fact value
set_fact:
certificates_opt_mapping: "{{ certificates_opt_mapping | default([]) + [item] }}"
when: certificates_renewal_list is defined and item.name in certificates_renewal_list
with_items: "{{ _certificates_opt_mapping }}"
- set_fact:
when:
- certificates_renewal_list is defined
- item.name in certificates_renewal_list
loop: "{{ _certificates_opt_mapping }}"

- name: Set default certificates_opt_mapping fact value
set_fact:
certificates_opt_mapping: "{{ _certificates_opt_mapping }}"
when: certificates_renewal_list is not defined

- name: Save old certificates
synchronize:
src: "{{ specification.advanced.certificates.location }}/"
dest: >-
"{{ specification.advanced.certificates.location | regex_replace('\\/$', '') }}-backup-{{ ansible_date_time.iso8601_basic_short }}"
{{ specification.advanced.certificates.location | regex_replace('\\/$', '') }}-backup-{{ ansible_date_time.iso8601_basic_short }}
delegate_to: "{{ inventory_hostname }}"

- name: Ensure necessary directories exist
Expand All @@ -68,14 +73,13 @@
owner: root
group: root
mode: u=rw
with_items:
loop:
- "{{ specification.advanced.certificates.location }}/csr"
- "{{ specification.advanced.certificates.location }}/ext"

- name: Generate new CSR
shell: kubeadm alpha certs renew all --csr-only --csr-dir=csr
command: kubeadm alpha certs renew all --csr-only --csr-dir=csr
args:
executable: /bin/bash
chdir: "{{ specification.advanced.certificates.location }}"

# ansible openssl modules and openssl tool behave different, extensions file is necessary for openssl
Expand All @@ -87,43 +91,44 @@
-in csr/{{ item.name }}.csr \
| sed '1,3d;s/ Address//g;s/^[[:blank:]]*//;s/[[:blank:]]*$//'
args:
executable: /bin/bash
chdir: "{{ specification.advanced.certificates.location }}"
register: csr_info
with_items: "{{ certificates_opt_mapping }}"
loop: "{{ certificates_opt_mapping }}"

- name: Generate extension files
template:
src: certificate-v3.ext.j2
dest: "{{ specification.advanced.certificates.location }}/ext/{{ item.0.name }}.ext"
with_together:
- "{{ certificates_opt_mapping }}"
- "{{ csr_info.results }}"
loop: "{{ certificates_opt_mapping|zip(csr_info.results)|list }}"

- name: Create signed certificates
shell: |-
openssl x509 -req -days {{ valid_days }} -in csr/{{ item.name }}.csr -extfile ext/{{ item.name }}.ext \
-CA {{ item.parent_ca }}.crt -CAkey {{ item.parent_ca }}.key -CAcreateserial -out {{ item.target }}.crt
command: |-
openssl x509 -req -days {{ valid_days }} \
-in csr/{{ item.name }}.csr \
-extfile ext/{{ item.name }}.ext \
-CA {{ item.parent_ca }}.crt \
-CAkey {{ item.parent_ca }}.key \
-CAcreateserial \
-out {{ item.target }}.crt
args:
executable: /bin/bash
chdir: "{{ specification.advanced.certificates.location }}"
with_items: "{{ certificates_opt_mapping }}"
loop: "{{ certificates_opt_mapping }}"

- name: Copy keys to pki location and ensure that permissions are strict
- name: Copy keys to certificates location and ensure that permissions are strict
copy:
src: "{{ specification.advanced.certificates.location }}/csr/{{ item.name }}.key"
remote_src: yes
dest: "{{ item.target }}.key"
owner: root
group: root
mode: '0600'
with_items: "{{ certificates_opt_mapping }}"
mode: u=rw
loop: "{{ certificates_opt_mapping }}"

- name: Remove csr and ext directories
file:
path: "{{ specification.advanced.certificates.location }}/{{ item }}"
state: absent
with_items:
loop:
- csr
- ext

Expand Down Expand Up @@ -152,29 +157,34 @@
controller-manager.conf: "system:kube-controller-manager"
command: |
kubectl config set-credentials {{ conf_account_mapping[item] }} \
--client-key {{ specification.advanced.certificates.location }}/{{ item }}.key \
--client-certificate {{ specification.advanced.certificates.location }}/{{ item }}.crt --embed-certs
with_items: "{{ conf_certificates }}"
--client-key {{ item }}.key \
--client-certificate {{ item }}.crt --embed-certs
args:
chdir: "{{ specification.advanced.certificates.location }}"
loop: "{{ conf_certificates }}"

- name: Remove conf certificates
file:
path: "{{ specification.advanced.certificates.location }}/{{ item.0 }}.{{ item.1 }}"
path: "{{ specification.advanced.certificates.location }}/{{ item }}"
state: absent
with_nested:
- - 'admin.conf'
- 'scheduler.conf'
- 'controller-manager.conf'
- - 'crt'
- 'key'
loop:
- 'admin.conf.crt'
- 'admin.conf.key'
- 'scheduler.conf.crt'
- 'scheduler.conf.key'
- 'controller-manager.conf.crt'
- 'controller-manager.conf.key'

- name: Restart systemd services
when: restart_services is defined and (restart_services | difference(['docker', 'kubelet']) | length == 0)
when:
- services_to_restart is defined
- services_to_restart | difference(['docker', 'kubelet']) | length == 0
block:
- name: Restart
- name: Restart services
systemd:
name: "{{ item }}"
state: restarted
with_items: "{{ restart_services }}"
loop: "{{ services_to_restart }}"

- name: Wait until cluster is available
command: kubectl cluster-info
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@
- import_tasks: master-join.yml

- name: Collect current apiserver certificate 'not_after' date by openssl
shell: openssl x509 -enddate -noout -in apiserver.crt
command: openssl x509 -enddate -noout -in apiserver.crt
args:
executable: /bin/bash
chdir: "{{ specification.advanced.certificates.location }}"
register: apiserver_certificate_info

Expand Down Expand Up @@ -90,7 +89,7 @@
when: specification.advanced.certificates.renew | bool
vars:
valid_days: "{{ specification.advanced.certificates.expiration_days }}"
restart_services:
services_to_restart:
- docker
include_tasks: generate-certificates.yml

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ specification:
imageRepository: k8s.gcr.io
certificates:
location: /etc/kubernetes/pki
expiration_days: 365
expiration_days: 365 # values greater than 24855 are not recommended
renew: false
etcd_args:
encrypted: yes
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1,40 @@
$ref: '#/definitions/unvalidated_specification'
"$id": "#/specification"
title: "K8s specification schema"
description: "K8s specification schema"
type: object
properties:
advanced:
type: object
properties:
certificates:
type: object
properties:
location:
title: location schema
"$id": "#/properties/specification/properties/advanced/properties/certificates/properties/location"
description: |-
Where the certificates should be stored
type: string
default: /etc/kubernetes/pki
examples:
- /etc/kubernetes/pki
expiration_days:
title: expiration_days schema
"$id": "#/properties/specification/properties/advanced/properties/certificates/properties/expiration_days"
description: |-
Days to make certificate be valid for.
For more explanation about the limit navigate to
https://groups.google.com/g/mailing.openssl.users/c/3kK_f0ywCZQ.
type: integer
minimum: 1
maximum: 24855
default: 365
renew:
title: renew schema
"$id": "#/properties/specification/properties/advanced/properties/certificates/properties/renew"
description: |-
Whether to renew certificates or not
type: boolean
default: false
examples:
- false
12 changes: 10 additions & 2 deletions docs/home/CERTIFICATES.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## TLS certificates in a cluster

It's possible to regenerate kubernetes control plane certificates with epiphany.
It's possible to regenerate Kubernetes control plane certificates with Epiphany.
To do so, additional configuration should be specified.

```yaml
Expand All @@ -22,6 +22,14 @@ Parameters (optional):
1. expiration_days - days to expire in, default value is `365`
2. renew - whether to renew certificates or not, default value is `false`

---
**NOTE**

Usage of values greater than 24855 for `expiration_days` is not possible.
For more information see [discussion](https://groups.google.com/g/mailing.openssl.users/c/3kK_f0ywCZQ) about that.

---

When `epicly apply` executes, if `renew` option is set to `true`, following certificates will be renewed with expiration period defined by `expiration_days`:

1. admin.conf
Expand All @@ -45,7 +53,7 @@ To verify that, navigate to `/var/lib/kubelet/` and check `config.yaml` file, wh

## CA certificates rotation

This part cannot be done by epiphany. Refer to official kubernetes [documentation](https://kubernetes.io/docs/tasks/tls/manual-rotation-of-ca-certificates/) to perform this task.
This part cannot be done by Epiphany. Refer to official Kubernetes [documentation](https://kubernetes.io/docs/tasks/tls/manual-rotation-of-ca-certificates/) to perform this task.

## References

Expand Down