From 2138cc7d6916645f8c0aac4b4ca45bb14a8c4574 Mon Sep 17 00:00:00 2001 From: Jeff Geerling Date: Mon, 14 May 2018 22:27:26 -0500 Subject: [PATCH] Fixes #2: Make role work with nodes joining master. --- README.md | 44 ++++++++++++++++++++++++++++-- defaults/main.yml | 4 +++ tasks/main.yml | 62 ++++++++---------------------------------- tasks/master-setup.yml | 57 ++++++++++++++++++++++++++++++++++++++ tasks/node-setup.yml | 5 ++++ 5 files changed, 118 insertions(+), 54 deletions(-) create mode 100644 tasks/master-setup.yml create mode 100644 tasks/node-setup.yml diff --git a/README.md b/README.md index 044b82e..df990c7 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,10 @@ Available variables are listed below, along with default values (see `defaults/m Kubernetes packages to be installed on the server. You can either provide a list of package names, or set `name` and `state` to have more control over whether the package is `present`, `absent`, `latest`, etc. + kubernetes_role: master + +Whether the particular server will serve as a Kubernetes `master` (default) or `node`. The master will have `kubeadm init` run on it to intialize the entire K8s control plane, while `node`s will have `kubeadm join` run on them to join them to the `master`. + kubernetes_kubelet_extra_args: "" Extra args to pass to `kubelet` during startup. E.g. to allow `kubelet` to start up even if there is swap is enabled on your server, set this to: `"--fail-swap-on=false"`. @@ -34,11 +38,16 @@ Whether to remove the taint that denies pods from being deployed to the Kubernet Whether to enable the Kubernetes web dashboard UI (only accessible on the master itself, or proxied). + kuberenetes_debug: False + +Whether to show extra debug info in Ansible's logs (e.g. the output of the `kubeadm init` command). + kubernetes_pod_network_cidr: '10.0.1.0/16' + kubernetes_apiserver_advertise_address: '' kubernetes_version: 'stable-1.10' kubernetes_ignore_preflight_errors: 'all' -Options passed to `kubeadm init` when initializing the Kubernetes master. +Options passed to `kubeadm init` when initializing the Kubernetes master. The `apiserver_advertise_address` defaults to `ansible_default_ipv4.address` if it's left empty. kubernetes_apt_release_channel: main kubernetes_apt_repository: "deb http://apt.kubernetes.io/ kubernetes-xenial {{ kubernetes_apt_release_channel }}" @@ -54,9 +63,9 @@ Yum repository options for Kubernetes installation. None. -## Example Playbook +## Example Playbooks -For a single node (master) Kubernetes cluster: +### Single node (master-only) cluster ```yaml - hosts: all @@ -69,6 +78,35 @@ For a single node (master) Kubernetes cluster: - geerlingguy.kubernetes ``` +### Two or more nodes (single master) cluster + +Master inventory vars: + +```yaml +kubernetes_role: "master" +``` + +Node(s) inventory vars: + +```yaml +kubernetes_role: "node" +``` + +Playbook: + +```yaml +- hosts: all + + vars: + kubernetes_allow_pods_on_master: True + + roles: + - geerlingguy.docker + - geerlingguy.kubernetes +``` + +Then, log into the Kubernetes master, and run `kubectl get nodes` as root, and you should see a list of all the servers. + ## License MIT / BSD diff --git a/defaults/main.yml b/defaults/main.yml index 56bcc01..c762218 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -9,12 +9,16 @@ kubernetes_packages: - name: kubernetes-cni state: present +kubernetes_role: master + kubernetes_kubelet_extra_args: "" kubernetes_allow_pods_on_master: True kubernetes_enable_web_ui: True +kuberenetes_debug: False kubernetes_pod_network_cidr: '10.0.1.0/16' +kubernetes_apiserver_advertise_address: '' kubernetes_version: 'stable-1.10' kubernetes_ignore_preflight_errors: 'all' diff --git a/tasks/main.yml b/tasks/main.yml index fdd555d..d6b8c0e 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -35,57 +35,17 @@ path: /etc/kubernetes/admin.conf register: kubernetes_init_stat -- name: Initialize the Kubernetes master with kubeadm init. - command: > - kubeadm init - --pod-network-cidr={{ kubernetes_pod_network_cidr }} - --apiserver-advertise-address={{ ansible_default_ipv4.address }} - --kubernetes-version {{ kubernetes_version }} - --ignore-preflight-errors={{ kubernetes_ignore_preflight_errors }} - register: kubeadmin_init - failed_when: False - when: kubernetes_init_stat.stat.exists == False +# Set up master. +- include_tasks: master-setup.yml + when: kubernetes_role == 'master' -- name: Print the init output to screen. - debug: var=kubeadmin_init.stdout - when: kubernetes_init_stat.stat.exists == False - -- name: Ensure .kube directory exists. - file: - path: ~/.kube - state: directory - -- name: Symlink the kubectl admin.conf to ~/.kube/conf. - file: - src: /etc/kubernetes/admin.conf - dest: ~/.kube/config - state: link - -- name: Configure Flannel networking. - command: "{{ item }}" - with_items: - - kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml - - kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml - register: flannel_result - changed_when: "'created' in flannel_result.stdout" - -# TODO: Check if taint exists with something like `kubectl describe nodes` -# instead of using kubernetes_init_stat.stat.exists check. -- name: Allow pods on master node (if configured). - command: "kubectl taint nodes --all node-role.kubernetes.io/master-" - when: - - kubernetes_allow_pods_on_master - - kubernetes_init_stat.stat.exists == False - -- name: Check if Kubernetes Dashboard UI service already exists. - shell: kubectl get services --namespace kube-system | grep -q kubernetes-dashboard +# Set up nodes. +- name: Get the kubeadm join command from the Kubernetes master. + shell: kubeadm token create --print-join-command changed_when: False - failed_when: False - register: kubernetes_dashboard_service - when: kubernetes_enable_web_ui + when: kubernetes_role == 'master' + run_once: True + register: kubernetes_join_command -- name: Enable the Kubernetes Web Dashboard UI (if configured). - command: "kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml" - when: - - kubernetes_enable_web_ui - - kubernetes_dashboard_service is failed +- include_tasks: node-setup.yml + when: kubernetes_role == 'node' diff --git a/tasks/master-setup.yml b/tasks/master-setup.yml new file mode 100644 index 0000000..3b4a1bb --- /dev/null +++ b/tasks/master-setup.yml @@ -0,0 +1,57 @@ +--- +- name: Initialize Kubernetes master with kubeadm init. + command: > + kubeadm init + --pod-network-cidr={{ kubernetes_pod_network_cidr }} + --apiserver-advertise-address={{ kubernetes_apiserver_advertise_address | default(ansible_default_ipv4.address) }} + --kubernetes-version {{ kubernetes_version }} + --ignore-preflight-errors={{ kubernetes_ignore_preflight_errors }} + register: kubeadmin_init + failed_when: False + when: kubernetes_init_stat.stat.exists == False + +- name: Print the init output to screen. + debug: var=kubeadmin_init.stdout + when: + - kuberenetes_debug + - kubernetes_init_stat.stat.exists == False + +- name: Ensure .kube directory exists. + file: + path: ~/.kube + state: directory + +- name: Symlink the kubectl admin.conf to ~/.kube/conf. + file: + src: /etc/kubernetes/admin.conf + dest: ~/.kube/config + state: link + +- name: Configure Flannel networking. + command: "{{ item }}" + with_items: + - kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml + - kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml + register: flannel_result + changed_when: "'created' in flannel_result.stdout" + +# TODO: Check if taint exists with something like `kubectl describe nodes` +# instead of using kubernetes_init_stat.stat.exists check. +- name: Allow pods on master node (if configured). + command: "kubectl taint nodes --all node-role.kubernetes.io/master-" + when: + - kubernetes_allow_pods_on_master + - kubernetes_init_stat.stat.exists == False + +- name: Check if Kubernetes Dashboard UI service already exists. + shell: kubectl get services --namespace kube-system | grep -q kubernetes-dashboard + changed_when: False + failed_when: False + register: kubernetes_dashboard_service + when: kubernetes_enable_web_ui + +- name: Enable the Kubernetes Web Dashboard UI (if configured). + command: "kubectl create -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml" + when: + - kubernetes_enable_web_ui + - kubernetes_dashboard_service is failed diff --git a/tasks/node-setup.yml b/tasks/node-setup.yml new file mode 100644 index 0000000..7a67963 --- /dev/null +++ b/tasks/node-setup.yml @@ -0,0 +1,5 @@ +--- +- name: Join node to Kubernetes master + shell: > + {{ kubernetes_join_command.stdout }} + creates=/etc/kubernetes/kubelet.conf