Skip to content
Commits on Source (2)
......@@ -281,6 +281,11 @@ node_taints:
* `audit_webhook_batch_max_wait`: 1s
* *kubectl_alias* - Bash alias of kubectl to interact with Kubernetes cluster much easier.
* *remove_anonymous_access* - When set to `true`, removes the `kubeadm:bootstrap-signer-clusterinfo` rolebinding created by kubeadm.
By default, kubeadm creates a rolebinding in the `kube-public` namespace which grants permissions to anonymous users. This rolebinding allows kubeadm to discover and validate cluster information during the join phase.
In a nutshell, this option removes the rolebinding after the init phase of the first control plane node and then configures kubeadm to use file discovery for the join phase of other nodes.
This option does not remove the anonymous authentication feature of the API server.
### Custom flags for Kube Components
For all kube components, custom flags can be passed in. This allows for edge cases where users need changes to the default deployment that may not be applicable to all deployments.
......
......@@ -371,3 +371,6 @@ kubeadm_patches:
enabled: false
source_dir: "{{ inventory_dir }}/patches"
dest_dir: "{{ kube_config_dir }}/patches"
# Set to true to remove the role binding to anonymous users created by kubeadm
remove_anonymous_access: false
......@@ -240,3 +240,6 @@ kubeadm_upgrade_auto_cert_renewal: true
kube_apiserver_tracing: false
kube_apiserver_tracing_endpoint: 0.0.0.0:4317
kube_apiserver_tracing_sampling_rate_per_million: 100
# Enable kubeadm file discovery if anonymous access has been removed
kubeadm_use_file_discovery: "{{ remove_anonymous_access }}"
......@@ -63,6 +63,26 @@
- kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists
- not kube_external_ca_mode
- name: Get kubeconfig for join discovery process
command: "{{ kubectl }} -n kube-public get cm cluster-info -o jsonpath='{.data.kubeconfig}'"
register: kubeconfig_file_discovery
run_once: true
delegate_to: "{{ groups['kube_control_plane'] | first }}"
when:
- kubeadm_use_file_discovery
- kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists
- name: Copy discovery kubeconfig
copy:
dest: "{{ kube_config_dir }}/cluster-info-discovery-kubeconfig.yaml"
content: "{{ kubeconfig_file_discovery.stdout }}"
owner: "root"
mode: 0644
when:
- inventory_hostname != first_kube_control_plane
- kubeadm_use_file_discovery
- kubeadm_already_run is not defined or not kubeadm_already_run.stat.exists
- name: Joining control plane node to the cluster.
command: >-
{{ bin_dir }}/kubeadm join
......
......@@ -221,12 +221,16 @@
{{ bin_dir }}/kubeadm --kubeconfig {{ kube_config_dir }}/admin.conf token create {{ kubeadm_token }}
changed_when: false
when:
- inventory_hostname == first_kube_control_plane
- inventory_hostname == first_kube_control_plane
- kubeadm_token is defined
- kubeadm_refresh_token
tags:
- kubeadm_token
- name: Remove binding to anonymous user
command: "{{ kubectl }} -n kube-public delete rolebinding kubeadm:bootstrap-signer-clusterinfo --ignore-not-found"
when: inventory_hostname == first_kube_control_plane and remove_anonymous_access
- name: Create kubeadm token for joining nodes with 24h expiration (default)
command: "{{ bin_dir }}/kubeadm --kubeconfig {{ kube_config_dir }}/admin.conf token create"
changed_when: false
......
......@@ -53,6 +53,10 @@
PATH: "{{ bin_dir }}:{{ ansible_env.PATH }}"
notify: Master | restart kubelet
- name: Kubeadm | Remove binding to anonymous user
command: "{{ kubectl }} -n kube-public delete rolebinding kubeadm:bootstrap-signer-clusterinfo --ignore-not-found"
when: remove_anonymous_access
- name: Kubeadm | clean kubectl cache to refresh api types
file:
path: "{{ item }}"
......
apiVersion: kubeadm.k8s.io/v1beta3
kind: JoinConfiguration
discovery:
{% if kubeadm_use_file_discovery %}
file:
kubeConfigPath: {{ kube_config_dir }}/cluster-info-discovery-kubeconfig.yaml
{% else %}
bootstrapToken:
{% if kubeadm_config_api_fqdn is defined %}
apiServerEndpoint: {{ kubeadm_config_api_fqdn }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }}
......@@ -9,6 +13,7 @@ discovery:
{% endif %}
token: {{ kubeadm_token }}
unsafeSkipCAVerification: true
{% endif %}
timeout: {{ discovery_timeout }}
tlsBootstrapToken: {{ kubeadm_token }}
controlPlane:
......
......@@ -4,6 +4,9 @@
discovery_timeout: 60s
kubeadm_join_timeout: 120s
# Enable kubeadm file discovery if anonymous access has been removed
kubeadm_use_file_discovery: "{{ remove_anonymous_access }}"
# If non-empty, will use this string as identification instead of the actual hostname
kube_override_hostname: >-
{%- if cloud_provider is defined and cloud_provider in ['aws'] -%}
......
......@@ -57,6 +57,24 @@
set_fact:
kubeadmConfig_api_version: v1beta3
- name: Get kubeconfig for join discovery process
command: "{{ kubectl }} -n kube-public get cm cluster-info -o jsonpath='{.data.kubeconfig}'"
register: kubeconfig_file_discovery
run_once: true
delegate_to: "{{ groups['kube_control_plane'] | first }}"
when: kubeadm_use_file_discovery
- name: Copy discovery kubeconfig
copy:
dest: "{{ kube_config_dir }}/cluster-info-discovery-kubeconfig.yaml"
content: "{{ kubeconfig_file_discovery.stdout }}"
owner: "root"
mode: 0644
when:
- not is_kube_master
- not kubelet_conf.stat.exists
- kubeadm_use_file_discovery
- name: Create kubeadm client config
template:
src: "kubeadm-client.conf.{{ kubeadmConfig_api_version }}.j2"
......
......@@ -2,6 +2,10 @@
apiVersion: kubeadm.k8s.io/v1beta3
kind: JoinConfiguration
discovery:
{% if kubeadm_use_file_discovery %}
file:
kubeConfigPath: {{ kube_config_dir }}/cluster-info-discovery-kubeconfig.yaml
{% else %}
bootstrapToken:
{% if kubeadm_config_api_fqdn is defined %}
apiServerEndpoint: {{ kubeadm_config_api_fqdn }}:{{ loadbalancer_apiserver.port | default(kube_apiserver_port) }}
......@@ -14,6 +18,7 @@ discovery:
- sha256:{{ kubeadm_ca_hash.stdout }}
{% else %}
unsafeSkipCAVerification: true
{% endif %}
{% endif %}
timeout: {{ discovery_timeout }}
tlsBootstrapToken: {{ kubeadm_token }}
......
......@@ -6,6 +6,8 @@ ansible_ssh_common_args: "{% if 'bastion' in groups['all'] %} -o ProxyCommand='s
# selinux state
preinstall_selinux_state: permissive
# Setting this value to false will fail
# For details, read this comment https://github.com/kubernetes-sigs/kubespray/pull/11016#issuecomment-2004985001
kube_api_anonymous_auth: true
# Default value, but will be set to true automatically if detected
......@@ -50,6 +52,9 @@ kubeadm_join_phases_skip_default: []
kubeadm_join_phases_skip: >-
{{ kubeadm_join_phases_skip_default }}
# Set to true to remove the role binding to anonymous users created by kubeadm
remove_anonymous_access: false
# A string slice of values which specify the addresses to use for NodePorts.
# Values may be valid IP blocks (e.g. 1.2.3.0/24, 1.2.3.4/32).
# The default empty string slice ([]) means to use all local addresses.
......
......@@ -38,7 +38,7 @@ spec:
# deletion": https://kubernetes.io/docs/concepts/workloads/pods/pod/#termination-of-pods.
terminationGracePeriodSeconds: 0
initContainers:
{% if calico_datastore == "kdd" %}
{% if calico_datastore == "kdd" and not calico_ipam_host_local %}
# This container performs upgrade from host-local IPAM to calico-ipam.
# It can be deleted if this is a fresh installation, or if you have already
# upgraded to use calico-ipam.
......@@ -310,6 +310,10 @@ spec:
value: "{{ calico_node_ignorelooserpf }}"
- name: CALICO_MANAGE_CNI
value: "true"
{% if calico_ipam_host_local %}
- name: USE_POD_CIDR
value: "true"
{% endif %}
{% if calico_node_extra_envs is defined %}
{% for key in calico_node_extra_envs %}
- name: {{ key }}
......@@ -428,7 +432,7 @@ spec:
hostPath:
path: /run/xtables.lock
type: FileOrCreate
{% if calico_datastore == "kdd" %}
{% if calico_datastore == "kdd" and not calico_ipam_host_local %}
# Mount in the directory for host-local IPAM allocations. This is
# used when upgrading from host-local to calico-ipam, and can be removed
# if not using the upgrade-ipam init container.
......
......@@ -136,11 +136,10 @@ spec:
name: cacert
readOnly: true
{% endif %}
# Needed for version >=3.7 when the 'host-local' ipam is used
# Should never happen given templates/cni-calico.conflist.j2
# Configure route aggregation based on pod CIDR.
# - name: USE_POD_CIDR
# value: "true"
{% if calico_ipam_host_local %}
- name: USE_POD_CIDR
value: "true"
{% endif %}
livenessProbe:
httpGet:
path: /liveness
......
......@@ -11,3 +11,6 @@ calico_network_backend: bird
# Needed to bypass deprecation check
ignore_assert_errors: true
# Remove anonymous access to cluster
remove_anonymous_access: true
......@@ -104,3 +104,6 @@ kube_cert_group: root
# kube-system namespace is exempted by default
kube_pod_security_use_default: true
kube_pod_security_default_enforce: restricted
# Remove anonymous access to cluster
remove_anonymous_access: true
......@@ -9,3 +9,6 @@ etcd_deployment_type: kubeadm
# Currently ipvs not available on KVM: https://packages.ubuntu.com/search?suite=focal&arch=amd64&mode=exactfilename&searchon=contents&keywords=ip_vs_sh.ko
kube_proxy_mode: iptables
enable_nodelocaldns: False
# Remove anonymous access to cluster
remove_anonymous_access: true