├── .gitignore ├── site.yml ├── roles ├── common │ ├── files │ │ └── 90-kubeadm.conf │ ├── handlers │ │ └── main.yml │ └── tasks │ │ └── main.yml ├── node │ └── tasks │ │ └── main.yml └── master │ └── tasks │ └── main.yml ├── hosts.example ├── common.yml ├── node.yml ├── master.yml ├── reset.yml ├── group_vars └── all.example └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.retry 2 | /hosts 3 | /group_vars/all 4 | -------------------------------------------------------------------------------- /site.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - include: common.yml 3 | - include: master.yml 4 | - include: node.yml -------------------------------------------------------------------------------- /roles/common/files/90-kubeadm.conf: -------------------------------------------------------------------------------- 1 | net.bridge.bridge-nf-call-iptables = 1 2 | net.bridge.bridge-nf-call-ip6tables = 1 -------------------------------------------------------------------------------- /hosts.example: -------------------------------------------------------------------------------- 1 | # Only one master is allowed 2 | [master] 3 | master.example.com 4 | 5 | [node] 6 | node[1:2].example.com -------------------------------------------------------------------------------- /common.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | remote_user: centos 4 | become: yes 5 | become_method: sudo 6 | roles: 7 | - common -------------------------------------------------------------------------------- /node.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: node 3 | remote_user: centos 4 | become: yes 5 | become_method: sudo 6 | roles: 7 | - node -------------------------------------------------------------------------------- /master.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: master 3 | remote_user: centos 4 | become: yes 5 | become_method: sudo 6 | roles: 7 | - master -------------------------------------------------------------------------------- /reset.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: all 3 | remote_user: centos 4 | become: yes 5 | become_method: sudo 6 | tasks: 7 | - name: Reset cluster 8 | command: /usr/bin/kubeadm reset -------------------------------------------------------------------------------- /roles/common/handlers/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Restart docker 3 | systemd: name=docker state=restarted 4 | 5 | - name: Reload systemd 6 | command: systemctl daemon-reload 7 | 8 | - name: Restart kubelet 9 | systemd: name=kubelet state=restarted -------------------------------------------------------------------------------- /roles/node/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - set_fact: kubeadm_token={{ hostvars[groups['master'][0]]['kubeadm_token'] }} 3 | when: kubeadm_token is not defined 4 | 5 | - name: Join cluster 6 | command: /usr/bin/kubeadm join {{ groups['master'][0] }}:6443 --token {{ kubeadm_token }} -------------------------------------------------------------------------------- /group_vars/all.example: -------------------------------------------------------------------------------- 1 | # global variables 2 | 3 | # https://kubernetes.io/docs/admin/addons/ 4 | kubeadm_network_addon_url: http://docs.projectcalico.org/v2.1/getting-started/kubernetes/installation/hosted/kubeadm/1.6/calico.yaml 5 | 6 | # kubeadm_docker_insecure_registry: registry.example.com:5000 7 | 8 | # Static token (generated on the fly if not set) 9 | # kubeadm_token: 0aab9a.be48b5a694f0c250 -------------------------------------------------------------------------------- /roles/master/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # TODO automatically detect this with "kubeadm version" 3 | - name: Pull images 4 | command: /usr/bin/docker pull {{ item }} 5 | with_items: 6 | - "gcr.io/google_containers/kube-proxy-amd64:v1.6.0" 7 | - "gcr.io/google_containers/kube-controller-manager-amd64:v1.6.0" 8 | - "gcr.io/google_containers/kube-apiserver-amd64:v1.6.0" 9 | - "gcr.io/google_containers/kube-scheduler-amd64:v1.6.0" 10 | 11 | - name: Generate cluster token 12 | command: /usr/bin/kubeadm token generate 13 | register: kubeadm_token_generate 14 | when: kubeadm_token is not defined 15 | 16 | - set_fact: kubeadm_token={{ kubeadm_token_generate.stdout }} 17 | when: kubeadm_token is not defined 18 | 19 | - name: Initialize cluster 20 | command: /usr/bin/kubeadm init --token {{ kubeadm_token }} 21 | 22 | - name: Create cluster network 23 | command: /usr/bin/kubectl apply -f {{ kubeadm_network_addon_url }} 24 | environment: 25 | KUBECONFIG: /etc/kubernetes/admin.conf 26 | 27 | - name: Wait 1 minute for images pulls and cluster services to start 28 | pause: minutes=1 -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kubeadm Ansible Playbook for Centos 7 2 | 3 | This is a simple playbook to wrap the following operations: 4 | 5 | * Install the kubeadm repo 6 | * Install docker, kubeadm, kubelet, kubernetes-cni, and kubectl 7 | * Disable SELinux :disappointed: 8 | * Set docker `--logging-driver=json-file` 9 | * Set docker `--storage-driver=overlay` 10 | * Set kubelet `--cgroup-driver=systemd` 11 | * Optional: Configure an insecure registry for docker 12 | * Initialize the cluster on master with `kubeadm init` 13 | * Install user specified pod network from `group_vars/all` 14 | * Join the nodes to the cluster with 'kubeadm join` 15 | 16 | This has been tested with **CentOS 7.3** and **Kubernetes v1.6.1** 17 | 18 | At the end of the playbook, either copy `/etc/kubernetes/admin.conf` to `$HOME/config` or `export KUBECONFIG=/etc/kubernetes/admin.conf` and `kubectl` will operate on the new cluster. 19 | 20 | # How To 21 | 22 | ``` 23 | git clone https://github.com/sjenning/kubeadm-playbook.git 24 | cd kubeadm-playbook/ 25 | cp hosts.example hosts 26 | vi hosts 27 | group_vars 28 | cp group_vars/all.example group_vars/all 29 | vi group_vars/all 30 | ansible-playbook -i hosts site.yaml 31 | ``` -------------------------------------------------------------------------------- /roles/common/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Create kubernetes yum repository 3 | yum_repository: 4 | name: kubernetes 5 | description: Kubernetes 6 | baseurl: http://yum.kubernetes.io/repos/kubernetes-el7-x86_64 7 | gpgcheck: 0 8 | 9 | - name: Disable selinux 10 | selinux: policy=targeted state=permissive 11 | 12 | - name: Clean yum metadata 13 | command: yum clean all 14 | args: 15 | warn: no 16 | 17 | - name: Install packages 18 | yum: name={{ item }} state=present 19 | with_items: 20 | - docker 21 | - kubelet 22 | - kubeadm 23 | - kubectl 24 | - kubernetes-cni 25 | 26 | - name: Use json-file docker logging driver 27 | lineinfile: 28 | dest: /etc/sysconfig/docker 29 | regexp: '^OPTIONS=' 30 | line: "OPTIONS='--selinux-enabled --log-driver=json-file --signature-verification=false'" 31 | notify: 32 | - Restart docker 33 | 34 | - name: Allow insecure registry 35 | lineinfile: 36 | dest: /etc/sysconfig/docker 37 | regexp: '^# INSECURE_REGISTRY=' 38 | line: "INSECURE_REGISTRY='--insecure-registry {{ kubeadm_docker_insecure_registry }}'" 39 | when: 40 | kubeadm_docker_insecure_registry is defined 41 | notify: 42 | - Restart docker 43 | 44 | - name: Use overlay docker storage driver 45 | lineinfile: 46 | dest: /etc/sysconfig/docker-storage 47 | regexp: '^DOCKER_STORAGE_OPTIONS=' 48 | line: 'DOCKER_STORAGE_OPTIONS="--storage-driver=overlay"' 49 | notify: 50 | - Restart docker 51 | 52 | - name: Remove existing kubelet args from drop-in unit 53 | lineinfile: 54 | dest: /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 55 | regexp: '^Environment="KUBELET_EXTRA_ARGS' 56 | state: absent 57 | 58 | - name: Use systemd kubelet cgroup driver 59 | lineinfile: 60 | dest: /etc/systemd/system/kubelet.service.d/10-kubeadm.conf 61 | insertafter: '^Environment=\"KUBELET_AUTHZ_ARGS' 62 | line: 'Environment="KUBELET_EXTRA_ARGS=--cgroup-driver=systemd"' 63 | notify: 64 | - Reload systemd 65 | - Restart kubelet 66 | 67 | - name: Create kubeadm sysctl file 68 | copy: src=90-kubeadm.conf dest=/etc/sysctl.d/90-kubeadm.conf 69 | 70 | - name: Set sysctl settings 71 | command: sysctl --system 72 | 73 | - name: Reset any existing cluster 74 | command: /usr/bin/kubeadm reset 75 | 76 | - name: Enable and start docker 77 | systemd: state=started enabled=yes name=docker 78 | 79 | - name: Enable and start kubelet 80 | systemd: state=started enabled=yes name=kubelet 81 | 82 | --------------------------------------------------------------------------------