-
Notifications
You must be signed in to change notification settings - Fork 637
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
Refine deployment rollouts #1222
Changes from all commits
e589ceb
ad531c8
b3a7436
94d68bf
f042cb3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,9 +13,17 @@ | |
- status.phase=Running | ||
register: tower_pod | ||
|
||
- name: Set the resource pod as a variable. | ||
set_fact: | ||
tower_pod: >- | ||
{{ tower_pod['resources'] | ||
| rejectattr('metadata.deletionTimestamp', 'defined') | ||
| sort(attribute='metadata.creationTimestamp') | ||
| first | default({}) }} | ||
|
||
- name: Set the resource pod name as a variable. | ||
set_fact: | ||
tower_pod_name: "{{ tower_pod['resources'][0]['metadata']['name'] | default('') }}" | ||
tower_pod_name: "{{ tower_pod['metadata']['name'] | default('') }}" | ||
|
||
- name: Set user provided control plane ee image | ||
set_fact: | ||
|
@@ -32,13 +40,13 @@ | |
kind: Secret | ||
namespace: '{{ ansible_operator_meta.namespace }}' | ||
name: '{{ ansible_operator_meta.name }}-receptor-ca' | ||
register: _receptor_ca | ||
register: receptor_ca | ||
no_log: "{{ no_log }}" | ||
|
||
- name: Migrate Receptor CA Secret | ||
when: | ||
- _receptor_ca['resources'] | default([]) | length | ||
- _receptor_ca['resources'][0]['type'] != "kubernetes.io/tls" | ||
- receptor_ca['resources'] | default([]) | length | ||
- receptor_ca['resources'][0]['type'] != "kubernetes.io/tls" | ||
block: | ||
- name: Delete old Receptor CA Secret | ||
k8s: | ||
|
@@ -53,7 +61,7 @@ | |
register: _receptor_ca_key_file | ||
- name: Copy Receptor CA key from old secret to tempfile | ||
copy: | ||
content: "{{ _receptor_ca['resources'][0]['data']['receptor-ca.key'] | b64decode }}" | ||
content: "{{ receptor_ca['resources'][0]['data']['receptor-ca.key'] | b64decode }}" | ||
dest: "{{ _receptor_ca_key_file.path }}" | ||
no_log: "{{ no_log }}" | ||
- name: Create tempfile for receptor-ca.crt | ||
|
@@ -63,14 +71,25 @@ | |
register: _receptor_ca_crt_file | ||
- name: Copy Receptor CA cert from old secret to tempfile | ||
copy: | ||
content: "{{ _receptor_ca['resources'][0]['data']['receptor-ca.crt'] | b64decode }}" | ||
content: "{{ receptor_ca['resources'][0]['data']['receptor-ca.crt'] | b64decode }}" | ||
dest: "{{ _receptor_ca_crt_file.path }}" | ||
no_log: "{{ no_log }}" | ||
- name: Create New Receptor CA secret | ||
k8s: | ||
apply: true | ||
definition: "{{ lookup('template', 'secrets/receptor_ca_secret.yaml.j2') }}" | ||
no_log: "{{ no_log }}" | ||
- name: Read New Receptor CA Secret | ||
k8s_info: | ||
kind: Secret | ||
namespace: '{{ ansible_operator_meta.namespace }}' | ||
name: '{{ ansible_operator_meta.name }}-receptor-ca' | ||
register: _receptor_ca | ||
no_log: "{{ no_log }}" | ||
- name: Set receptor_ca variable | ||
set_fact: | ||
receptor_ca: '{{ _receptor_ca }}' | ||
no_log: "{{ no_log }}" | ||
- name: Remove tempfiles | ||
file: | ||
path: "{{ item }}" | ||
|
@@ -106,21 +125,32 @@ | |
apply: true | ||
definition: "{{ lookup('template', 'secrets/receptor_ca_secret.yaml.j2') }}" | ||
no_log: "{{ no_log }}" | ||
- name: Read Receptor CA secret | ||
k8s_info: | ||
kind: Secret | ||
namespace: '{{ ansible_operator_meta.namespace }}' | ||
name: '{{ ansible_operator_meta.name }}-receptor-ca' | ||
register: _receptor_ca | ||
no_log: "{{ no_log }}" | ||
- name: Set receptor_ca variable | ||
set_fact: | ||
receptor_ca: '{{ _receptor_ca }}' | ||
no_log: "{{ no_log }}" | ||
- name: Remove tempfiles | ||
file: | ||
path: "{{ item }}" | ||
state: absent | ||
loop: | ||
- "{{ _receptor_ca_key_file.path }}" | ||
- "{{ _receptor_ca_crt_file.path }}" | ||
when: not _receptor_ca['resources'] | default([]) | length | ||
when: not receptor_ca['resources'] | default([]) | length | ||
|
||
- name: Check for Receptor work signing Secret | ||
k8s_info: | ||
kind: Secret | ||
namespace: '{{ ansible_operator_meta.namespace }}' | ||
name: '{{ ansible_operator_meta.name }}-receptor-work-signing' | ||
register: _receptor_work_signing | ||
register: receptor_work_signing | ||
no_log: "{{ no_log }}" | ||
|
||
- name: Generate Receptor work signing RSA key pair | ||
|
@@ -151,21 +181,31 @@ | |
apply: true | ||
definition: "{{ lookup('template', 'secrets/receptor_work_signing_secret.yaml.j2') }}" | ||
no_log: "{{ no_log }}" | ||
- name: Read Receptor work signing Secret | ||
k8s_info: | ||
kind: Secret | ||
namespace: '{{ ansible_operator_meta.namespace }}' | ||
name: '{{ ansible_operator_meta.name }}-receptor-work-signing' | ||
register: _receptor_work_signing | ||
no_log: "{{ no_log }}" | ||
- name: Set receptor_work_signing variable | ||
set_fact: | ||
receptor_work_signing: '{{ _receptor_work_signing }}' | ||
no_log: "{{ no_log }}" | ||
- name: Remove tempfiles | ||
file: | ||
path: "{{ item }}" | ||
state: absent | ||
loop: | ||
- "{{ _receptor_work_signing_private_key_file.path }}" | ||
- "{{ _receptor_work_signing_public_key_file.path }}" | ||
when: not _receptor_work_signing['resources'] | default([]) | length | ||
when: not receptor_work_signing['resources'] | default([]) | length | ||
|
||
- name: Apply Resources | ||
k8s: | ||
apply: yes | ||
definition: "{{ lookup('template', item + '.yaml.j2') }}" | ||
wait: yes | ||
register: tower_resources_result | ||
loop: | ||
- 'configmaps/config' | ||
- 'secrets/app_credentials' | ||
|
@@ -210,21 +250,10 @@ | |
apply: yes | ||
definition: "{{ lookup('template', 'deployments/deployment.yaml.j2') }}" | ||
wait: yes | ||
wait_timeout: "{{ 120 * replicas or 120 }}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @stanislav-zaprudskiy could you expand on why you added this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adding the corresponding commit message just in case it got missed
The corresponding parameter Just to add, also the Deployment's rollout strategy configuration could increase the time for having the new pods ready. There could be cases when scheduling new pods may not be possible (e.g. due to lack of resources, or wrong image configuration, etc) - but the operator would stuck (unnecessary) waiting. Having lower timeout value would make users aware of the problem earlier - but in multi-replica AWX configurations running in multi-node clusters where image caches aren't generally available, the lower timeout values provide too much false-positive failures of operator runs. |
||
register: this_deployment_result | ||
|
||
- block: | ||
- name: Delete pod to reload a resource configuration | ||
k8s: | ||
api_version: v1 | ||
state: absent | ||
kind: Pod | ||
namespace: '{{ ansible_operator_meta.namespace }}' | ||
name: '{{ tower_pod_name }}' | ||
wait: yes | ||
when: | ||
- tower_resources_result.changed | ||
- tower_pod_name | length | ||
|
||
- name: Get the new resource pod information after updating resource. | ||
k8s_info: | ||
kind: Pod | ||
|
@@ -236,17 +265,20 @@ | |
field_selectors: | ||
- status.phase=Running | ||
register: _new_pod | ||
until: | ||
- _new_pod['resources'] | length | ||
- _new_pod['resources'][0]['metadata']['name'] != tower_pod_name | ||
delay: 5 | ||
retries: 60 | ||
|
||
- name: Update new resource pod as a variable. | ||
set_fact: | ||
tower_pod: >- | ||
{{ _new_pod['resources'] | ||
| rejectattr('metadata.deletionTimestamp', 'defined') | ||
| sort(attribute='metadata.creationTimestamp') | ||
| last | default({}) }} | ||
|
||
- name: Update new resource pod name as a variable. | ||
set_fact: | ||
tower_pod_name: '{{ _new_pod["resources"][0]["metadata"]["name"] }}' | ||
tower_pod_name: '{{ tower_pod["metadata"]["name"] | default("")}}' | ||
when: | ||
- tower_resources_result.changed or this_deployment_result.changed | ||
- this_deployment_result.changed | ||
|
||
- name: Verify the resource pod name is populated. | ||
assert: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,10 +40,10 @@ | |
|
||
- name: Set secret key secret | ||
set_fact: | ||
__secret_key_secret: '{{ _generated_secret_key["resources"] | default([]) | length | ternary(_generated_secret_key, _secret_key_secret) }}' | ||
secret_key: '{{ _generated_secret_key["resources"] | default([]) | length | ternary(_generated_secret_key, _secret_key_secret) }}' | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I want to do some testing around this before merging. cc @TheRealHaoLiu |
||
no_log: "{{ no_log }}" | ||
|
||
- name: Store secret key secret name | ||
set_fact: | ||
secret_key_secret_name: "{{ __secret_key_secret['resources'][0]['metadata']['name'] }}" | ||
secret_key_secret_name: "{{ secret_key['resources'][0]['metadata']['name'] }}" | ||
no_log: "{{ no_log }}" |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,8 +20,25 @@ spec: | |
labels: | ||
{{ lookup("template", "../common/templates/labels/common.yaml.j2") | indent(width=8) | trim }} | ||
{{ lookup("template", "../common/templates/labels/version.yaml.j2") | indent(width=8) | trim }} | ||
{% if annotations %} | ||
annotations: | ||
{% for template in [ | ||
"configmaps/config", | ||
"secrets/app_credentials", | ||
"storage/persistent", | ||
] %} | ||
checksum-{{ template | replace('/', '-') }}: "{{ lookup('template', template + '.yaml.j2') | md5 }}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ❤️ This is a great trick! This is an elegant solution to the issue of deployments not being cycled when changes are made to the ConfigMap. @TheRealHaoLiu is impressed too. |
||
{% endfor %} | ||
{% for secret in [ | ||
"bundle_cacert", | ||
"route_tls", | ||
"ldap_cacert", | ||
"secret_key", | ||
"receptor_ca", | ||
"receptor_work_signing", | ||
] %} | ||
checksum-secret-{{ secret }}: "{{ lookup('ansible.builtin.vars', secret, default='')["resources"][0]["data"] | default('') | md5 }}" | ||
{% endfor %} | ||
{% if annotations %} | ||
{{ annotations | indent(width=8) }} | ||
{% endif %} | ||
spec: | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will prevent us from grabbing a pod that is in terminating state. It also ensures that only one pod is grabbed (the oldest).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just adding the corresponding commit message in case it got missed
I've also encountered a couple of cases when
Terminating
pod was picked up, and runningawx-manage
command on it during the later tasks was not possible (the pod was gone already, etc).Here indeed the oldest pod is taken, while later in the code the newest (the one most recently created) is used.