Browse Source
kubeadm support (#1631)
kubeadm support (#1631)
* 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 * change ci boolean vars to json format * fixup * Update create-gce.yml * Update create-gce.yml * Update create-gce.ymlpull/1661/head
Matthew Mosesohn
7 years ago
committed by
GitHub
35 changed files with 469 additions and 120 deletions
Split View
Diff Options
-
78.gitlab-ci.yml
-
11cluster.yml
-
6inventory/group_vars/all.yml
-
9library/kube.py
-
14roles/download/defaults/main.yml
-
2roles/etcd/tasks/main.yml
-
12roles/kubernetes-apps/ansible/tasks/main.yml
-
41roles/kubernetes/kubeadm/tasks/main.yml
-
6roles/kubernetes/kubeadm/templates/kubeadm-client.conf.j2
-
4roles/kubernetes/master/defaults/main.yml
-
4roles/kubernetes/master/handlers/main.yml
-
35roles/kubernetes/master/tasks/kubeadm-setup.yml
-
68roles/kubernetes/master/tasks/main.yml
-
61roles/kubernetes/master/tasks/static-pod-setup.yml
-
14roles/kubernetes/master/tasks/users-file.yml
-
0roles/kubernetes/master/templates/known_users.csv.j2
-
67roles/kubernetes/master/templates/kubeadm-config.yaml.j2
-
2roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2
-
2roles/kubernetes/master/templates/manifests/kube-controller-manager.manifest.j2
-
5roles/kubernetes/node/meta/main.yml
-
12roles/kubernetes/node/tasks/install.yml
-
16roles/kubernetes/node/tasks/main.yml
-
2roles/kubernetes/node/templates/kubelet.host.service.j2
-
57roles/kubernetes/node/templates/kubelet.kubeadm.env.j2
-
0roles/kubernetes/node/templates/kubelet.standard.env.j2
-
25roles/kubernetes/preinstall/tasks/main.yml
-
1roles/kubernetes/preinstall/vars/centos.yml
-
1roles/kubernetes/preinstall/vars/debian.yml
-
1roles/kubernetes/preinstall/vars/fedora.yml
-
1roles/kubernetes/preinstall/vars/redhat.yml
-
7roles/kubernetes/preinstall/vars/ubuntu.yml
-
17roles/kubernetes/secrets/tasks/main.yml
-
4roles/kubespray-defaults/defaults/main.yaml
-
2roles/network_plugin/calico/templates/calico-node.yml.j2
-
2upgrade-cluster.yml
@ -0,0 +1,41 @@ |
|||
--- |
|||
- name: Set kubeadm_discovery_address |
|||
set_fact: |
|||
kubeadm_discovery_address: >- |
|||
{%- if "127.0.0.1" or "localhost" in kube_apiserver_endpoint -%} |
|||
{{ first_kube_master }}:{{ kube_apiserver_port }} |
|||
{%- else -%} |
|||
{{ kube_apiserver_endpoint }} |
|||
{%- endif %} |
|||
when: not is_kube_master |
|||
tags: facts |
|||
|
|||
- name: Create kubeadm client config |
|||
template: |
|||
src: kubeadm-client.conf.j2 |
|||
dest: "{{ kube_config_dir }}/kubeadm-client.conf" |
|||
backup: yes |
|||
when: not is_kube_master |
|||
register: kubeadm_client_conf |
|||
|
|||
- name: Join to cluster if needed |
|||
command: kubeadm join --config {{ kube_config_dir}}/kubeadm-client.conf --skip-preflight-checks |
|||
register: kubeadm_join |
|||
when: not is_kube_master and kubeadm_client_conf.changed |
|||
|
|||
- name: Update server field in kubelet kubeconfig |
|||
replace: |
|||
path: "{{ kube_config_dir }}/kubelet.conf" |
|||
regexp: '(\s+){{ first_kube_master }}:{{ kube_apiserver_port }}(\s+.*)?$' |
|||
replace: '\1{{ kube_apiserver_endpoint }}\2' |
|||
backup: yes |
|||
when: not is_kube_master and kubeadm_discovery_address != kube_apiserver_endpoint |
|||
|
|||
# FIXME(mattymo): Reconcile kubelet kubeconfig filename for both deploy modes |
|||
- name: Symlink kubelet kubeconfig for calico/canal |
|||
file: |
|||
src: "{{ kube_config_dir }}//kubelet.conf" |
|||
dest: "{{ kube_config_dir }}/node-kubeconfig.yaml" |
|||
state: link |
|||
force: yes |
|||
when: kube_network_plugin in ['calico','canal'] |
@ -0,0 +1,6 @@ |
|||
apiVersion: kubeadm.k8s.io/v1alpha1 |
|||
kind: NodeConfiguration |
|||
caCertPath: {{ kube_config_dir }}/ssl/ca.crt |
|||
token: {{ kubeadm_token }} |
|||
discoveryTokenAPIServers: |
|||
- {{ kubeadm_discovery_address | replace("https://", "")}} |
@ -0,0 +1,35 @@ |
|||
--- |
|||
- name: kubeadm | aggregate all SANs |
|||
set_fact: |
|||
apiserver_sans: >- |
|||
kubernetes |
|||
kubernetes.default |
|||
kubernetes.default.svc |
|||
kubernetes.default.svc.{{ dns_domain }} |
|||
{{ kube_apiserver_ip }} |
|||
localhost |
|||
127.0.0.1 |
|||
{{ ' '.join(groups['kube-master']) }} |
|||
{%- if loadbalancer_apiserver is defined and apiserver_loadbalancer_domain_name is defined %} |
|||
{{ apiserver_loadbalancer_domain_name }} |
|||
{%- endif %} |
|||
{%- for host in groups['kube-master'] -%} |
|||
{%- if hostvars[host]['access_ip'] is defined %}{{ hostvars[host]['access_ip'] }}{% endif -%} |
|||
{{ hostvars[host]['ip'] | default(hostvars[host]['ansible_default_ipv4']['address']) }} |
|||
{%- endfor %} |
|||
tags: facts |
|||
|
|||
- name: kubeadm | Copy etcd cert dir under k8s cert dir |
|||
command: "cp -TR {{ etcd_cert_dir }} {{ kube_config_dir }}/ssl/etcd" |
|||
changed_when: false |
|||
|
|||
- name: kubeadm | Create kubeadm config |
|||
template: |
|||
src: kubeadm-config.yaml.j2 |
|||
dest: "{{ kube_config_dir }}/kubeadm-config.yaml" |
|||
register: kubeadm_config |
|||
|
|||
- name: kubeadm | Initialize cluster |
|||
command: timeout -k 240s 240s kubeadm init --config={{ kube_config_dir }}/kubeadm-config.yaml --skip-preflight-checks |
|||
register: kubeadm_init |
|||
when: kubeadm_config.changed |
@ -0,0 +1,61 @@ |
|||
--- |
|||
- name: Write kube-apiserver manifest |
|||
template: |
|||
src: manifests/kube-apiserver.manifest.j2 |
|||
dest: "{{ kube_manifest_dir }}/kube-apiserver.manifest" |
|||
notify: Master | wait for the apiserver to be running |
|||
tags: kube-apiserver |
|||
|
|||
- meta: flush_handlers |
|||
|
|||
- name: Write kube system namespace manifest |
|||
template: |
|||
src: namespace.j2 |
|||
dest: "{{kube_config_dir}}/{{system_namespace}}-ns.yml" |
|||
run_once: yes |
|||
when: inventory_hostname == groups['kube-master'][0] |
|||
tags: apps |
|||
|
|||
- name: Check if kube system namespace exists |
|||
command: "{{ bin_dir }}/kubectl get ns {{system_namespace}}" |
|||
register: 'kubesystem' |
|||
changed_when: False |
|||
failed_when: False |
|||
run_once: yes |
|||
tags: apps |
|||
|
|||
- name: Create kube system namespace |
|||
command: "{{ bin_dir }}/kubectl create -f {{kube_config_dir}}/{{system_namespace}}-ns.yml" |
|||
retries: 4 |
|||
delay: "{{ retry_stagger | random + 3 }}" |
|||
register: create_system_ns |
|||
until: create_system_ns.rc == 0 |
|||
changed_when: False |
|||
when: kubesystem|failed and inventory_hostname == groups['kube-master'][0] |
|||
tags: apps |
|||
|
|||
- name: Write kube-scheduler kubeconfig |
|||
template: |
|||
src: kube-scheduler-kubeconfig.yaml.j2 |
|||
dest: "{{ kube_config_dir }}/kube-scheduler-kubeconfig.yaml" |
|||
tags: kube-scheduler |
|||
|
|||
- name: Write kube-scheduler manifest |
|||
template: |
|||
src: manifests/kube-scheduler.manifest.j2 |
|||
dest: "{{ kube_manifest_dir }}/kube-scheduler.manifest" |
|||
notify: Master | wait for kube-scheduler |
|||
tags: kube-scheduler |
|||
|
|||
- name: Write kube-controller-manager kubeconfig |
|||
template: |
|||
src: kube-controller-manager-kubeconfig.yaml.j2 |
|||
dest: "{{ kube_config_dir }}/kube-controller-manager-kubeconfig.yaml" |
|||
tags: kube-controller-manager |
|||
|
|||
- name: Write kube-controller-manager manifest |
|||
template: |
|||
src: manifests/kube-controller-manager.manifest.j2 |
|||
dest: "{{ kube_manifest_dir }}/kube-controller-manager.manifest" |
|||
notify: Master | wait for kube-controller-manager |
|||
tags: kube-controller-manager |
@ -0,0 +1,14 @@ |
|||
--- |
|||
- name: Make sure the users directory exits |
|||
file: |
|||
path: "{{ kube_users_dir }}" |
|||
state: directory |
|||
mode: o-rwx |
|||
group: "{{ kube_cert_group }}" |
|||
|
|||
- name: Populate users for basic auth in API |
|||
template: |
|||
src: known_users.csv.j2 |
|||
dest: "{{ kube_users_dir }}/known_users.csv" |
|||
backup: yes |
|||
notify: Master | set secret_changed |
@ -0,0 +1,67 @@ |
|||
apiVersion: kubeadm.k8s.io/v1alpha1 |
|||
kind: MasterConfiguration |
|||
api: |
|||
advertiseAddress: {{ ip | default(ansible_default_ipv4.address) }} |
|||
bindPort: "{{ kube_apiserver_port }}" |
|||
etcd: |
|||
endpoints: |
|||
{% for endpoint in etcd_access_endpoint.split(',') %} |
|||
- {{ endpoint }} |
|||
{% endfor %} |
|||
caFile: {{ kube_config_dir }}/ssl/etcd/ca.pem |
|||
certFile: {{ kube_config_dir }}/ssl/etcd/node-{{ inventory_hostname }}.pem |
|||
keyFile: {{ kube_config_dir }}/ssl/etcd/node-{{ inventory_hostname }}-key.pem |
|||
networking: |
|||
dnsDomain: {{ dns_domain }} |
|||
serviceSubnet: {{ kube_service_addresses }} |
|||
podSubnet: {{ kube_pods_subnet }} |
|||
kubernetesVersion: {{ kube_version }} |
|||
cloudProvider: {{ cloud_provider|default('') }} |
|||
#TODO: cloud provider conf file |
|||
authorizationModes: |
|||
{% for mode in authorization_modes %} |
|||
- {{ mode }} |
|||
{% endfor %} |
|||
token: {{ kubeadm_token }} |
|||
tokenTTL: {{ kubeadm_token_ttl }} |
|||
selfHosted: false |
|||
apiServerExtraArgs: |
|||
insecure-bind-address: {{ kube_apiserver_insecure_bind_address }} |
|||
insecure-port: "{{ kube_apiserver_insecure_port }}" |
|||
admission-control: {{ kube_apiserver_admission_control | join(',') }} |
|||
service-node-port-range: {{ kube_apiserver_node_port_range }} |
|||
{% if kube_basic_auth|default(true) %} |
|||
basic-auth-file: {{ kube_users_dir }}/known_users.csv |
|||
{% endif %} |
|||
{% if kube_oidc_auth|default(false) and kube_oidc_url is defined and kube_oidc_client_id is defined %} |
|||
oidc-issuer-url: {{ kube_oidc_url }} |
|||
oidc-client-id: {{ kube_oidc_client_id }} |
|||
{% if kube_oidc_ca_file is defined %} |
|||
oidc-ca-file: {{ kube_oidc_ca_file }} |
|||
{% endif %} |
|||
{% if kube_oidc_username_claim is defined %} |
|||
oidc-username-claim: {{ kube_oidc_username_claim }} |
|||
{% endif %} |
|||
{% if kube_oidc_groups_claim is defined %} |
|||
oidc-groups-claim: {{ kube_oidc_groups_claim }} |
|||
{% endif %} |
|||
{% endif %} |
|||
storage-backend: {{ kube_apiserver_storage_backend }} |
|||
{% if kube_api_runtime_config is defined %} |
|||
runtime-config: {{ kube_api_runtime_config }} |
|||
{% endif %} |
|||
allow-privileged: "true" |
|||
#TODO: Custom flags compatible with kubeadm |
|||
controllerManagerExtraArgs: |
|||
node-monitor-grace-period: {{ kube_controller_node_monitor_grace_period }} |
|||
node-monitor-period: {{ kube_controller_node_monitor_period }} |
|||
pod-eviction-timeout: {{ kube_controller_pod_eviction_timeout }} |
|||
{% if kube_feature_gates %} |
|||
feature-gates: {{ kube_feature_gates|join(',') }} |
|||
{% endif %} |
|||
#schedulerExtraArgs: |
|||
apiServerCertSANs: |
|||
{% for san in apiserver_sans.split(' ') | unique %} |
|||
- {{ san }} |
|||
{% endfor %} |
|||
certificatesDir: {{ kube_config_dir }}/ssl |
@ -0,0 +1,57 @@ |
|||
### Upstream source https://github.com/kubernetes/release/blob/master/debian/xenial/kubeadm/channel/stable/etc/systemd/system/kubelet.service.d/10-kubeadm.conf |
|||
### All upstream values should be present in this file |
|||
|
|||
# logging to stderr means we get it in the systemd journal |
|||
KUBE_LOGGING="--logtostderr=true" |
|||
KUBE_LOG_LEVEL="--v={{ kube_log_level }}" |
|||
# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces) |
|||
KUBELET_ADDRESS="--address={{ ip | default("0.0.0.0") }}" |
|||
# The port for the info server to serve on |
|||
# KUBELET_PORT="--port=10250" |
|||
# You may leave this blank to use the actual hostname |
|||
{% if kube_override_hostname %} |
|||
KUBELET_HOSTNAME="--hostname-override={{ kube_override_hostname }}" |
|||
{% endif %} |
|||
{# Base kubelet args #} |
|||
{% set kubelet_args_base -%} |
|||
{# start kubeadm specific settings #} |
|||
--kubeconfig={{ kube_config_dir }}/kubelet.conf \ |
|||
--require-kubeconfig=true \ |
|||
--authorization-mode=Webhook \ |
|||
--client-ca-file={{ kube_cert_dir }}/ca.crt \ |
|||
--pod-manifest-path={{ kube_manifest_dir }} \ |
|||
--cadvisor-port=0 \ |
|||
{# end kubeadm specific settings #} |
|||
--pod-infra-container-image={{ pod_infra_image_repo }}:{{ pod_infra_image_tag }} \ |
|||
--kube-reserved cpu={{ kubelet_cpu_limit }},memory={{ kubelet_memory_limit|regex_replace('Mi', 'M') }} \ |
|||
--node-status-update-frequency={{ kubelet_status_update_frequency }} \ |
|||
{% endset %} |
|||
|
|||
{# DNS settings for kubelet #} |
|||
{% if dns_mode == 'kubedns' %} |
|||
{% set kubelet_args_cluster_dns %}--cluster-dns={{ skydns_server }}{% endset %} |
|||
{% elif dns_mode == 'dnsmasq_kubedns' %} |
|||
{% set kubelet_args_cluster_dns %}--cluster-dns={{ dns_server }}{% endset %} |
|||
{% else %} |
|||
{% set kubelet_args_cluster_dns %}{% endset %} |
|||
{% endif %} |
|||
{% set kubelet_args_dns %}{{ kubelet_args_cluster_dns }} --cluster-domain={{ dns_domain }} --resolv-conf={{ kube_resolv_conf }}{% endset %} |
|||
|
|||
|
|||
KUBELET_ARGS="{{ kubelet_args_base }} {{ kubelet_args_dns }}" |
|||
{% if kube_network_plugin is defined and kube_network_plugin in ["calico", "canal", "flannel", "weave"] %} |
|||
KUBELET_NETWORK_PLUGIN="--network-plugin=cni --network-plugin-dir=/etc/cni/net.d --cni-bin-dir=/opt/cni/bin" |
|||
{% elif kube_network_plugin is defined and kube_network_plugin == "cloud" %} |
|||
KUBELET_NETWORK_PLUGIN="--hairpin-mode=promiscuous-bridge --network-plugin=kubenet" |
|||
{% endif %} |
|||
# Should this cluster be allowed to run privileged docker containers |
|||
KUBE_ALLOW_PRIV="--allow-privileged=true" |
|||
{% if cloud_provider is defined and cloud_provider in ["openstack", "azure", "vsphere"] %} |
|||
KUBELET_CLOUDPROVIDER="--cloud-provider={{ cloud_provider }} --cloud-config={{ kube_config_dir }}/cloud_config" |
|||
{% elif cloud_provider is defined and cloud_provider == "aws" %} |
|||
KUBELET_CLOUDPROVIDER="--cloud-provider={{ cloud_provider }}" |
|||
{% else %} |
|||
KUBELET_CLOUDPROVIDER="" |
|||
{% endif %} |
|||
|
|||
PATH={{ bin_dir }}:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |
@ -0,0 +1,7 @@ |
|||
--- |
|||
required_pkgs: |
|||
- python-apt |
|||
- aufs-tools |
|||
- apt-transport-https |
|||
- software-properties-common |
|||
- ebtables |
Write
Preview
Loading…
Cancel
Save