Skip to content

Commit 6da20e2

Browse files
committed
kubeadm support
* move k8s master to a subtask * disable k8s secrets when using kubeadm * fix etcd cert serial var * move simple auth users to master role * make a kubeadm-specific env file for kubelet * add non-ha CI job
1 parent e8bde03 commit 6da20e2

File tree

35 files changed

+449
-106
lines changed

35 files changed

+449
-106
lines changed

.gitlab-ci.yml

+42-2
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ before_script:
5353
IDEMPOT_CHECK: "false"
5454
RESET_CHECK: "false"
5555
UPGRADE_TEST: "false"
56+
KUBEADM_ENABLED: "false"
5657
RESOLVCONF_MODE: docker_dns
5758
LOG_LEVEL: "-vv"
5859
ETCD_DEPLOYMENT: "docker"
@@ -127,6 +128,7 @@ before_script:
127128
-e local_release_dir=${PWD}/downloads
128129
-e resolvconf_mode=${RESOLVCONF_MODE}
129130
-e vault_deployment_type=${VAULT_DEPLOYMENT}
131+
-e kubeadm_enabled=${KUBEADM_ENABLED}
130132
-e "${AUTHORIZATION_MODES}"
131133
--limit "all:!fake_hosts"
132134
cluster.yml
@@ -153,6 +155,8 @@ before_script:
153155
-e kubelet_deployment_type=${KUBELET_DEPLOYMENT}
154156
-e local_release_dir=${PWD}/downloads
155157
-e resolvconf_mode=${RESOLVCONF_MODE}
158+
-e vault_deployment_type=${VAULT_DEPLOYMENT}
159+
-e kubeadm_enabled=${KUBEADM_ENABLED}
156160
-e weave_cpu_requests=${WEAVE_CPU_LIMIT}
157161
-e weave_cpu_limit=${WEAVE_CPU_LIMIT}
158162
-e "${AUTHORIZATION_MODES}"
@@ -181,11 +185,15 @@ before_script:
181185
-e download_localhost=${DOWNLOAD_LOCALHOST}
182186
-e download_run_once=${DOWNLOAD_RUN_ONCE}
183187
-e deploy_netchecker=true
184-
-e resolvconf_mode=${RESOLVCONF_MODE}
185-
-e local_release_dir=${PWD}/downloads
186188
-e etcd_deployment_type=${ETCD_DEPLOYMENT}
187189
-e kubedns_min_replicas=1
188190
-e kubelet_deployment_type=${KUBELET_DEPLOYMENT}
191+
-e local_release_dir=${PWD}/downloads
192+
-e resolvconf_mode=${RESOLVCONF_MODE}
193+
-e vault_deployment_type=${VAULT_DEPLOYMENT}
194+
-e kubeadm_enabled=${KUBEADM_ENABLED}
195+
-e weave_cpu_requests=${WEAVE_CPU_LIMIT}
196+
-e weave_cpu_limit=${WEAVE_CPU_LIMIT}
189197
-e "${AUTHORIZATION_MODES}"
190198
--limit "all:!fake_hosts"
191199
cluster.yml;
@@ -280,6 +288,17 @@ before_script:
280288
UPGRADE_TEST: "graceful"
281289
STARTUP_SCRIPT: ""
282290

291+
.ubuntu_canal_kubeadm_variables: &ubuntu_canal_kubeadm_variables
292+
# stage: deploy-gce-part1
293+
KUBE_NETWORK_PLUGIN: canal
294+
AUTHORIZATION_MODES: "{ 'authorization_modes': [ 'RBAC' ] }"
295+
CLOUD_IMAGE: ubuntu-1604-xenial
296+
CLOUD_MACHINE_TYPE: "n1-standard-2"
297+
CLOUD_REGION: europe-west1-b
298+
CLUSTER_MODE: default
299+
KUBEADM_ENABLED: "true"
300+
STARTUP_SCRIPT: ""
301+
283302
.rhel7_weave_variables: &rhel7_weave_variables
284303
# stage: deploy-gce-part1
285304
KUBE_NETWORK_PLUGIN: weave
@@ -470,6 +489,27 @@ ubuntu-canal-ha-rbac-triggers:
470489
when: on_success
471490
only: ['triggers']
472491

492+
ubuntu-canal-kubeadm-rbac:
493+
stage: deploy-gce-part1
494+
<<: *job
495+
<<: *gce
496+
variables:
497+
<<: *gce_variables
498+
<<: *ubuntu_canal_kubeadm_variables
499+
when: manual
500+
except: ['triggers']
501+
only: ['master', /^pr-.*$/]
502+
503+
ubuntu-canal-kubeadm-triggers:
504+
stage: deploy-gce-part1
505+
<<: *job
506+
<<: *gce
507+
variables:
508+
<<: *gce_variables
509+
<<: *ubuntu_canal_kubeadm_variables
510+
when: on_success
511+
only: ['triggers']
512+
473513
rhel7-weave:
474514
stage: deploy-gce-part1
475515
<<: *job

cluster.yml

+11
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,17 @@
6969
roles:
7070
- { role: kubespray-defaults}
7171
- { role: kubernetes/master, tags: master }
72+
73+
- hosts: k8s-cluster
74+
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
75+
roles:
76+
- { role: kubespray-defaults}
77+
- { role: kubernetes/kubeadm, tags: kubeadm, when: "kubeadm_enabled" }
78+
79+
- hosts: kube-master
80+
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
81+
roles:
82+
- { role: kubespray-defaults}
7283
- { role: kubernetes-apps/network_plugin, tags: network }
7384
- { role: kubernetes-apps/policy_controller, tags: policy-controller }
7485

inventory/group_vars/all.yml

+4
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ bin_dir: /usr/local/bin
8282
#openstack_lbaas_monitor_timeout: "30s"
8383
#openstack_lbaas_monitor_max_retries: "3"
8484

85+
## Uncomment to enable experimental kubeadm deployment mode
86+
#kubeadm_enabled: false
87+
#kubeadm_token: "{{ lookup('password', 'credentials/kubeadm_token length=15') }}"
88+
#
8589
## Set these proxy values in order to update docker daemon to use proxies
8690
#http_proxy: ""
8791
#https_proxy: ""

library/kube.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -135,24 +135,27 @@ def _execute_nofail(self, cmd):
135135
return None
136136
return out.splitlines()
137137

138-
def create(self, check=True):
138+
def create(self, check=True, force=True):
139139
if check and self.exists():
140140
return []
141141

142142
cmd = ['apply']
143143

144+
if force:
145+
cmd.append('--force')
146+
144147
if not self.filename:
145148
self.module.fail_json(msg='filename required to create')
146149

147150
cmd.append('--filename=' + self.filename)
148151

149152
return self._execute(cmd)
150153

151-
def replace(self):
154+
def replace(self, force=True):
152155

153156
cmd = ['apply']
154157

155-
if self.force:
158+
if force:
156159
cmd.append('--force')
157160

158161
if not self.filename:

roles/download/defaults/main.yml

+13-1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ download_always_pull: False
1919

2020
# Versions
2121
kube_version: v1.7.3
22+
kubeadm_version: "{{ kube_version }}"
2223
etcd_version: v3.2.4
2324
# TODO(mattymo): Move calico versions to roles/network_plugins/calico/defaults
2425
# after migration to container download
@@ -31,11 +32,13 @@ flannel_version: "v0.8.0"
3132
flannel_cni_version: "v0.2.0"
3233
pod_infra_version: 3.0
3334

34-
# Download URL's
35+
# Download URLs
3536
etcd_download_url: "https://storage.googleapis.com/kargo/{{etcd_version}}_etcd"
37+
kubeadm_download_url: "https://storage.googleapis.com/kubernetes-release/release/{{ kubeadm_version }}/bin/linux/amd64/kubeadm"
3638

3739
# Checksums
3840
etcd_checksum: "274c46a7f8d26f7ae99d6880610f54933cbcf7f3beafa19236c52eb5df8c7a0b"
41+
kubeadm_checksum: "378e6052f8b178f8e6a38e8637681c72d389443b66b78b51b8ddc9a162c655c3"
3942

4043
# Containers
4144
# Possible values: host, docker
@@ -132,6 +135,15 @@ downloads:
132135
container: "{{ etcd_deployment_type in [ 'docker', 'rkt' ] }}"
133136
repo: "{{ etcd_image_repo }}"
134137
tag: "{{ etcd_image_tag }}"
138+
kubeadm:
139+
version: "{{ kubeadm_version }}"
140+
dest: "kubeadm"
141+
sha256: "{{ kubeadm_checksum }}"
142+
source_url: "{{ kubeadm_download_url }}"
143+
url: "{{ kubeadm_download_url }}"
144+
unarchive: false
145+
owner: "root"
146+
mode: "0755"
135147
hyperkube:
136148
container: true
137149
repo: "{{ hyperkube_image_repo }}"

roles/etcd/tasks/main.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
- name: "Gen_certs | Get etcd certificate serials"
1313
shell: "openssl x509 -in {{ etcd_cert_dir }}/node-{{ inventory_hostname }}.pem -noout -serial | cut -d= -f2"
14-
register: "node-{{ inventory_hostname }}_serial"
14+
register: "etcd_client_cert_serial"
1515
when: inventory_hostname in groups['k8s-cluster']|union(groups['etcd'])|union(groups['calico-rr']|default([]))|unique|sort
1616

1717
- include: "install_{{ etcd_deployment_type }}.yml"

roles/kubernetes-apps/ansible/tasks/main.yml

+12
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,18 @@
88
delay: 6
99
when: inventory_hostname == groups['kube-master'][0]
1010

11+
- name: kubeadm | Delete kubeadm kubedns
12+
kube:
13+
name: "kubedns"
14+
namespace: "{{ system_namespace }}"
15+
kubectl: "{{bin_dir}}/kubectl"
16+
resource: "deploy"
17+
state: absent
18+
when:
19+
- kubeadm_enabled|default(false)
20+
- kubeadm_init.changed|default(false)
21+
- inventory_hostname == groups['kube-master'][0]
22+
1123
- name: Kubernetes Apps | Lay Down KubeDNS Template
1224
template:
1325
src: "{{item.file}}"
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
- name: Set kubeadm_discovery_address
3+
set_fact:
4+
kubeadm_discovery_address: >-
5+
{%- if "127.0.0.1" or "localhost" in kube_apiserver_endpoint -%}
6+
{{ first_kube_master }}:{{ kube_apiserver_port }}
7+
{%- else -%}
8+
{{ kube_apiserver_endpoint }}
9+
{%- endif %}
10+
when: not is_kube_master
11+
tags: facts
12+
13+
- name: Create kubeadm client config
14+
template:
15+
src: kubeadm-client.conf.j2
16+
dest: "{{ kube_config_dir }}/kubeadm-client.conf"
17+
backup: yes
18+
when: not is_kube_master
19+
register: kubeadm_client_conf
20+
21+
- name: Join to cluster if needed
22+
command: kubeadm join --config {{ kube_config_dir}}/kubeadm-client.conf --skip-preflight-checks
23+
register: kubeadm_join
24+
when: not is_kube_master and kubeadm_client_conf.changed
25+
26+
- name: Update server field in kubelet kubeconfig
27+
replace:
28+
path: "{{ kube_config_dir }}/kubelet.conf"
29+
regexp: '(\s+){{ first_kube_master }}:{{ kube_apiserver_port }}(\s+.*)?$'
30+
replace: '\1{{ kube_apiserver_endpoint }}\2'
31+
backup: yes
32+
when: not is_kube_master and kubeadm_discovery_address != kube_apiserver_endpoint
33+
34+
# FIXME(mattymo): Reconcile kubelet kubeconfig filename for both deploy modes
35+
- name: Symlink kubelet kubeconfig for calico/canal
36+
file:
37+
src: "{{ kube_config_dir }}//kubelet.conf"
38+
dest: "{{ kube_config_dir }}/node-kubeconfig.yaml"
39+
state: link
40+
force: yes
41+
when: kube_network_plugin in ['calico','canal']
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: kubeadm.k8s.io/v1alpha1
2+
kind: NodeConfiguration
3+
caCertPath: {{ kube_config_dir }}/ssl/ca.crt
4+
token: {{ kubeadm_token }}
5+
discoveryTokenAPIServers:
6+
- {{ kubeadm_discovery_address | replace("https://", "")}}

roles/kubernetes/master/defaults/main.yml

+4
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,7 @@ apiserver_custom_flags: []
6666
controller_mgr_custom_flags: []
6767

6868
scheduler_custom_flags: []
69+
70+
# kubeadm settings
71+
# Value of 0 means it never expires
72+
kubeadm_token_ttl: 0

roles/kubernetes/master/handlers/main.yml

+4
Original file line numberDiff line numberDiff line change
@@ -44,3 +44,7 @@
4444
until: result.status == 200
4545
retries: 20
4646
delay: 6
47+
48+
- name: Master | set secret_changed
49+
set_fact:
50+
secret_changed: true
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
- name: kubeadm | aggregate all SANs
3+
set_fact:
4+
apiserver_sans: >-
5+
kubernetes
6+
kubernetes.default
7+
kubernetes.default.svc
8+
kubernetes.default.svc.{{ dns_domain }}
9+
{{ kube_apiserver_ip }}
10+
localhost
11+
127.0.0.1
12+
{{ ' '.join(groups['kube-master']) }}
13+
{%- if loadbalancer_apiserver is defined and apiserver_loadbalancer_domain_name is defined %}
14+
{{ apiserver_loadbalancer_domain_name }}
15+
{%- endif %}
16+
{%- for host in groups['kube-master'] -%}
17+
{%- if hostvars[host]['access_ip'] is defined %}{{ hostvars[host]['access_ip'] }}{% endif -%}
18+
{{ hostvars[host]['ip'] | default(hostvars[host]['ansible_default_ipv4']['address']) }}
19+
{%- endfor %}
20+
tags: facts
21+
22+
- name: kubeadm | Copy etcd cert dir under k8s cert dir
23+
command: "cp -TR {{ etcd_cert_dir }} {{ kube_config_dir }}/ssl/etcd"
24+
changed_when: false
25+
26+
- name: kubeadm | Create kubeadm config
27+
template:
28+
src: kubeadm-config.yaml.j2
29+
dest: "{{ kube_config_dir }}/kubeadm-config.yaml"
30+
register: kubeadm_config
31+
32+
- name: kubeadm | Initialize cluster
33+
command: timeout -k 240s 240s kubeadm init --config={{ kube_config_dir }}/kubeadm-config.yaml --skip-preflight-checks
34+
register: kubeadm_init
35+
when: kubeadm_config.changed

roles/kubernetes/master/tasks/main.yml

+9-59
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
- include: pre-upgrade.yml
33
tags: k8s-pre-upgrade
44

5+
- include: users-file.yml
6+
when: kube_basic_auth|default(true)
7+
58
- name: Copy kubectl from hyperkube container
69
command: "{{ docker_bin_dir }}/docker run --rm -v {{ bin_dir }}:/systembindir {{ hyperkube_image_repo }}:{{ hyperkube_image_tag }} /bin/cp /hyperkube /systembindir/kubectl"
710
register: kube_task_result
@@ -25,63 +28,10 @@
2528
when: ansible_os_family in ["Debian","RedHat"]
2629
tags: [kubectl, upgrade]
2730

28-
- name: Write kube-apiserver manifest
29-
template:
30-
src: manifests/kube-apiserver.manifest.j2
31-
dest: "{{ kube_manifest_dir }}/kube-apiserver.manifest"
32-
notify: Master | wait for the apiserver to be running
33-
tags: kube-apiserver
34-
35-
- meta: flush_handlers
36-
37-
- name: Write kube system namespace manifest
38-
template:
39-
src: namespace.j2
40-
dest: "{{kube_config_dir}}/{{system_namespace}}-ns.yml"
41-
run_once: yes
42-
when: inventory_hostname == groups['kube-master'][0]
43-
tags: apps
44-
45-
- name: Check if kube system namespace exists
46-
command: "{{ bin_dir }}/kubectl get ns {{system_namespace}}"
47-
register: 'kubesystem'
48-
changed_when: False
49-
failed_when: False
50-
run_once: yes
51-
tags: apps
52-
53-
- name: Create kube system namespace
54-
command: "{{ bin_dir }}/kubectl create -f {{kube_config_dir}}/{{system_namespace}}-ns.yml"
55-
retries: 4
56-
delay: "{{ retry_stagger | random + 3 }}"
57-
register: create_system_ns
58-
until: create_system_ns.rc == 0
59-
changed_when: False
60-
when: kubesystem|failed and inventory_hostname == groups['kube-master'][0]
61-
tags: apps
62-
63-
- name: Write kube-scheduler kubeconfig
64-
template:
65-
src: kube-scheduler-kubeconfig.yaml.j2
66-
dest: "{{ kube_config_dir }}/kube-scheduler-kubeconfig.yaml"
67-
tags: kube-scheduler
68-
69-
- name: Write kube-scheduler manifest
70-
template:
71-
src: manifests/kube-scheduler.manifest.j2
72-
dest: "{{ kube_manifest_dir }}/kube-scheduler.manifest"
73-
notify: Master | wait for kube-scheduler
74-
tags: kube-scheduler
75-
76-
- name: Write kube-controller-manager kubeconfig
77-
template:
78-
src: kube-controller-manager-kubeconfig.yaml.j2
79-
dest: "{{ kube_config_dir }}/kube-controller-manager-kubeconfig.yaml"
80-
tags: kube-controller-manager
31+
- task: Include kubeadm setup if enabled
32+
include: kubeadm-setup.yml
33+
when: kubeadm_enabled|bool|default(false)
8134

82-
- name: Write kube-controller-manager manifest
83-
template:
84-
src: manifests/kube-controller-manager.manifest.j2
85-
dest: "{{ kube_manifest_dir }}/kube-controller-manager.manifest"
86-
notify: Master | wait for kube-controller-manager
87-
tags: kube-controller-manager
35+
- task: Include static pod setup if not using kubeadm
36+
include: static-pod-setup.yml
37+
when: not kubeadm_enabled|bool|default(false)

0 commit comments

Comments
 (0)