From 1c5391dda78b43fc629320dd59f1234e81afb2ad Mon Sep 17 00:00:00 2001
From: Etienne Champetier <e.champetier@ateme.com>
Date: Tue, 16 Feb 2021 11:44:58 -0500
Subject: [PATCH] Ensure kubeadm doesn't use proxy (#7275)

* Move proxy_env to kubespray-defaults/defaults

There is no reasons to use set_facts here

Signed-off-by: Etienne Champetier <e.champetier@ateme.com>

* Ensure kubeadm doesn't use proxy

*_proxy variables might be present in the environment (/etc/environment, bash profile, ...)
When this is the case we end up with those proxy configuration in /etc/kubernetes/manifests/kube-*.yaml manifests

We cannot unset env variables, but kubeadm is nice enough to ignore empty vars
https://github.com/kubernetes/kubernetes/blob/93d288e2a47fa6d497b50d37c8b3a04e91da4228/cmd/kubeadm/app/util/env.go#L27

Signed-off-by: Etienne Champetier <e.champetier@ateme.com>
---
 roles/download/tasks/prep_kubeadm_images.yml  |  1 +
 .../tasks/kubeadm-fix-apiserver.yml           |  1 +
 .../control-plane/tasks/kubeadm-secondary.yml |  4 ++--
 .../control-plane/tasks/kubeadm-setup.yml     |  5 +++--
 .../control-plane/tasks/kubeadm-version.yml   |  1 +
 .../kubeadm/tasks/kubeadm_etcd_node.yml       |  1 +
 roles/kubernetes/kubeadm/tasks/main.yml       |  5 +++--
 roles/kubernetes/node/tasks/kubelet.yml       |  1 +
 roles/kubespray-defaults/defaults/main.yaml   | 20 +++++++++++++++++++
 roles/kubespray-defaults/tasks/main.yaml      | 13 ------------
 scale.yml                                     |  1 +
 11 files changed, 34 insertions(+), 19 deletions(-)

diff --git a/roles/download/tasks/prep_kubeadm_images.yml b/roles/download/tasks/prep_kubeadm_images.yml
index fa829e8f0..d004f9367 100644
--- a/roles/download/tasks/prep_kubeadm_images.yml
+++ b/roles/download/tasks/prep_kubeadm_images.yml
@@ -38,6 +38,7 @@
   shell: "set -o pipefail && {{ bin_dir }}/kubeadm config images list --config={{ kube_config_dir }}/kubeadm-images.yaml | grep -Ev 'coredns|pause'"
   args:
     executable: /bin/bash
+  environment: "{{ proxy_disable_env }}"
   register: kubeadm_images_raw
   run_once: true
   changed_when: false
diff --git a/roles/kubernetes/control-plane/tasks/kubeadm-fix-apiserver.yml b/roles/kubernetes/control-plane/tasks/kubeadm-fix-apiserver.yml
index 6ebfb179a..c589dd76d 100644
--- a/roles/kubernetes/control-plane/tasks/kubeadm-fix-apiserver.yml
+++ b/roles/kubernetes/control-plane/tasks/kubeadm-fix-apiserver.yml
@@ -20,6 +20,7 @@
     {{ bin_dir }}/kubeadm init phase kubeconfig all
     --config {{ kube_config_dir }}/kubeadm-config.yaml
     --kubeconfig-dir {{ kubeconfig_temp_dir.path }}
+  environment: "{{ proxy_disable_env }}"
   when: kubeconfig_correct_apiserver.rc != 0
 
 - name: Copy new kubeconfigs to kube config dir
diff --git a/roles/kubernetes/control-plane/tasks/kubeadm-secondary.yml b/roles/kubernetes/control-plane/tasks/kubeadm-secondary.yml
index 75eea9132..13b844204 100644
--- a/roles/kubernetes/control-plane/tasks/kubeadm-secondary.yml
+++ b/roles/kubernetes/control-plane/tasks/kubeadm-secondary.yml
@@ -16,6 +16,7 @@
     --config {{ kube_config_dir }}/kubeadm-config.yaml
     upload-certs
     --upload-certs
+  environment: "{{ proxy_disable_env }}"
   register: kubeadm_upload_cert
   when:
     - inventory_hostname == groups['kube-master']|first
@@ -57,6 +58,7 @@
     {{ bin_dir }}/kubeadm join
     --config {{ kube_config_dir }}/kubeadm-controlplane.yaml
     --ignore-preflight-errors=all
+  environment: '{{ proxy_disable_env | combine({"PATH": "{{ bin_dir }}:{{ ansible_env.PATH }}"}) }}'
   register: kubeadm_join_control_plane
   retries: 3
   throttle: 1
@@ -64,8 +66,6 @@
   when:
     - inventory_hostname != groups['kube-master']|first
     - kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists
-  environment:
-    PATH: "{{ bin_dir }}:{{ ansible_env.PATH }}"
 
 - name: Set secret_changed to false to avoid extra token rotation
   set_fact:
diff --git a/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml b/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml
index 6fa9cfd7f..eb89a9104 100644
--- a/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml
+++ b/roles/kubernetes/control-plane/tasks/kubeadm-setup.yml
@@ -165,8 +165,7 @@
   until: kubeadm_init is succeeded or "field is immutable" in kubeadm_init.stderr
   when: inventory_hostname == groups['kube-master']|first and not kubeadm_already_run.stat.exists
   failed_when: kubeadm_init.rc != 0 and "field is immutable" not in kubeadm_init.stderr
-  environment:
-    PATH: "{{ bin_dir }}:{{ ansible_env.PATH }}"
+  environment: '{{ proxy_disable_env | combine({"PATH": "{{ bin_dir }}:{{ ansible_env.PATH }}"}) }}'
   notify: Master | restart kubelet
 
 - name: set kubeadm certificate key
@@ -181,6 +180,7 @@
   shell: >-
     {{ bin_dir }}/kubeadm --kubeconfig /etc/kubernetes/admin.conf token delete {{ kubeadm_token }} || :;
     {{ bin_dir }}/kubeadm --kubeconfig /etc/kubernetes/admin.conf token create {{ kubeadm_token }}
+  environment: "{{ proxy_disable_env }}"
   changed_when: false
   when:
     - inventory_hostname == groups['kube-master']|first
@@ -191,6 +191,7 @@
 
 - name: Create kubeadm token for joining nodes with 24h expiration (default)
   command: "{{ bin_dir }}/kubeadm --kubeconfig /etc/kubernetes/admin.conf token create"
+  environment: "{{ proxy_disable_env }}"
   changed_when: false
   register: temp_token
   retries: 5
diff --git a/roles/kubernetes/control-plane/tasks/kubeadm-version.yml b/roles/kubernetes/control-plane/tasks/kubeadm-version.yml
index 8c7feea35..2793c77ab 100644
--- a/roles/kubernetes/control-plane/tasks/kubeadm-version.yml
+++ b/roles/kubernetes/control-plane/tasks/kubeadm-version.yml
@@ -1,6 +1,7 @@
 ---
 - name: Get the kubeadm version
   command: "{{ bin_dir }}/kubeadm version -o short"
+  environment: "{{ proxy_disable_env }}"
   register: kubeadm_output
   changed_when: false
 
diff --git a/roles/kubernetes/kubeadm/tasks/kubeadm_etcd_node.yml b/roles/kubernetes/kubeadm/tasks/kubeadm_etcd_node.yml
index b5c0f2552..27e0c5f93 100644
--- a/roles/kubernetes/kubeadm/tasks/kubeadm_etcd_node.yml
+++ b/roles/kubernetes/kubeadm/tasks/kubeadm_etcd_node.yml
@@ -22,6 +22,7 @@
     {{ kubeadm_discovery_address }}
   args:
     creates: "{{ kube_cert_dir }}/apiserver-etcd-client.key"
+  environment: "{{ proxy_disable_env }}"
 
 - name: Delete unneeded certificates
   file:
diff --git a/roles/kubernetes/kubeadm/tasks/main.yml b/roles/kubernetes/kubeadm/tasks/main.yml
index b939b38c4..276e139be 100644
--- a/roles/kubernetes/kubeadm/tasks/main.yml
+++ b/roles/kubernetes/kubeadm/tasks/main.yml
@@ -42,6 +42,7 @@
 
 - name: Create kubeadm token for joining nodes with 24h expiration (default)
   command: "{{ bin_dir }}/kubeadm token create"
+  environment: "{{ proxy_disable_env }}"
   register: temp_token
   delegate_to: "{{ groups['kube-master'][0] }}"
   when: kubeadm_token is not defined
@@ -54,6 +55,7 @@
 
 - name: Get the kubeadm version
   command: "{{ bin_dir }}/kubeadm version -o short"
+  environment: "{{ proxy_disable_env }}"
   register: kubeadm_output
   changed_when: false
 
@@ -69,8 +71,7 @@
   when: not is_kube_master
 
 - name: Join to cluster if needed
-  environment:
-    PATH: "{{ bin_dir }}:{{ ansible_env.PATH }}:/sbin"  # Make sure we can workaround RH / CentOS conservative path management
+  environment: '{{ proxy_disable_env | combine({"PATH": "{{ bin_dir }}:{{ ansible_env.PATH }}:/sbin"}) }}'
   when: not is_kube_master and (not kubelet_conf.stat.exists)
   block:
 
diff --git a/roles/kubernetes/node/tasks/kubelet.yml b/roles/kubernetes/node/tasks/kubelet.yml
index cb95cc174..68cd0ff63 100644
--- a/roles/kubernetes/node/tasks/kubelet.yml
+++ b/roles/kubernetes/node/tasks/kubelet.yml
@@ -8,6 +8,7 @@
 
 - name: Get the kubeadm version
   command: "{{ bin_dir }}/kubeadm version -o short"
+  environment: "{{ proxy_disable_env }}"
   register: kubeadm_output
   changed_when: false
 
diff --git a/roles/kubespray-defaults/defaults/main.yaml b/roles/kubespray-defaults/defaults/main.yaml
index cd8a47d6c..00a1dc00b 100644
--- a/roles/kubespray-defaults/defaults/main.yaml
+++ b/roles/kubespray-defaults/defaults/main.yaml
@@ -553,3 +553,23 @@ host_architecture: >-
 # Sets the eventRecordQPS parameter in kubelet-config.yaml. The default value is 5 (see types.go)
 # Setting it to 0 allows unlimited requests per second.
 kubelet_event_record_qps: 5
+
+proxy_env:
+  http_proxy: "{{ http_proxy | default ('') }}"
+  HTTP_PROXY: "{{ http_proxy | default ('') }}"
+  https_proxy: "{{ https_proxy | default ('') }}"
+  HTTPS_PROXY: "{{ https_proxy | default ('') }}"
+  no_proxy: "{{ no_proxy | default ('') }}"
+  NO_PROXY: "{{ no_proxy | default ('') }}"
+
+proxy_disable_env:
+  ALL_PROXY: ''
+  FTP_PROXY: ''
+  HTTPS_PROXY: ''
+  HTTP_PROXY: ''
+  NO_PROXY: ''
+  all_proxy: ''
+  ftp_proxy: ''
+  http_proxy: ''
+  https_proxy: ''
+  no_proxy: ''
diff --git a/roles/kubespray-defaults/tasks/main.yaml b/roles/kubespray-defaults/tasks/main.yaml
index 7c0c5d240..fe268e953 100644
--- a/roles/kubespray-defaults/tasks/main.yaml
+++ b/roles/kubespray-defaults/tasks/main.yaml
@@ -5,19 +5,6 @@
   tags:
     - always
 
-- name: "Set up proxy environment"
-  set_fact:
-    proxy_env:
-      http_proxy: "{{ http_proxy | default ('') }}"
-      HTTP_PROXY: "{{ http_proxy | default ('') }}"
-      https_proxy: "{{ https_proxy | default ('') }}"
-      HTTPS_PROXY: "{{ https_proxy | default ('') }}"
-      no_proxy: "{{ no_proxy | default ('') }}"
-      NO_PROXY: "{{ no_proxy | default ('') }}"
-  no_log: true
-  tags:
-    - always
-
 # do not run gather facts when bootstrap-os in roles
 - name: set fallback_ips
   import_tasks: fallback_ips.yml
diff --git a/scale.yml b/scale.yml
index 52f59d22c..a47e67507 100644
--- a/scale.yml
+++ b/scale.yml
@@ -69,6 +69,7 @@
         --config {{ kube_config_dir }}/kubeadm-config.yaml
         upload-certs
         --upload-certs
+      environment: "{{ proxy_disable_env }}"
       register: kubeadm_upload_cert
       changed_when: false
     - name: set fact 'kubeadm_certificate_key' for later use
-- 
GitLab