mirror of
https://github.com/kubernetes-sigs/kubespray.git
synced 2026-06-03 18:17:57 +00:00
Compare commits
234 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| af8f394714 | |||
| eab2cec0ad | |||
| 0b17a4c00f | |||
| f49aa90bf7 | |||
| 6f9148e994 | |||
| 7c8e9dbe00 | |||
| df3d0bcc21 | |||
| 7913d62749 | |||
| d5320961e9 | |||
| 9c461e1018 | |||
| 9a03249446 | |||
| 4e015dd3f1 | |||
| 6f53269ce3 | |||
| e356b2de4f | |||
| 8fa0110e28 | |||
| 2a08f7bc0a | |||
| 99d16913d3 | |||
| d172457504 | |||
| 6103d673b7 | |||
| 29bf90a858 | |||
| 2c35e4c055 | |||
| e3cdb3574a | |||
| 15cd1bfc56 | |||
| 392570f4ff | |||
| be5fe9af54 | |||
| 7006d56ab8 | |||
| 1695682d85 | |||
| 1d1d8b9c28 | |||
| 98fe2c02b2 | |||
| 92c2a9457e | |||
| a11e0cb3d1 | |||
| dbb6f4934e | |||
| 9f07f2a951 | |||
| 005ddedb94 | |||
| b72e220126 | |||
| e0f460d9b5 | |||
| 2bd6b83656 | |||
| 2df70d6a3d | |||
| ddaeb2b8fa | |||
| 6f4f170a88 | |||
| 3f3b03bc99 | |||
| c9d9ccf025 | |||
| e378f4fb14 | |||
| 5c15d14f12 | |||
| b45747ec86 | |||
| d597f707f1 | |||
| 4388cab8d6 | |||
| 595e93e6da | |||
| 5f4e01cec5 | |||
| 7c9c609ac4 | |||
| 680864f95c | |||
| 7315d33e3c | |||
| b2afbfd4fb | |||
| ab694ee291 | |||
| bba3525cd8 | |||
| 2c816f66a3 | |||
| d585ceaf3b | |||
| fec1dc9041 | |||
| e7e03bae9f | |||
| b81a064242 | |||
| 03d402e226 | |||
| 0a238d9853 | |||
| 4fe0ced5db | |||
| c6d65cb535 | |||
| a0746a3efd | |||
| 46807c655d | |||
| 970aab70e1 | |||
| 4561dd327b | |||
| 94c0c32752 | |||
| b155e8cc7b | |||
| 9046b7b1bf | |||
| 3c450191ea | |||
| 184bb8c94d | |||
| a003d91576 | |||
| 9914229484 | |||
| b3841659d7 | |||
| 3a349b8519 | |||
| 6e91b6f47c | |||
| bf5c531037 | |||
| 44ac355aa7 | |||
| 958c770bef | |||
| 6012230110 | |||
| 61bb6468ef | |||
| f2069b296c | |||
| 9649f2779d | |||
| c91a3183d3 | |||
| 693230ace9 | |||
| f21f660cc5 | |||
| 43afd42f59 | |||
| 4d1828c724 | |||
| 953f482585 | |||
| 4055980ce6 | |||
| e2984b4fdb | |||
| 394a64f904 | |||
| 2fc8b46996 | |||
| 5efc09710b | |||
| f908309739 | |||
| 9862afb097 | |||
| 59994a6df1 | |||
| 0a1b92f348 | |||
| af9b945874 | |||
| 3cbcd6f189 | |||
| 1568cbe8e9 | |||
| eb4dd5f19d | |||
| fd0e5e756e | |||
| f49620517e | |||
| ef8a46b8c5 | |||
| 47c211f9c1 | |||
| b23b8aa3de | |||
| 3981b73924 | |||
| e0ec3e7241 | |||
| b66cc67b6f | |||
| 83c1105192 | |||
| d9a8de487f | |||
| d1e19563b0 | |||
| 3014dfef24 | |||
| b92fa01e05 | |||
| e3ebc8e009 | |||
| 625efc85af | |||
| d30474d305 | |||
| 9cecc30b6d | |||
| 563be70728 | |||
| a03f3739dc | |||
| bfe78848fa | |||
| 126d4e36c8 | |||
| 97c4edc028 | |||
| f74c195d47 | |||
| 2374878ef7 | |||
| b9e56dd435 | |||
| ede5f9592a | |||
| a6137b3aee | |||
| da3920496d | |||
| 895a02e274 | |||
| b4b20c9dbc | |||
| fe8eff07d3 | |||
| 941cae2a4c | |||
| 4a9a82ca86 | |||
| d2ac5ac54b | |||
| 4c2f757fe8 | |||
| e701c3d49d | |||
| 5762d8f301 | |||
| 9a278bae00 | |||
| d3f35e12a2 | |||
| d7b7db34fa | |||
| 4dd85b5078 | |||
| 7f73bb5522 | |||
| 795ce8468d | |||
| fb6dd60f52 | |||
| e427591545 | |||
| 9b8c89ebb0 | |||
| 323155b0e1 | |||
| f368faf66b | |||
| 8fa7811b63 | |||
| c352df6fc8 | |||
| 34419d6bae | |||
| d94bc8e599 | |||
| 57e1831f78 | |||
| 1a0208f448 | |||
| 5319f23e73 | |||
| b45261b763 | |||
| 10ade2cbdc | |||
| 471dad44b6 | |||
| 3f411bffe4 | |||
| 5cc29b77aa | |||
| 70aa68b9c7 | |||
| 7efaf30d36 | |||
| 0b164bec02 | |||
| 3f8f0f550b | |||
| d6a790ec46 | |||
| 8eef0db3ec | |||
| 2b3543d0ee | |||
| c997860e1c | |||
| 27b0980622 | |||
| 3fb9101e40 | |||
| 3bf74530ce | |||
| f6e4cc530c | |||
| e85fb0460e | |||
| f0eb963f5e | |||
| f216302f95 | |||
| b98227e9a4 | |||
| f27a3f047f | |||
| 8e585cfdfe | |||
| 0af0a3517f | |||
| 73e240c644 | |||
| 533fe3b8e6 | |||
| 95403e9d93 | |||
| 250ed9d56b | |||
| 6381e75769 | |||
| 71e4b185c5 | |||
| a3c5be2c9d | |||
| 78e67aea8f | |||
| 3427119577 | |||
| 73084a8377 | |||
| 058ccea9bc | |||
| 5d61661850 | |||
| 42613eac91 | |||
| af5e35e938 | |||
| f1647d621e | |||
| fb13b42db9 | |||
| 72096c8b1b | |||
| bc507dfb82 | |||
| fec609053c | |||
| 6183a4d3b1 | |||
| 481d16d5ad | |||
| 347bc4a79c | |||
| 6646cd5cef | |||
| 9c1f722f8d | |||
| c105e20ac9 | |||
| 744b0be2ac | |||
| 4281506322 | |||
| f9395f7259 | |||
| 5fbfee593d | |||
| 9c1543c3db | |||
| a5849938d4 | |||
| ca977d7681 | |||
| c811a0b193 | |||
| 7841d4d3c9 | |||
| 4a9a682a24 | |||
| e46adbca8a | |||
| b35288e6b5 | |||
| 6b798d87d1 | |||
| 4ee8bd2e0f | |||
| fa60d0e67b | |||
| 6b6a5ceeae | |||
| 67be137e01 | |||
| 5ba39f5176 | |||
| c26d2e17cd | |||
| 488da0749d | |||
| 606267b7df | |||
| a37273b422 | |||
| e74ad80fe4 | |||
| 89a25fa3fa | |||
| 00c562828f | |||
| 4aa588e481 |
@@ -1 +0,0 @@
|
||||
ssh
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
[submodule "roles/apps/k8s-kube-ui"]
|
||||
path = roles/apps/k8s-kube-ui
|
||||
url = https://github.com/ansibl8s/k8s-kube-ui.git
|
||||
branch = v1.0
|
||||
[submodule "roles/apps/k8s-kubedns"]
|
||||
path = roles/apps/k8s-kubedns
|
||||
url = https://github.com/ansibl8s/k8s-kubedns.git
|
||||
branch = v1.0
|
||||
[submodule "roles/apps/k8s-common"]
|
||||
path = roles/apps/k8s-common
|
||||
url = https://github.com/ansibl8s/k8s-common.git
|
||||
branch = v1.0
|
||||
[submodule "roles/apps/k8s-redis"]
|
||||
path = roles/apps/k8s-redis
|
||||
url = https://github.com/ansibl8s/k8s-redis.git
|
||||
branch = v1.0
|
||||
[submodule "roles/apps/k8s-elasticsearch"]
|
||||
path = roles/apps/k8s-elasticsearch
|
||||
url = https://github.com/ansibl8s/k8s-elasticsearch.git
|
||||
[submodule "roles/apps/k8s-fabric8"]
|
||||
path = roles/apps/k8s-fabric8
|
||||
url = https://github.com/ansibl8s/k8s-fabric8.git
|
||||
branch = v1.0
|
||||
[submodule "roles/apps/k8s-memcached"]
|
||||
path = roles/apps/k8s-memcached
|
||||
url = https://github.com/ansibl8s/k8s-memcached.git
|
||||
branch = v1.0
|
||||
[submodule "roles/apps/k8s-postgres"]
|
||||
path = roles/apps/k8s-postgres
|
||||
url = https://github.com/ansibl8s/k8s-postgres.git
|
||||
branch = v1.0
|
||||
[submodule "roles/apps/k8s-kubedash"]
|
||||
path = roles/apps/k8s-kubedash
|
||||
url = https://github.com/ansibl8s/k8s-kubedash.git
|
||||
[submodule "roles/apps/k8s-heapster"]
|
||||
path = roles/apps/k8s-heapster
|
||||
url = https://github.com/ansibl8s/k8s-heapster.git
|
||||
[submodule "roles/apps/k8s-influxdb"]
|
||||
path = roles/apps/k8s-influxdb
|
||||
url = https://github.com/ansibl8s/k8s-influxdb.git
|
||||
[submodule "roles/apps/k8s-kube-logstash"]
|
||||
path = roles/apps/k8s-kube-logstash
|
||||
url = https://github.com/ansibl8s/k8s-kube-logstash.git
|
||||
[submodule "roles/apps/k8s-etcd"]
|
||||
path = roles/apps/k8s-etcd
|
||||
url = https://github.com/ansibl8s/k8s-etcd.git
|
||||
[submodule "roles/apps/k8s-rabbitmq"]
|
||||
path = roles/apps/k8s-rabbitmq
|
||||
url = https://github.com/ansibl8s/k8s-rabbitmq.git
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
sudo: required
|
||||
dist: trusty
|
||||
language: python
|
||||
python: "2.7"
|
||||
|
||||
addons:
|
||||
hosts:
|
||||
- node1
|
||||
|
||||
env:
|
||||
- SITE=cluster.yml
|
||||
|
||||
before_install:
|
||||
- sudo apt-get update -qq
|
||||
|
||||
install:
|
||||
# Install Ansible.
|
||||
- sudo -H pip install ansible
|
||||
- sudo -H pip install netaddr
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/releases
|
||||
- $HOME/.cache/pip
|
||||
|
||||
before_script:
|
||||
- export PATH=$PATH:/usr/local/bin
|
||||
|
||||
script:
|
||||
# Check the role/playbook's syntax.
|
||||
- "sudo -H ansible-playbook -i inventory/local-tests.cfg $SITE --syntax-check"
|
||||
|
||||
# Run the role/playbook with ansible-playbook.
|
||||
- "sudo -H ansible-playbook -i inventory/local-tests.cfg $SITE --connection=local"
|
||||
|
||||
# Run the role/playbook again, checking to make sure it's idempotent.
|
||||
- >
|
||||
sudo -H ansible-playbook -i inventory/local-tests.cfg $SITE --connection=local
|
||||
| tee /dev/stderr | grep -q 'changed=0.*failed=0'
|
||||
&& (echo 'Idempotence test: pass' && exit 0)
|
||||
|| (echo 'Idempotence test: fail' && exit 1)
|
||||
@@ -1,33 +1,279 @@
|
||||
vagrant-k8s
|
||||
===========
|
||||
Scripts to create libvirt lab with vagrant and prepare some stuff for `k8s` deployment with `kargo`.
|
||||
[](https://travis-ci.org/ansibl8s/setup-kubernetes)
|
||||
kubernetes-ansible
|
||||
========
|
||||
|
||||
Install and configure a Multi-Master/HA kubernetes cluster including network plugin.
|
||||
|
||||
Requirements
|
||||
============
|
||||
### Requirements
|
||||
Tested on **Debian Wheezy/Jessie** and **Ubuntu** (14.10, 15.04, 15.10).
|
||||
Should work on **RedHat/Fedora/Centos** platforms (to be tested)
|
||||
* The target servers must have access to the Internet in order to pull docker imaqes.
|
||||
* The firewalls are not managed, you'll need to implement your own rules the way you used to.
|
||||
* Ansible v1.9.x and python-netaddr
|
||||
|
||||
* `libvirt`
|
||||
* `vagrant`
|
||||
* `vagrant-libvirt` plugin
|
||||
* `$USER` should be able to connect to libvirt (test with `virsh list --all`)
|
||||
### Components
|
||||
* [kubernetes](https://github.com/kubernetes/kubernetes/releases) v1.1.3
|
||||
* [etcd](https://github.com/coreos/etcd/releases) v2.2.2
|
||||
* [calicoctl](https://github.com/projectcalico/calico-docker/releases) v0.13.0
|
||||
* [flanneld](https://github.com/coreos/flannel/releases) v0.5.5
|
||||
* [docker](https://www.docker.com/) v1.9.1
|
||||
|
||||
How-to
|
||||
======
|
||||
Quickstart
|
||||
-------------------------
|
||||
The following steps will quickly setup a kubernetes cluster with default configuration.
|
||||
These defaults are good for tests purposes.
|
||||
|
||||
* Prepare the virtual lab:
|
||||
Edit the inventory according to the number of servers
|
||||
```
|
||||
[downloader]
|
||||
localhost ansible_connection=local ansible_python_interpreter=python2
|
||||
|
||||
```bash
|
||||
export VAGRANT_POOL="10.100.0.0/16"
|
||||
git clone https://github.com/adidenko/vagrant-k8s
|
||||
cd vagrant-k8s
|
||||
vagrant up
|
||||
[kube-master]
|
||||
10.115.99.31
|
||||
|
||||
[etcd]
|
||||
10.115.99.31
|
||||
10.115.99.32
|
||||
10.115.99.33
|
||||
|
||||
[kube-node]
|
||||
10.115.99.32
|
||||
10.115.99.33
|
||||
|
||||
[k8s-cluster:children]
|
||||
kube-node
|
||||
kube-master
|
||||
```
|
||||
|
||||
* Login to master node and deploy k8s with kargo:
|
||||
|
||||
```bash
|
||||
vagrant ssh $USER-k8s-01
|
||||
# Inside your master VM run this:
|
||||
sudo su -
|
||||
./deploy-k8s.kargo.sh
|
||||
Run the playbook
|
||||
```
|
||||
ansible-playbook -i inventory/inventory.cfg cluster.yml -u root
|
||||
```
|
||||
|
||||
You can jump directly to "*Available apps, installation procedure*"
|
||||
|
||||
|
||||
Ansible
|
||||
-------------------------
|
||||
### Variables
|
||||
The main variables to change are located in the directory ```inventory/group_vars/all.yml```.
|
||||
|
||||
### Inventory
|
||||
Below is an example of an inventory.
|
||||
Note : The bgp vars local_as and peers are not mandatory if the var **'peer_with_router'** is set to false
|
||||
By default this variable is set to false and therefore all the nodes are configure in **'node-mesh'** mode.
|
||||
In node-mesh mode the nodes peers with all the nodes in order to exchange routes.
|
||||
|
||||
```
|
||||
|
||||
[downloader]
|
||||
localhost ansible_connection=local ansible_python_interpreter=python2
|
||||
|
||||
[kube-master]
|
||||
node1 ansible_ssh_host=10.99.0.26
|
||||
node2 ansible_ssh_host=10.99.0.27
|
||||
|
||||
[etcd]
|
||||
node1 ansible_ssh_host=10.99.0.26
|
||||
node2 ansible_ssh_host=10.99.0.27
|
||||
node3 ansible_ssh_host=10.99.0.4
|
||||
|
||||
[kube-node]
|
||||
node2 ansible_ssh_host=10.99.0.27
|
||||
node3 ansible_ssh_host=10.99.0.4
|
||||
node4 ansible_ssh_host=10.99.0.5
|
||||
node5 ansible_ssh_host=10.99.0.36
|
||||
node6 ansible_ssh_host=10.99.0.37
|
||||
|
||||
[paris]
|
||||
node1 ansible_ssh_host=10.99.0.26
|
||||
node3 ansible_ssh_host=10.99.0.4 local_as=xxxxxxxx
|
||||
node4 ansible_ssh_host=10.99.0.5 local_as=xxxxxxxx
|
||||
|
||||
[new-york]
|
||||
node2 ansible_ssh_host=10.99.0.27
|
||||
node5 ansible_ssh_host=10.99.0.36 local_as=xxxxxxxx
|
||||
node6 ansible_ssh_host=10.99.0.37 local_as=xxxxxxxx
|
||||
|
||||
[k8s-cluster:children]
|
||||
kube-node
|
||||
kube-master
|
||||
```
|
||||
|
||||
### Playbook
|
||||
```
|
||||
---
|
||||
- hosts: downloader
|
||||
sudo: no
|
||||
roles:
|
||||
- { role: download, tags: download }
|
||||
|
||||
- hosts: k8s-cluster
|
||||
roles:
|
||||
- { role: kubernetes/preinstall, tags: preinstall }
|
||||
- { role: docker, tags: docker }
|
||||
- { role: kubernetes/node, tags: node }
|
||||
- { role: etcd, tags: etcd }
|
||||
- { role: dnsmasq, tags: dnsmasq }
|
||||
- { role: network_plugin, tags: ['calico', 'flannel', 'network'] }
|
||||
|
||||
- hosts: kube-master
|
||||
roles:
|
||||
- { role: kubernetes/master, tags: master }
|
||||
|
||||
```
|
||||
|
||||
### Run
|
||||
It is possible to define variables for different environments.
|
||||
For instance, in order to deploy the cluster on 'dev' environment run the following command.
|
||||
```
|
||||
ansible-playbook -i inventory/dev/inventory.cfg cluster.yml -u root
|
||||
```
|
||||
|
||||
Kubernetes
|
||||
-------------------------
|
||||
### Multi master notes
|
||||
* You can choose where to install the master components. If you want your master node to act both as master (api,scheduler,controller) and node (e.g. accept workloads, create pods ...),
|
||||
the server address has to be present on both groups 'kube-master' and 'kube-node'.
|
||||
|
||||
* Almost all kubernetes components are running into pods except *kubelet*. These pods are managed by kubelet which ensure they're always running
|
||||
|
||||
* For safety reasons, you should have at least two master nodes and 3 etcd servers
|
||||
|
||||
* Kube-proxy doesn't support multiple apiservers on startup ([Issue 18174](https://github.com/kubernetes/kubernetes/issues/18174)). An external loadbalancer needs to be configured.
|
||||
In order to do so, some variables have to be used '**loadbalancer_apiserver**' and '**apiserver_loadbalancer_domain_name**'
|
||||
|
||||
|
||||
### Network Overlay
|
||||
You can choose between 2 network plugins. Only one must be chosen.
|
||||
|
||||
* **flannel**: gre/vxlan (layer 2) networking. ([official docs](https://github.com/coreos/flannel))
|
||||
|
||||
* **calico**: bgp (layer 3) networking. ([official docs](http://docs.projectcalico.org/en/0.13/))
|
||||
|
||||
The choice is defined with the variable '**kube_network_plugin**'
|
||||
|
||||
### Expose a service
|
||||
There are several loadbalancing solutions.
|
||||
The one i found suitable for kubernetes are [Vulcand](http://vulcand.io/) and [Haproxy](http://www.haproxy.org/)
|
||||
|
||||
My cluster is working with haproxy and kubernetes services are configured with the loadbalancing type '**nodePort**'.
|
||||
eg: each node opens the same tcp port and forwards the traffic to the target pod wherever it is located.
|
||||
|
||||
Then Haproxy can be configured to request kubernetes's api in order to loadbalance on the proper tcp port on the nodes.
|
||||
|
||||
Please refer to the proper kubernetes documentation on [Services](https://github.com/kubernetes/kubernetes/blob/release-1.0/docs/user-guide/services.md)
|
||||
|
||||
### Check cluster status
|
||||
|
||||
#### Kubernetes components
|
||||
|
||||
* Check the status of the processes
|
||||
```
|
||||
systemctl status kubelet
|
||||
```
|
||||
|
||||
* Check the logs
|
||||
```
|
||||
journalctl -ae -u kubelet
|
||||
```
|
||||
|
||||
* Check the NAT rules
|
||||
```
|
||||
iptables -nLv -t nat
|
||||
```
|
||||
|
||||
For the master nodes you'll have to see the docker logs for the apiserver
|
||||
```
|
||||
docker logs [apiserver docker id]
|
||||
```
|
||||
|
||||
|
||||
### Available apps, installation procedure
|
||||
|
||||
There are two ways of installing new apps
|
||||
|
||||
#### Ansible galaxy
|
||||
|
||||
Additionnal apps can be installed with ```ansible-galaxy```.
|
||||
|
||||
ou'll need to edit the file '*requirements.yml*' in order to chose needed apps.
|
||||
The list of available apps are available [there](https://github.com/ansibl8s)
|
||||
|
||||
For instance it is **strongly recommanded** to install a dns server which resolves kubernetes service names.
|
||||
In order to use this role you'll need the following entries in the file '*requirements.yml*'
|
||||
Please refer to the [k8s-kubedns readme](https://github.com/ansibl8s/k8s-kubedns) for additionnal info.
|
||||
```
|
||||
- src: https://github.com/ansibl8s/k8s-common.git
|
||||
path: roles/apps
|
||||
# version: v1.0
|
||||
|
||||
- src: https://github.com/ansibl8s/k8s-kubedns.git
|
||||
path: roles/apps
|
||||
# version: v1.0
|
||||
```
|
||||
**Note**: the role common is required by all the apps and provides the tasks and libraries needed.
|
||||
|
||||
And empty the apps directory
|
||||
```
|
||||
rm -rf roles/apps/*
|
||||
```
|
||||
|
||||
Then download the roles with ansible-galaxy
|
||||
```
|
||||
ansible-galaxy install -r requirements.yml
|
||||
```
|
||||
|
||||
#### Git submodules
|
||||
Alternatively the roles can be installed as git submodules.
|
||||
That way is easier if you want to do some changes and commit them.
|
||||
|
||||
You can list available submodules with the following command:
|
||||
```
|
||||
grep path .gitmodules | sed 's/.*= //'
|
||||
```
|
||||
|
||||
In order to install the dns addon you'll need to follow these steps
|
||||
```
|
||||
git submodule init roles/apps/k8s-common roles/apps/k8s-kubedns
|
||||
git submodule update
|
||||
```
|
||||
|
||||
Finally update the playbook ```apps.yml``` with the chosen roles, and run it
|
||||
```
|
||||
...
|
||||
- hosts: kube-master
|
||||
roles:
|
||||
- { role: apps/k8s-kubedns, tags: ['kubedns', 'apps'] }
|
||||
...
|
||||
```
|
||||
|
||||
```
|
||||
ansible-playbook -i inventory/inventory.cfg apps.yml -u root
|
||||
```
|
||||
|
||||
|
||||
#### Calico networking
|
||||
Check if the calico-node container is running
|
||||
```
|
||||
docker ps | grep calico
|
||||
```
|
||||
|
||||
The **calicoctl** command allows to check the status of the network workloads.
|
||||
* Check the status of Calico nodes
|
||||
```
|
||||
calicoctl status
|
||||
```
|
||||
|
||||
* Show the configured network subnet for containers
|
||||
```
|
||||
calicoctl pool show
|
||||
```
|
||||
|
||||
* Show the workloads (ip addresses of containers and their located)
|
||||
```
|
||||
calicoctl endpoint show --detail
|
||||
```
|
||||
#### Flannel networking
|
||||
|
||||
Congrats ! now you can walk through [kubernetes basics](http://kubernetes.io/v1.1/basicstutorials.html)
|
||||
|
||||
Vendored
-88
@@ -1,88 +0,0 @@
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
ENV["VAGRANT_DEFAULT_PROVIDER"] = "libvirt"
|
||||
pool = ENV["VAGRANT_POOL"] || "10.210.0.0/16"
|
||||
prefix = pool.gsub(/\.\d+\.\d+\/16$/, "")
|
||||
|
||||
$num_instances = 7
|
||||
$vm_memory = 2048
|
||||
$vm_cpus = 2
|
||||
|
||||
$user = ENV["USER"]
|
||||
$public_subnet = prefix.to_s + ".0"
|
||||
$private_subnet = prefix.to_s + ".1"
|
||||
$mgmt_cidr = prefix.to_s + ".2.0/24"
|
||||
|
||||
$instance_name_prefix = "#{$user}-k8s"
|
||||
|
||||
# Boxes with libvirt provider support:
|
||||
#$box = "yk0/ubuntu-xenial" #900M
|
||||
#$box = "centos/7"
|
||||
$box = "nrclark/xenial64-minimal-libvirt"
|
||||
|
||||
# Create SSH keys for future lab
|
||||
system 'bash ssh-keygen.sh'
|
||||
|
||||
# Create nodes list for future kargo deployment
|
||||
nodes=""
|
||||
(2..$num_instances).each do |i|
|
||||
ip = "#{$private_subnet}.#{i+10}"
|
||||
nodes = "#{nodes}#{ip}\n"
|
||||
end
|
||||
File.open("nodes", 'w') { |file| file.write(nodes) }
|
||||
|
||||
# Create the lab
|
||||
Vagrant.configure("2") do |config|
|
||||
(1..$num_instances).each do |i|
|
||||
# First node would be master node
|
||||
if i == 1
|
||||
master = true
|
||||
else
|
||||
master = false
|
||||
end
|
||||
|
||||
config.ssh.insert_key = false
|
||||
vm_name = "%s-%02d" % [$instance_name_prefix, i]
|
||||
|
||||
config.vm.define vm_name do |test_vm|
|
||||
test_vm.vm.box = $box
|
||||
test_vm.vm.hostname = vm_name
|
||||
|
||||
# Libvirt provider settings
|
||||
test_vm.vm.provider :libvirt do |domain|
|
||||
domain.uri = "qemu+unix:///system"
|
||||
domain.memory = $vm_memory
|
||||
domain.cpus = $vm_cpus
|
||||
domain.driver = "kvm"
|
||||
domain.host = "localhost"
|
||||
domain.connect_via_ssh = false
|
||||
domain.username = $user
|
||||
domain.storage_pool_name = "default"
|
||||
domain.nic_model_type = "e1000"
|
||||
domain.management_network_name = "#{$instance_name_prefix}-mgmt-net"
|
||||
domain.management_network_address = $mgmt_cidr
|
||||
domain.nested = true
|
||||
domain.cpu_mode = "host-passthrough"
|
||||
domain.volume_cache = "unsafe"
|
||||
domain.disk_bus = "virtio"
|
||||
end
|
||||
|
||||
ip = "#{$private_subnet}.#{i+10}"
|
||||
test_vm.vm.network :private_network, :ip => "#{ip}"
|
||||
|
||||
# Provisioning
|
||||
config.vm.provision "file", source: "ssh", destination: "~/ssh"
|
||||
if master
|
||||
config.vm.provision "deploy-k8s", type: "file", source: "deploy-k8s.kargo.sh", destination: "~/deploy-k8s.kargo.sh"
|
||||
config.vm.provision "custom.yaml", type: "file", source: "custom.yaml", destination: "~/custom.yaml"
|
||||
config.vm.provision "kubedns.yaml", type: "file", source: "kubedns.yaml", destination: "~/kubedns.yaml"
|
||||
config.vm.provision "nodes", type: "file", source: "nodes", destination: "~/nodes"
|
||||
config.vm.provision "bootstrap", type: "shell", path: "bootstrap-master.sh"
|
||||
else
|
||||
config.vm.provision "bootstrap", type: "shell", path: "bootstrap-node.sh"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
- hosts: kube-master
|
||||
roles:
|
||||
# System
|
||||
- { role: apps/k8s-kubedns, tags: ['kubedns', 'kube-system'] }
|
||||
|
||||
# Databases
|
||||
- { role: apps/k8s-postgres, tags: 'postgres' }
|
||||
- { role: apps/k8s-elasticsearch, tags: 'elasticsearch' }
|
||||
- { role: apps/k8s-memcached, tags: 'memcached' }
|
||||
- { role: apps/k8s-redis, tags: 'redis' }
|
||||
|
||||
# Msg Broker
|
||||
- { role: apps/k8s-rabbitmq, tags: 'rabbitmq' }
|
||||
|
||||
# Monitoring
|
||||
- { role: apps/k8s-influxdb, tags: ['influxdb', 'kube-system']}
|
||||
- { role: apps/k8s-heapster, tags: ['heapster', 'kube-system']}
|
||||
- { role: apps/k8s-kubedash, tags: ['kubedash', 'kube-system']}
|
||||
|
||||
# logging
|
||||
- { role: apps/k8s-kube-logstash, tags: 'kube-logstash'}
|
||||
|
||||
# Console
|
||||
- { role: apps/k8s-fabric8, tags: 'fabric8' }
|
||||
- { role: apps/k8s-kube-ui, tags: ['kube-ui', 'kube-system']}
|
||||
|
||||
# ETCD
|
||||
- { role: apps/k8s-etcd, tags: 'etcd'}
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/bin/bash
|
||||
echo master > /var/tmp/role
|
||||
|
||||
# Packages
|
||||
sudo apt-get --yes update
|
||||
sudo apt-get --yes upgrade
|
||||
sudo apt-get --yes install git screen vim telnet tcpdump python-setuptools gcc python-dev python-pip libssl-dev libffi-dev software-properties-common
|
||||
|
||||
# Get ansible-2.1+, vanilla ubuntu-16.04 ansible (2.0.0.2) is broken due to https://github.com/ansible/ansible/issues/13876
|
||||
sudo sh -c 'apt-add-repository -y ppa:ansible/ansible;apt-get update;apt-get install -y ansible'
|
||||
|
||||
# Kargo-cli
|
||||
sudo git clone https://github.com/kubespray/kargo-cli.git /root/kargo-cli
|
||||
sudo sh -c 'cd /root/kargo-cli && python setup.py install'
|
||||
|
||||
# k8s deploy script and configs
|
||||
sudo sh -c 'cp -a ~vagrant/deploy-k8s.kargo.sh /root/ && chmod 755 /root/deploy-k8s.kargo.sh'
|
||||
sudo cp -a ~vagrant/custom.yaml /root/custom.yaml
|
||||
sudo cp -a ~vagrant/kubedns.yaml /root/kubedns.yaml
|
||||
|
||||
# SSH keys and config
|
||||
sudo rm -rf /root/.ssh
|
||||
sudo mv ~vagrant/ssh /root/.ssh
|
||||
sudo echo -e 'Host 10.*\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile=/dev/null' >> /root/.ssh/config
|
||||
sudo chown -R root: /root/.ssh
|
||||
|
||||
# Copy nodes list
|
||||
sudo cp ~vagrant/nodes /root/nodes
|
||||
|
||||
# README
|
||||
sudo echo 'cd /root/kargo ; ansible-playbook -vvv -i inv/inventory.cfg cluster.yml -u root -f 7' > /root/README
|
||||
@@ -1,17 +0,0 @@
|
||||
#!/bin/bash
|
||||
echo node > /var/tmp/role
|
||||
|
||||
# Packages
|
||||
sudo apt-get --yes update
|
||||
sudo apt-get --yes upgrade
|
||||
sudo apt-get --yes install screen vim telnet tcpdump python-pip
|
||||
|
||||
# Pip
|
||||
sudo pip install kpm
|
||||
|
||||
# SSH
|
||||
sudo rm -rf /root/.ssh
|
||||
sudo mv ~vagrant/ssh /root/.ssh
|
||||
sudo rm -f /root/.ssh/id_rsa*
|
||||
sudo chown -R root: /root/.ssh
|
||||
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
---
|
||||
- hosts: downloader
|
||||
sudo: no
|
||||
roles:
|
||||
- { role: download, tags: download }
|
||||
|
||||
- hosts: k8s-cluster
|
||||
roles:
|
||||
- { role: kubernetes/preinstall, tags: preinstall }
|
||||
- { role: docker, tags: docker }
|
||||
- { role: kubernetes/node, tags: node }
|
||||
- { role: etcd, tags: etcd }
|
||||
- { role: dnsmasq, tags: dnsmasq }
|
||||
- { role: network_plugin, tags: ['calico', 'flannel', 'network'] }
|
||||
|
||||
- hosts: kube-master
|
||||
roles:
|
||||
- { role: kubernetes/master, tags: master }
|
||||
@@ -1,3 +0,0 @@
|
||||
kube_network_plugin: "calico"
|
||||
kube_proxy_mode: "iptables"
|
||||
local_release_dir: "/var/tmp/releases"
|
||||
@@ -1,26 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
INVENTORY="kargo/inventory/inventory.cfg"
|
||||
|
||||
nodes=""
|
||||
i=1
|
||||
for nodeip in `cat /root/nodes` ; do
|
||||
i=$(( $i+1 ))
|
||||
nodes+=" node${i}[ansible_ssh_host=${nodeip},ip=${nodeip}]"
|
||||
done
|
||||
|
||||
if [ -f "$INVENTORY" ] ; then
|
||||
echo "$INVENTORY already exists, if you want to recreate, pls remove it and re-run this script"
|
||||
else
|
||||
echo "Preparing inventory..."
|
||||
kargo prepare -y --nodes $nodes
|
||||
fi
|
||||
|
||||
echo "Running deployment..."
|
||||
kargo deploy -y --ansible-opts="-e @custom.yaml"
|
||||
deploy_res=$?
|
||||
|
||||
if [ "$deploy_res" -eq "0" ]; then
|
||||
echo "Setting up kubedns..."
|
||||
ansible-playbook -i $INVENTORY kubedns.yaml
|
||||
fi
|
||||
@@ -0,0 +1,86 @@
|
||||
# Directory where the binaries will be installed
|
||||
bin_dir: /usr/local/bin
|
||||
|
||||
# Where the binaries will be downloaded.
|
||||
# Note: ensure that you've enough disk space (about 1G)
|
||||
local_release_dir: "/tmp/releases"
|
||||
|
||||
# Cluster Loglevel configuration
|
||||
kube_log_level: 2
|
||||
|
||||
# Users to create for basic auth in Kubernetes API via HTTP
|
||||
kube_users:
|
||||
kube:
|
||||
pass: changeme
|
||||
role: admin
|
||||
# root:
|
||||
# pass: changeme
|
||||
# role: admin
|
||||
|
||||
# Kubernetes cluster name, also will be used as DNS domain
|
||||
cluster_name: cluster.local
|
||||
|
||||
# set this variable to calico if needed. keep it empty if flannel is used
|
||||
kube_network_plugin: calico
|
||||
|
||||
# Kubernetes internal network for services, unused block of space.
|
||||
kube_service_addresses: 10.233.0.0/18
|
||||
|
||||
# internal network. When used, it will assign IP
|
||||
# addresses from this range to individual pods.
|
||||
# This network must be unused in your network infrastructure!
|
||||
kube_pods_subnet: 10.233.64.0/18
|
||||
|
||||
# internal network total size (optional). This is the prefix of the
|
||||
# entire network. Must be unused in your environment.
|
||||
# kube_network_prefix: 18
|
||||
|
||||
# internal network node size allocation (optional). This is the size allocated
|
||||
# to each node on your network. With these defaults you should have
|
||||
# room for 4096 nodes with 254 pods per node.
|
||||
kube_network_node_prefix: 24
|
||||
|
||||
# With calico it is possible to distributed routes with border routers of the datacenter.
|
||||
peer_with_router: false
|
||||
# Warning : enabling router peering will disable calico's default behavior ('node mesh').
|
||||
# The subnets of each nodes will be distributed by the datacenter router
|
||||
|
||||
# The port the API Server will be listening on.
|
||||
kube_apiserver_ip: "{{ kube_service_addresses|ipaddr('net')|ipaddr(1)|ipaddr('address') }}"
|
||||
kube_apiserver_port: 443 # (https)
|
||||
kube_apiserver_insecure_port: 8080 # (http)
|
||||
|
||||
# Internal DNS configuration.
|
||||
# Kubernetes can create and mainatain its own DNS server to resolve service names
|
||||
# into appropriate IP addresses. It's highly advisable to run such DNS server,
|
||||
# as it greatly simplifies configuration of your applications - you can use
|
||||
# service names instead of magic environment variables.
|
||||
# You still must manually configure all your containers to use this DNS server,
|
||||
# Kubernetes won't do this for you (yet).
|
||||
|
||||
# Upstream dns servers used by dnsmasq
|
||||
upstream_dns_servers:
|
||||
- 8.8.8.8
|
||||
- 4.4.8.8
|
||||
#
|
||||
# # Use dns server : https://github.com/ansibl8s/k8s-skydns/blob/master/skydns-README.md
|
||||
dns_setup: true
|
||||
dns_domain: "{{ cluster_name }}"
|
||||
#
|
||||
# # Ip address of the kubernetes dns service
|
||||
dns_server: "{{ kube_service_addresses|ipaddr('net')|ipaddr(2)|ipaddr('address') }}"
|
||||
|
||||
# For multi masters architecture:
|
||||
# kube-proxy doesn't support multiple apiservers for the time being so you'll need to configure your own loadbalancer
|
||||
# This domain name will be inserted into the /etc/hosts file of all servers
|
||||
# configuration example with haproxy :
|
||||
# listen kubernetes-apiserver-https
|
||||
# bind 10.99.0.21:8383
|
||||
# option ssl-hello-chk
|
||||
# mode tcp
|
||||
# timeout client 3h
|
||||
# timeout server 3h
|
||||
# server master1 10.99.0.26:443
|
||||
# server master2 10.99.0.27:443
|
||||
# balance roundrobin
|
||||
# apiserver_loadbalancer_domain_name: "lb-apiserver.kubernetes.local"
|
||||
@@ -0,0 +1,10 @@
|
||||
#---
|
||||
#peers:
|
||||
# -router_id: "10.99.0.34"
|
||||
# as: "65xxx"
|
||||
# - router_id: "10.99.0.35"
|
||||
# as: "65xxx"
|
||||
#
|
||||
#loadbalancer_apiserver:
|
||||
# address: "10.99.0.44"
|
||||
# port: "8383"
|
||||
@@ -0,0 +1,10 @@
|
||||
#---
|
||||
#peers:
|
||||
# -router_id: "10.99.0.2"
|
||||
# as: "65xxx"
|
||||
# - router_id: "10.99.0.3"
|
||||
# as: "65xxx"
|
||||
#
|
||||
#loadbalancer_apiserver:
|
||||
# address: "10.99.0.21"
|
||||
# port: "8383"
|
||||
@@ -0,0 +1,32 @@
|
||||
[downloader]
|
||||
localhost ansible_connection=local ansible_python_interpreter=python2
|
||||
|
||||
[kube-master]
|
||||
node1 ansible_ssh_host=10.99.0.26
|
||||
node2 ansible_ssh_host=10.99.0.27
|
||||
|
||||
[etcd]
|
||||
node1 ansible_ssh_host=10.99.0.26
|
||||
node2 ansible_ssh_host=10.99.0.27
|
||||
node3 ansible_ssh_host=10.99.0.4
|
||||
|
||||
[kube-node]
|
||||
node2 ansible_ssh_host=10.99.0.27
|
||||
node3 ansible_ssh_host=10.99.0.4
|
||||
node4 ansible_ssh_host=10.99.0.5
|
||||
node5 ansible_ssh_host=10.99.0.36
|
||||
node6 ansible_ssh_host=10.99.0.37
|
||||
|
||||
[paris]
|
||||
node1 ansible_ssh_host=10.99.0.26
|
||||
node3 ansible_ssh_host=10.99.0.4 local_as=xxxxxxxx
|
||||
node4 ansible_ssh_host=10.99.0.5 local_as=xxxxxxxx
|
||||
|
||||
[new-york]
|
||||
node2 ansible_ssh_host=10.99.0.27
|
||||
node5 ansible_ssh_host=10.99.0.36 local_as=xxxxxxxx
|
||||
node6 ansible_ssh_host=10.99.0.37 local_as=xxxxxxxx
|
||||
|
||||
[k8s-cluster:children]
|
||||
kube-node
|
||||
kube-master
|
||||
@@ -0,0 +1,17 @@
|
||||
node1 ansible_connection=local local_release_dir={{ansible_env.HOME}}/releases
|
||||
|
||||
[downloader]
|
||||
node1
|
||||
|
||||
[kube-master]
|
||||
node1
|
||||
|
||||
[etcd]
|
||||
node1
|
||||
|
||||
[kube-node]
|
||||
node1
|
||||
|
||||
[k8s-cluster:children]
|
||||
kube-node
|
||||
kube-master
|
||||
@@ -1,5 +0,0 @@
|
||||
- hosts: kube-master
|
||||
tasks:
|
||||
- name: setup-kubedns
|
||||
shell: kpm deploy kube-system/kubedns --namespace=kube-system
|
||||
run_once: true
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
- src: https://github.com/ansibl8s/k8s-common.git
|
||||
path: roles/apps
|
||||
version: v1.0
|
||||
|
||||
- src: https://github.com/ansibl8s/k8s-kubedns.git
|
||||
path: roles/apps
|
||||
version: v1.0
|
||||
|
||||
#- src: https://github.com/ansibl8s/k8s-kube-ui.git
|
||||
# path: roles/apps
|
||||
# version: v1.0
|
||||
#
|
||||
#- src: https://github.com/ansibl8s/k8s-fabric8.git
|
||||
# path: roles/apps
|
||||
# version: v1.0
|
||||
#
|
||||
#- src: https://github.com/ansibl8s/k8s-elasticsearch.git
|
||||
# path: roles/apps
|
||||
# # version: v1.0
|
||||
#
|
||||
#- src: https://github.com/ansibl8s/k8s-redis.git
|
||||
# path: roles/apps
|
||||
# # version: v1.0
|
||||
#
|
||||
#- src: https://github.com/ansibl8s/k8s-memcached.git
|
||||
# path: roles/apps
|
||||
# version: v1.0
|
||||
#
|
||||
#- src: https://github.com/ansibl8s/k8s-postgres.git
|
||||
# path: roles/apps
|
||||
# version: v1.0
|
||||
#
|
||||
#- src: https://github.com/ansibl8s/k8s-heapster.git
|
||||
# path: roles/apps
|
||||
#
|
||||
#- src: https://github.com/ansibl8s/k8s-influxdb.git
|
||||
# path: roles/apps
|
||||
#
|
||||
#- src: https://github.com/ansibl8s/k8s-kubedash.git
|
||||
# path: roles/apps
|
||||
Submodule
+1
Submodule roles/apps/k8s-common added at c69c5f881f
Submodule
+1
Submodule roles/apps/k8s-elasticsearch added at 3d74c70a4a
Submodule
+1
Submodule roles/apps/k8s-etcd added at abd61ee91a
Submodule
+1
Submodule roles/apps/k8s-fabric8 added at 82ca8293b0
Submodule
+1
Submodule roles/apps/k8s-heapster added at 44a6519bf8
Submodule
+1
Submodule roles/apps/k8s-influxdb added at 38d54c48e7
Submodule
+1
Submodule roles/apps/k8s-kube-logstash added at 256fa156e4
Submodule
+1
Submodule roles/apps/k8s-kube-ui added at b81a2848d9
Submodule
+1
Submodule roles/apps/k8s-kubedash added at 64385696a9
Submodule
+1
Submodule roles/apps/k8s-kubedns added at b5015aed8f
Submodule
+1
Submodule roles/apps/k8s-memcached added at 563b35f3b6
Submodule
+1
Submodule roles/apps/k8s-postgres added at e219c91391
Submodule
+1
Submodule roles/apps/k8s-rabbitmq added at b91f96bb9c
Submodule
+1
Submodule roles/apps/k8s-redis added at a4e134fef3
@@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
make_resolv_conf() {
|
||||
:
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
---
|
||||
- name: populate inventory into hosts file
|
||||
lineinfile:
|
||||
dest: /etc/hosts
|
||||
regexp: "^{{ hostvars[item].ansible_default_ipv4.address }} {{ item }}$"
|
||||
line: "{{ hostvars[item].ansible_default_ipv4.address }} {{ item }}"
|
||||
state: present
|
||||
backup: yes
|
||||
when: hostvars[item].ansible_default_ipv4.address is defined
|
||||
with_items: groups['all']
|
||||
|
||||
- name: populate kubernetes loadbalancer address into hosts file
|
||||
lineinfile:
|
||||
dest: /etc/hosts
|
||||
regexp: ".*{{ apiserver_loadbalancer_domain_name }}$"
|
||||
line: "{{ loadbalancer_apiserver.address }} lb-apiserver.kubernetes.local"
|
||||
state: present
|
||||
backup: yes
|
||||
when: loadbalancer_apiserver is defined and apiserver_loadbalancer_domain_name is defined
|
||||
|
||||
- name: clean hosts file
|
||||
lineinfile:
|
||||
dest: /etc/hosts
|
||||
regexp: "{{ item }}"
|
||||
state: absent
|
||||
backup: yes
|
||||
with_items:
|
||||
- '^127\.0\.0\.1(\s+){{ inventory_hostname }}.*'
|
||||
- '^::1(\s+){{ inventory_hostname }}.*'
|
||||
|
||||
- name: ensure dnsmasq.d directory exists
|
||||
file:
|
||||
path: /etc/dnsmasq.d
|
||||
state: directory
|
||||
when: inventory_hostname in groups['kube-master']
|
||||
|
||||
- name: configure dnsmasq
|
||||
template:
|
||||
src: 01-kube-dns.conf.j2
|
||||
dest: /etc/dnsmasq.d/01-kube-dns.conf
|
||||
mode: 755
|
||||
backup: yes
|
||||
when: inventory_hostname in groups['kube-master']
|
||||
|
||||
- name: create dnsmasq pod template
|
||||
template: src=dnsmasq-pod.yml dest=/etc/kubernetes/manifests/dnsmasq-pod.manifest
|
||||
when: inventory_hostname in groups['kube-master']
|
||||
|
||||
- name: Check for dnsmasq port
|
||||
wait_for:
|
||||
port: 53
|
||||
delay: 5
|
||||
timeout: 100
|
||||
when: inventory_hostname in groups['kube-master']
|
||||
|
||||
- name: check resolvconf
|
||||
stat: path=/etc/resolvconf/resolv.conf.d/head
|
||||
register: resolvconf
|
||||
|
||||
- name: target resolv.conf file
|
||||
set_fact:
|
||||
resolvconffile: >
|
||||
{%- if resolvconf.stat.exists == True -%}
|
||||
/etc/resolvconf/resolv.conf.d/head
|
||||
{%- else -%}
|
||||
/etc/resolv.conf
|
||||
{%- endif -%}
|
||||
|
||||
- name: Add search resolv.conf
|
||||
lineinfile:
|
||||
line: search {{ [ 'default.svc.' + dns_domain, 'svc.' + dns_domain, dns_domain ] | join(' ') }}
|
||||
dest: "{{resolvconffile}}"
|
||||
state: present
|
||||
insertafter: EOF
|
||||
backup: yes
|
||||
follow: yes
|
||||
|
||||
- name: Add all masters as nameserver
|
||||
lineinfile:
|
||||
line: nameserver {{ hostvars[item]['ansible_default_ipv4']['address'] }}
|
||||
dest: "{{resolvconffile}}"
|
||||
state: present
|
||||
insertafter: EOF
|
||||
backup: yes
|
||||
follow: yes
|
||||
with_items: groups['kube-master']
|
||||
|
||||
- name: disable resolv.conf modification by dhclient
|
||||
copy: src=dhclient_nodnsupdate dest=/etc/dhcp/dhclient-enter-hooks.d/nodnsupdate mode=u+x backup=yes
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
- name: disable resolv.conf modification by dhclient
|
||||
copy: src=dhclient_nodnsupdate dest=/etc/dhcp/dhclient.d/nodnsupdate mode=u+x backup=yes
|
||||
when: ansible_os_family == "RedHat"
|
||||
|
||||
- name: update resolvconf
|
||||
command: resolvconf -u
|
||||
changed_when: False
|
||||
when: resolvconf.stat.exists == True
|
||||
|
||||
- meta: flush_handlers
|
||||
@@ -0,0 +1,19 @@
|
||||
#Listen on all interfaces
|
||||
interface=*
|
||||
|
||||
addn-hosts=/etc/hosts
|
||||
|
||||
bogus-priv
|
||||
|
||||
#Set upstream dns servers
|
||||
{% if upstream_dns_servers is defined %}
|
||||
{% for srv in upstream_dns_servers %}
|
||||
server={{ srv }}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
server=8.8.8.8
|
||||
server=8.8.4.4
|
||||
{% endif %}
|
||||
|
||||
# Forward k8s domain to kube-dns
|
||||
server=/{{ dns_domain }}/{{ dns_server }}
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: dnsmasq
|
||||
namespace: kube-system
|
||||
spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: dnsmasq
|
||||
image: andyshinn/dnsmasq:2.72
|
||||
command:
|
||||
- dnsmasq
|
||||
args:
|
||||
- -k
|
||||
- "-7"
|
||||
- /etc/dnsmasq.d
|
||||
- --local-service
|
||||
securityContext:
|
||||
capabilities:
|
||||
add:
|
||||
- NET_ADMIN
|
||||
imagePullPolicy: Always
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 256M
|
||||
ports:
|
||||
- name: dns
|
||||
containerPort: 53
|
||||
hostPort: 53
|
||||
protocol: UDP
|
||||
- name: dns-tcp
|
||||
containerPort: 53
|
||||
hostPort: 53
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- name: etcdnsmasqd
|
||||
mountPath: /etc/dnsmasq.d
|
||||
- name: etcdnsmasqdavailable
|
||||
mountPath: /etc/dnsmasq.d-available
|
||||
|
||||
volumes:
|
||||
- name: etcdnsmasqd
|
||||
hostPath:
|
||||
path: /etc/dnsmasq.d
|
||||
- name: etcdnsmasqdavailable
|
||||
hostPath:
|
||||
path: /etc/dnsmasq.d-available
|
||||
@@ -0,0 +1,2 @@
|
||||
.*.swp
|
||||
.vagrant
|
||||
@@ -0,0 +1,53 @@
|
||||
---
|
||||
- name: gather os specific variables
|
||||
include_vars: "{{ item }}"
|
||||
with_first_found:
|
||||
- files:
|
||||
- "{{ ansible_distribution|lower }}-{{ ansible_distribution_version|lower|replace('/', '_') }}.yml"
|
||||
- "{{ ansible_distribution|lower }}-{{ ansible_distribution_release }}.yml"
|
||||
- "{{ ansible_distribution|lower }}-{{ ansible_distribution_major_version|lower|replace('/', '_') }}.yml"
|
||||
- "{{ ansible_distribution|lower }}.yml"
|
||||
- "{{ ansible_os_family|lower }}.yml"
|
||||
- defaults.yml
|
||||
paths:
|
||||
- ../vars
|
||||
|
||||
- name: check for minimum kernel version
|
||||
fail:
|
||||
msg: >
|
||||
docker requires a minimum kernel version of
|
||||
{{ docker_kernel_min_version }} on
|
||||
{{ ansible_distribution }}-{{ ansible_distribution_version }}
|
||||
when: ansible_kernel|version_compare(docker_kernel_min_version, "<")
|
||||
|
||||
- name: ensure docker requirements packages are installed
|
||||
action: "{{ docker_package_info.pkg_mgr }}"
|
||||
args: docker_package_info.args
|
||||
with_items: docker_package_info.pre_pkgs
|
||||
when: docker_package_info.pre_pkgs|length > 0
|
||||
|
||||
- name: ensure docker repository public key is installed
|
||||
action: "{{ docker_repo_key_info.pkg_key }}"
|
||||
args: docker_repo_key_info.args
|
||||
with_items: docker_repo_key_info.repo_keys
|
||||
when: docker_repo_key_info.repo_keys|length > 0
|
||||
|
||||
- name: ensure docker repository is enabled
|
||||
action: "{{ docker_repo_info.pkg_repo }}"
|
||||
args: docker_repo_info.args
|
||||
with_items: docker_repo_info.repos
|
||||
when: docker_repo_info.repos|length > 0
|
||||
|
||||
- name: ensure docker packages are installed
|
||||
action: "{{ docker_package_info.pkg_mgr }}"
|
||||
args: docker_package_info.args
|
||||
with_items: docker_package_info.pkgs
|
||||
when: docker_package_info.pkgs|length > 0
|
||||
|
||||
- name: ensure docker service is started and enabled
|
||||
service:
|
||||
name: "{{ item }}"
|
||||
enabled: yes
|
||||
state: started
|
||||
with_items:
|
||||
- docker
|
||||
@@ -0,0 +1,24 @@
|
||||
docker_kernel_min_version: '2.6.32-431'
|
||||
|
||||
docker_package_info:
|
||||
pkg_mgr: yum
|
||||
args:
|
||||
name: "{{ item }}"
|
||||
state: latest
|
||||
update_cache: yes
|
||||
pre_pkgs:
|
||||
- epel-release
|
||||
- curl
|
||||
- device-mapper-libs
|
||||
pkgs:
|
||||
- docker-io
|
||||
|
||||
docker_repo_key_info:
|
||||
pkg_key: ''
|
||||
args: {}
|
||||
repo_keys: []
|
||||
|
||||
docker_repo_info:
|
||||
pkg_repo: ''
|
||||
args: {}
|
||||
repos: []
|
||||
@@ -0,0 +1,36 @@
|
||||
docker_kernel_min_version: '3.2'
|
||||
|
||||
docker_package_info:
|
||||
pkg_mgr: apt
|
||||
args:
|
||||
pkg: "{{ item }}"
|
||||
update_cache: yes
|
||||
cache_valid_time: 600
|
||||
state: latest
|
||||
pre_pkgs:
|
||||
- apt-transport-https
|
||||
- curl
|
||||
- software-properties-common
|
||||
pkgs:
|
||||
- docker-engine
|
||||
|
||||
docker_repo_key_info:
|
||||
pkg_key: apt_key
|
||||
args:
|
||||
id: "{{ item }}"
|
||||
keyserver: hkp://p80.pool.sks-keyservers.net:80
|
||||
state: present
|
||||
repo_keys:
|
||||
- 58118E89F3A912897C070ADBF76221572C52609D
|
||||
|
||||
docker_repo_info:
|
||||
pkg_repo: apt_repository
|
||||
args:
|
||||
repo: "{{ item }}"
|
||||
update_cache: yes
|
||||
state: present
|
||||
repos:
|
||||
- >
|
||||
deb https://apt.dockerproject.org/repo
|
||||
{{ ansible_distribution|lower }}-{{ ansible_distribution_release|lower }}
|
||||
main
|
||||
@@ -0,0 +1,22 @@
|
||||
docker_kernel_min_version: '0'
|
||||
|
||||
docker_package_info:
|
||||
pkg_mgr: yum
|
||||
args:
|
||||
name: "{{ item }}"
|
||||
state: latest
|
||||
update_cache: yes
|
||||
pre_pkgs:
|
||||
- curl
|
||||
pkgs:
|
||||
- docker-io
|
||||
|
||||
docker_repo_key_info:
|
||||
pkg_key: ''
|
||||
args: {}
|
||||
repo_keys: []
|
||||
|
||||
docker_repo_info:
|
||||
pkg_repo: ''
|
||||
args: {}
|
||||
repos: []
|
||||
@@ -0,0 +1,22 @@
|
||||
docker_kernel_min_version: '0'
|
||||
|
||||
docker_package_info:
|
||||
pkg_mgr: yum
|
||||
args:
|
||||
name: "{{ item }}"
|
||||
state: latest
|
||||
update_cache: yes
|
||||
pre_pkgs:
|
||||
- curl
|
||||
pkgs:
|
||||
- docker
|
||||
|
||||
docker_repo_key_info:
|
||||
pkg_key: ''
|
||||
args: {}
|
||||
repo_keys: []
|
||||
|
||||
docker_repo_info:
|
||||
pkg_repo: ''
|
||||
args: {}
|
||||
repos: []
|
||||
@@ -0,0 +1,42 @@
|
||||
---
|
||||
local_release_dir: /tmp
|
||||
|
||||
flannel_version: 0.5.5
|
||||
calico_version: v0.13.0
|
||||
calico_plugin_version: v0.7.0
|
||||
kube_version: v1.1.3
|
||||
|
||||
kubectl_checksum: "01b9bea18061a27b1cf30e34fd8ab45cfc096c9a9d57d0ed21072abb40dd3d1d"
|
||||
kubelet_checksum: "62191c66f2d670dd52ddf1d88ef81048977abf1ffaa95ee6333299447eb6a482"
|
||||
|
||||
kube_download_url: "https://storage.googleapis.com/kubernetes-release/release/{{ kube_version }}/bin/linux/amd64"
|
||||
|
||||
flannel_download_url: "https://github.com/coreos/flannel/releases/download/v{{ flannel_version }}/flannel-{{ flannel_version }}-linux-amd64.tar.gz"
|
||||
|
||||
calico_download_url: "https://github.com/Metaswitch/calico-docker/releases/download/{{calico_version}}/calicoctl"
|
||||
|
||||
calico_plugin_download_url: "https://github.com/projectcalico/calico-kubernetes/releases/download/{{calico_plugin_version}}/calico_kubernetes"
|
||||
|
||||
downloads:
|
||||
- name: calico
|
||||
dest: calico/bin/calicoctl
|
||||
url: "{{calico_download_url}}"
|
||||
|
||||
- name: calico-plugin
|
||||
dest: calico/bin/calico
|
||||
url: "{{calico_plugin_download_url}}"
|
||||
|
||||
- name: flannel
|
||||
dest: flannel/flannel-{{ flannel_version }}-linux-amd64.tar.gz
|
||||
url: "{{flannel_download_url}}"
|
||||
unarchive: yes
|
||||
|
||||
- name: kubernetes-kubelet
|
||||
dest: kubernetes/bin/kubelet
|
||||
sha256: "{{kubelet_checksum}}"
|
||||
url: "{{ kube_download_url }}/kubelet"
|
||||
|
||||
- name: kubernetes-kubectl
|
||||
dest: kubernetes/bin/kubectl
|
||||
sha256: "{{kubectl_checksum}}"
|
||||
url: "{{ kube_download_url }}/kubectl"
|
||||
@@ -0,0 +1,19 @@
|
||||
---
|
||||
- name: Create dest directories
|
||||
file: path={{local_release_dir}}/{{item.dest|dirname}} state=directory recurse=yes
|
||||
with_items: downloads
|
||||
|
||||
- name: Download items
|
||||
get_url:
|
||||
url: "{{item.url}}"
|
||||
dest: "{{local_release_dir}}/{{item.dest}}"
|
||||
sha256sum: "{{item.sha256 | default(omit)}}"
|
||||
with_items: downloads
|
||||
|
||||
- name: Extract archives
|
||||
unarchive:
|
||||
src: "{{ local_release_dir }}/{{item.dest}}"
|
||||
dest: "{{ local_release_dir }}/{{item.dest|dirname}}"
|
||||
copy: no
|
||||
when: "{{item.unarchive is defined and item.unarchive == True}}"
|
||||
with_items: downloads
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: ETCD2 | Stop etcd2 service
|
||||
service: name=etcd state=stopped
|
||||
ignore_errors: yes
|
||||
|
||||
- name: ETCD2 | create etcd pod template
|
||||
template: src=etcd-pod.yml dest=/etc/kubernetes/manifests/etcd-pod.manifest
|
||||
|
||||
- name: ETCD2 | Check for etcd2 port
|
||||
wait_for:
|
||||
port: 2379
|
||||
delay: 5
|
||||
timeout: 100
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: etcd
|
||||
namespace: kube-system
|
||||
spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: etcd
|
||||
image: quay.io/coreos/etcd:v2.2.2
|
||||
resources:
|
||||
limits:
|
||||
cpu: 100m
|
||||
memory: 256M
|
||||
args:
|
||||
{% if inventory_hostname in groups['etcd'] %}
|
||||
- --name
|
||||
- etcd-{{inventory_hostname}}-master
|
||||
- --advertise-client-urls
|
||||
- "http://{{ hostvars[inventory_hostname]['ip'] | default( ansible_default_ipv4.address) }}:2379"
|
||||
- --listen-peer-urls
|
||||
- http://0.0.0.0:2380
|
||||
- --initial-advertise-peer-urls
|
||||
- http://{{ hostvars[inventory_hostname]['ip'] | default( ansible_default_ipv4.address) }}:2380
|
||||
- --data-dir
|
||||
- /var/etcd/data
|
||||
- --initial-cluster-state
|
||||
- new
|
||||
{% else %}
|
||||
- --proxy
|
||||
- 'on'
|
||||
{% endif %}
|
||||
- --listen-client-urls
|
||||
- "http://{{ hostvars[inventory_hostname]['ip'] | default( ansible_default_ipv4.address) }}:2379,http://127.0.0.1:2379"
|
||||
- --initial-cluster
|
||||
- "{% for host in groups['etcd'] %}etcd-{{host}}-master=http://{{ hostvars[host]['ip'] | default( hostvars[host]['ansible_default_ipv4']['address']) }}:2380{% if not loop.last %},{% endif %}{% endfor %}"
|
||||
- --initial-cluster-token
|
||||
- etcd-k8s-cluster
|
||||
ports:
|
||||
- name: etcd-client
|
||||
containerPort: 2379
|
||||
hostPort: 2379
|
||||
- name: etcd-peer
|
||||
containerPort: 2380
|
||||
hostPort: 2380
|
||||
volumeMounts:
|
||||
- name: varetcd
|
||||
mountPath: /var/etcd
|
||||
readOnly: false
|
||||
volumes:
|
||||
- name: varetcd
|
||||
hostPath:
|
||||
path: /containers/pods/etcd-{{inventory_hostname}}/rootfs/var/etcd
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: reload systemd
|
||||
command: systemctl daemon-reload
|
||||
|
||||
- name: restart systemd-kubelet
|
||||
command: /bin/true
|
||||
notify:
|
||||
- reload systemd
|
||||
- restart kubelet
|
||||
|
||||
- name: restart kubelet
|
||||
service:
|
||||
name: kubelet
|
||||
state: restarted
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
dependencies:
|
||||
- { role: etcd }
|
||||
- { role: kubernetes/node }
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
- name: Copy kubectl bash completion
|
||||
copy:
|
||||
src: kubectl_bash_completion.sh
|
||||
dest: /etc/bash_completion.d/kubectl.sh
|
||||
|
||||
- name: Install kubectl binary
|
||||
synchronize:
|
||||
src: "{{ local_release_dir }}/kubernetes/bin/kubectl"
|
||||
dest: "{{ bin_dir }}/kubectl"
|
||||
archive: no
|
||||
checksum: yes
|
||||
times: yes
|
||||
delegate_to: "{{ groups['downloader'][0] }}"
|
||||
|
||||
- name: Perms kubectl binary
|
||||
file: path={{ bin_dir }}/kubectl owner=kube mode=0755 state=file
|
||||
|
||||
- name: populate users for basic auth in API
|
||||
lineinfile:
|
||||
dest: "{{ kube_users_dir }}/known_users.csv"
|
||||
create: yes
|
||||
line: '{{ item.value.pass }},{{ item.key }},{{ item.value.role }}'
|
||||
backup: yes
|
||||
with_dict: "{{ kube_users }}"
|
||||
|
||||
# Sync masters
|
||||
- name: synchronize auth directories for masters
|
||||
synchronize:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ kube_config_dir }}"
|
||||
recursive: yes
|
||||
delete: yes
|
||||
rsync_opts: [ '--one-file-system']
|
||||
set_remote_user: false
|
||||
with_items:
|
||||
- "{{ kube_token_dir }}"
|
||||
- "{{ kube_cert_dir }}"
|
||||
- "{{ kube_users_dir }}"
|
||||
delegate_to: "{{ groups['kube-master'][0] }}"
|
||||
when: inventory_hostname != "{{ groups['kube-master'][0] }}"
|
||||
|
||||
# Write manifests
|
||||
- name: Write kube-apiserver manifest
|
||||
template:
|
||||
src: manifests/kube-apiserver.manifest.j2
|
||||
dest: "{{ kube_manifest_dir }}/kube-apisever.manifest"
|
||||
notify:
|
||||
- restart kubelet
|
||||
|
||||
- meta: flush_handlers
|
||||
|
||||
- name: wait for the apiserver to be running (pulling image and running container)
|
||||
wait_for:
|
||||
port: "{{kube_apiserver_insecure_port}}"
|
||||
delay: 10
|
||||
timeout: 60
|
||||
|
||||
- name: Create 'kube-system' namespace
|
||||
uri:
|
||||
url: http://127.0.0.1:{{ kube_apiserver_insecure_port }}/api/v1/namespaces
|
||||
method: POST
|
||||
body: '{"apiVersion":"v1","kind":"Namespace","metadata":{"name":"kube-system"}}'
|
||||
status_code: 201,409
|
||||
body_format: json
|
||||
run_once: yes
|
||||
when: inventory_hostname == groups['kube-master'][0]
|
||||
|
||||
- name: Write kube-controller-manager manifest
|
||||
template:
|
||||
src: manifests/kube-controller-manager.manifest.j2
|
||||
dest: "{{ kube_config_dir }}/kube-controller-manager.manifest"
|
||||
|
||||
- name: Write kube-scheduler manifest
|
||||
template:
|
||||
src: manifests/kube-scheduler.manifest.j2
|
||||
dest: "{{ kube_config_dir }}/kube-scheduler.manifest"
|
||||
|
||||
- name: Write podmaster manifest
|
||||
template:
|
||||
src: manifests/kube-podmaster.manifest.j2
|
||||
dest: "{{ kube_manifest_dir }}/kube-podmaster.manifest"
|
||||
@@ -0,0 +1,18 @@
|
||||
apiVersion: v1
|
||||
kind: Config
|
||||
current-context: kubectl-to-{{ cluster_name }}
|
||||
preferences: {}
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority-data: {{ kube_node_cert|b64encode }}
|
||||
server: https://{{ groups['kube-master'][0] }}:{{ kube_apiserver_port }}
|
||||
name: {{ cluster_name }}
|
||||
contexts:
|
||||
- context:
|
||||
cluster: {{ cluster_name }}
|
||||
user: kubectl
|
||||
name: kubectl-to-{{ cluster_name }}
|
||||
users:
|
||||
- name: kubectl
|
||||
user:
|
||||
token: {{ kubectl_token }}
|
||||
@@ -0,0 +1,52 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: kube-apiserver
|
||||
spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kube-apiserver
|
||||
image: {{ hyperkube_image_repo }}:{{ hyperkube_image_tag }}
|
||||
command:
|
||||
- /hyperkube
|
||||
- apiserver
|
||||
- --etcd-servers={% for srv in groups['etcd'] %}http://{{ srv }}:2379{% if not loop.last %},{% endif %}{% endfor %}
|
||||
|
||||
- --admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota
|
||||
- --service-cluster-ip-range={{ kube_service_addresses }}
|
||||
- --client-ca-file={{ kube_cert_dir }}/ca.pem
|
||||
- --basic-auth-file={{ kube_users_dir }}/known_users.csv
|
||||
- --tls-cert-file={{ kube_cert_dir }}/apiserver.pem
|
||||
- --tls-private-key-file={{ kube_cert_dir }}/apiserver-key.pem
|
||||
- --service-account-key-file={{ kube_cert_dir }}/apiserver-key.pem
|
||||
- --secure-port={{ kube_apiserver_port }}
|
||||
- --insecure-port={{ kube_apiserver_insecure_port }}
|
||||
{% if kube_api_runtime_config is defined %}
|
||||
{% for conf in kube_api_runtime_config %}
|
||||
- --runtime-config={{ conf }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
- --token-auth-file={{ kube_token_dir }}/known_tokens.csv
|
||||
- --v={{ kube_log_level | default('2') }}
|
||||
- --allow-privileged=true
|
||||
ports:
|
||||
- containerPort: {{ kube_apiserver_port }}
|
||||
hostPort: {{ kube_apiserver_port }}
|
||||
name: https
|
||||
- containerPort: {{ kube_apiserver_insecure_port }}
|
||||
hostPort: {{ kube_apiserver_insecure_port }}
|
||||
name: local
|
||||
volumeMounts:
|
||||
- mountPath: {{ kube_config_dir }}
|
||||
name: kubernetes-config
|
||||
readOnly: true
|
||||
- mountPath: /etc/ssl/certs
|
||||
name: ssl-certs-host
|
||||
readOnly: true
|
||||
volumes:
|
||||
- hostPath:
|
||||
path: {{ kube_config_dir }}
|
||||
name: kubernetes-config
|
||||
- hostPath:
|
||||
path: /usr/share/ca-certificates
|
||||
name: ssl-certs-host
|
||||
@@ -0,0 +1,38 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: kube-controller-manager
|
||||
namespace: kube-system
|
||||
spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kube-controller-manager
|
||||
image: {{ hyperkube_image_repo }}:{{ hyperkube_image_tag }}
|
||||
command:
|
||||
- /hyperkube
|
||||
- controller-manager
|
||||
- --master=http://127.0.0.1:{{kube_apiserver_insecure_port}}
|
||||
- --service-account-private-key-file={{ kube_cert_dir }}/apiserver-key.pem
|
||||
- --root-ca-file={{ kube_cert_dir }}/ca.pem
|
||||
- --v={{ kube_log_level | default('2') }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
host: 127.0.0.1
|
||||
path: /healthz
|
||||
port: 10252
|
||||
initialDelaySeconds: 15
|
||||
timeoutSeconds: 1
|
||||
volumeMounts:
|
||||
- mountPath: {{ kube_cert_dir }}
|
||||
name: ssl-certs-kubernetes
|
||||
readOnly: true
|
||||
- mountPath: /etc/ssl/certs
|
||||
name: ssl-certs-host
|
||||
readOnly: true
|
||||
volumes:
|
||||
- hostPath:
|
||||
path: {{ kube_cert_dir }}
|
||||
name: ssl-certs-kubernetes
|
||||
- hostPath:
|
||||
path: /usr/share/ca-certificates
|
||||
name: ssl-certs-host
|
||||
@@ -0,0 +1,46 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: kube-podmaster
|
||||
namespace: kube-system
|
||||
spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: scheduler-elector
|
||||
image: gcr.io/google_containers/podmaster:1.1
|
||||
command:
|
||||
- /podmaster
|
||||
- --etcd-servers={% for srv in groups['etcd'] %}http://{{ srv }}:2379{% if not loop.last %},{% endif %}{% endfor %}
|
||||
|
||||
- --key=scheduler
|
||||
- --source-file={{ kube_config_dir}}/kube-scheduler.manifest
|
||||
- --dest-file={{ kube_manifest_dir }}/kube-scheduler.manifest
|
||||
volumeMounts:
|
||||
- mountPath: {{ kube_config_dir }}
|
||||
name: manifest-src
|
||||
readOnly: true
|
||||
- mountPath: {{ kube_manifest_dir }}
|
||||
name: manifest-dst
|
||||
- name: controller-manager-elector
|
||||
image: gcr.io/google_containers/podmaster:1.1
|
||||
command:
|
||||
- /podmaster
|
||||
- --etcd-servers={% for srv in groups['etcd'] %}http://{{ srv }}:2379{% if not loop.last %},{% endif %}{% endfor %}
|
||||
|
||||
- --key=controller
|
||||
- --source-file={{ kube_config_dir }}/kube-controller-manager.manifest
|
||||
- --dest-file={{ kube_manifest_dir }}/kube-controller-manager.manifest
|
||||
terminationMessagePath: /dev/termination-log
|
||||
volumeMounts:
|
||||
- mountPath: {{ kube_config_dir }}
|
||||
name: manifest-src
|
||||
readOnly: true
|
||||
- mountPath: {{ kube_manifest_dir }}
|
||||
name: manifest-dst
|
||||
volumes:
|
||||
- hostPath:
|
||||
path: {{ kube_config_dir }}
|
||||
name: manifest-src
|
||||
- hostPath:
|
||||
path: {{ kube_manifest_dir }}
|
||||
name: manifest-dst
|
||||
@@ -0,0 +1,22 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: kube-scheduler
|
||||
namespace: kube-system
|
||||
spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kube-scheduler
|
||||
image: {{ hyperkube_image_repo }}:{{ hyperkube_image_tag }}
|
||||
command:
|
||||
- /hyperkube
|
||||
- scheduler
|
||||
- --master=http://127.0.0.1:{{kube_apiserver_insecure_port}}
|
||||
- --v={{ kube_log_level | default('2') }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
host: 127.0.0.1
|
||||
path: /healthz
|
||||
port: 10251
|
||||
initialDelaySeconds: 15
|
||||
timeoutSeconds: 1
|
||||
@@ -0,0 +1,49 @@
|
||||
# This directory is where all the additional scripts go
|
||||
# that Kubernetes normally puts in /srv/kubernetes.
|
||||
# This puts them in a sane location
|
||||
kube_script_dir: "{{ bin_dir }}/kubernetes-scripts"
|
||||
|
||||
# This directory is where all the additional config stuff goes
|
||||
# the kubernetes normally puts in /srv/kubernets.
|
||||
# This puts them in a sane location.
|
||||
# Editting this value will almost surely break something. Don't
|
||||
# change it. Things like the systemd scripts are hard coded to
|
||||
# look in here. Don't do it.
|
||||
kube_config_dir: /etc/kubernetes
|
||||
|
||||
# This is where all the cert scripts and certs will be located
|
||||
kube_cert_dir: "{{ kube_config_dir }}/ssl"
|
||||
|
||||
# This is where all of the bearer tokens will be stored
|
||||
kube_token_dir: "{{ kube_config_dir }}/tokens"
|
||||
|
||||
# This is where to save basic auth file
|
||||
kube_users_dir: "{{ kube_config_dir }}/users"
|
||||
|
||||
# This is where you can drop yaml/json files and the kubelet will run those
|
||||
# pods on startup
|
||||
kube_manifest_dir: "{{ kube_config_dir }}/manifests"
|
||||
|
||||
# This is the group that the cert creation scripts chgrp the
|
||||
# cert files to. Not really changable...
|
||||
kube_cert_group: kube-cert
|
||||
|
||||
dns_domain: "{{ cluster_name }}"
|
||||
|
||||
kube_proxy_mode: userspace
|
||||
|
||||
# Temporary image, waiting for official google release
|
||||
# hyperkube_image_repo: gcr.io/google_containers/hyperkube
|
||||
hyperkube_image_repo: quay.io/smana/hyperkube
|
||||
hyperkube_image_tag: v1.1.3
|
||||
|
||||
# IP address of the DNS server.
|
||||
# Kubernetes will create a pod with several containers, serving as the DNS
|
||||
# server and expose it under this IP address. The IP address must be from
|
||||
# the range specified as kube_service_addresses. This magic will actually
|
||||
# pick the 10th ip address in the kube_service_addresses range and use that.
|
||||
dns_server: "{{ kube_service_addresses|ipaddr('net')|ipaddr(253)|ipaddr('address') }}"
|
||||
|
||||
kube_api_runtime_config:
|
||||
- extensions/v1beta1/daemonsets=true
|
||||
- extensions/v1beta1/deployments=true
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
token_dir=${TOKEN_DIR:-/var/srv/kubernetes}
|
||||
token_file="${token_dir}/known_tokens.csv"
|
||||
|
||||
create_accounts=($@)
|
||||
|
||||
if [ ! -e "${token_file}" ]; then
|
||||
touch "${token_file}"
|
||||
fi
|
||||
|
||||
for account in "${create_accounts[@]}"; do
|
||||
if grep ",${account}," "${token_file}" ; then
|
||||
continue
|
||||
fi
|
||||
token=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null)
|
||||
echo "${token},${account},${account}" >> "${token_file}"
|
||||
echo "${token}" > "${token_dir}/${account}.token"
|
||||
echo "Added ${account}"
|
||||
done
|
||||
@@ -0,0 +1,107 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Author: skahlouc@skahlouc-laptop
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
||||
usage()
|
||||
{
|
||||
cat << EOF
|
||||
Create self signed certificates
|
||||
|
||||
Usage : $(basename $0) -f <config> [-c <cloud_provider>] [-d <ssldir>] [-g <ssl_group>]
|
||||
-h | --help : Show this message
|
||||
-f | --config : Openssl configuration file
|
||||
-c | --cloud : Cloud provider (GCE, AWS or AZURE)
|
||||
-d | --ssldir : Directory where the certificates will be installed
|
||||
-g | --sslgrp : Group of the certificates
|
||||
|
||||
ex :
|
||||
$(basename $0) -f openssl.conf -c GCE -d /srv/ssl -g kube
|
||||
EOF
|
||||
}
|
||||
|
||||
# Options parsing
|
||||
while (($#)); do
|
||||
case "$1" in
|
||||
-h | --help) usage; exit 0;;
|
||||
-f | --config) CONFIG=${2}; shift 2;;
|
||||
-c | --cloud) CLOUD=${2}; shift 2;;
|
||||
-d | --ssldir) SSLDIR="${2}"; shift 2;;
|
||||
-g | --group) SSLGRP="${2}"; shift 2;;
|
||||
*)
|
||||
usage
|
||||
echo "ERROR : Unknown option"
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z ${CONFIG} ]; then
|
||||
echo "ERROR: the openssl configuration file is missing. option -f"
|
||||
exit 1
|
||||
fi
|
||||
if [ -z ${SSLDIR} ]; then
|
||||
SSLDIR="/etc/kubernetes/certs"
|
||||
fi
|
||||
if [ -z ${SSLGRP} ]; then
|
||||
SSLGRP="kube-cert"
|
||||
fi
|
||||
|
||||
#echo "config=$CONFIG, cloud=$CLOUD, certdir=$SSLDIR, certgroup=$SSLGRP"
|
||||
|
||||
SUPPORTED_CLOUDS="GCE AWS AZURE"
|
||||
|
||||
# TODO: Add support for discovery on other providers?
|
||||
if [ "${CLOUD}" == "GCE" ]; then
|
||||
CLOUD_IP=$(curl -s -H Metadata-Flavor:Google http://metadata.google.internal./computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip)
|
||||
fi
|
||||
|
||||
if [ "${CLOUD}" == "AWS" ]; then
|
||||
CLOUD_IP=$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4)
|
||||
fi
|
||||
|
||||
if [ "${CLOUD}" == "AZURE" ]; then
|
||||
CLOUD_IP=$(uname -n | awk -F. '{ print $2 }').cloudapp.net
|
||||
fi
|
||||
|
||||
tmpdir=$(mktemp -d --tmpdir kubernetes_cacert.XXXXXX)
|
||||
trap 'rm -rf "${tmpdir}"' EXIT
|
||||
cd "${tmpdir}"
|
||||
|
||||
mkdir -p "${SSLDIR}"
|
||||
|
||||
# Root CA
|
||||
openssl genrsa -out ca-key.pem 2048 > /dev/null 2>&1
|
||||
openssl req -x509 -new -nodes -key ca-key.pem -days 10000 -out ca.pem -subj "/CN=kube-ca" > /dev/null 2>&1
|
||||
|
||||
# Apiserver
|
||||
openssl genrsa -out apiserver-key.pem 2048 > /dev/null 2>&1
|
||||
openssl req -new -key apiserver-key.pem -out apiserver.csr -subj "/CN=kube-apiserver" -config ${CONFIG} > /dev/null 2>&1
|
||||
openssl x509 -req -in apiserver.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out apiserver.pem -days 365 -extensions v3_req -extfile ${CONFIG} > /dev/null 2>&1
|
||||
|
||||
# Nodes and Admin
|
||||
for i in node admin; do
|
||||
openssl genrsa -out ${i}-key.pem 2048 > /dev/null 2>&1
|
||||
openssl req -new -key ${i}-key.pem -out ${i}.csr -subj "/CN=kube-${i}" > /dev/null 2>&1
|
||||
openssl x509 -req -in ${i}.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out ${i}.pem -days 365 > /dev/null 2>&1
|
||||
done
|
||||
|
||||
# Install certs
|
||||
mv *.pem ${SSLDIR}/
|
||||
chgrp ${SSLGRP} ${SSLDIR}/*
|
||||
chmod 600 ${SSLDIR}/*-key.pem
|
||||
chown root:root ${SSLDIR}/*-key.pem
|
||||
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: reload systemd
|
||||
command: systemctl daemon-reload
|
||||
|
||||
- name: restart systemd-kubelet
|
||||
command: /bin/true
|
||||
notify:
|
||||
- reload systemd
|
||||
- restart kubelet
|
||||
|
||||
- name: restart kubelet
|
||||
service:
|
||||
name: kubelet
|
||||
state: restarted
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
- name: certs | install cert generation script
|
||||
copy:
|
||||
src=make-ssl.sh
|
||||
dest={{ kube_script_dir }}
|
||||
mode=0500
|
||||
changed_when: false
|
||||
|
||||
- name: certs | write openssl config
|
||||
template:
|
||||
src: "openssl.conf.j2"
|
||||
dest: "{{ kube_config_dir }}/.openssl.conf"
|
||||
|
||||
- name: certs | run cert generation script
|
||||
shell: >
|
||||
{{ kube_script_dir }}/make-ssl.sh
|
||||
-f {{ kube_config_dir }}/.openssl.conf
|
||||
-g {{ kube_cert_group }}
|
||||
-d {{ kube_cert_dir }}
|
||||
args:
|
||||
creates: "{{ kube_cert_dir }}/apiserver.pem"
|
||||
|
||||
- name: certs | check certificate permissions
|
||||
file:
|
||||
path={{ kube_cert_dir }}
|
||||
group={{ kube_cert_group }}
|
||||
owner=kube
|
||||
recurse=yes
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
- name: tokens | copy the token gen script
|
||||
copy:
|
||||
src=kube-gen-token.sh
|
||||
dest={{ kube_script_dir }}
|
||||
mode=u+x
|
||||
when: inventory_hostname == groups['kube-master'][0]
|
||||
|
||||
- name: tokens | generate tokens for master components
|
||||
command: "{{ kube_script_dir }}/kube-gen-token.sh {{ item[0] }}-{{ item[1] }}"
|
||||
environment:
|
||||
TOKEN_DIR: "{{ kube_token_dir }}"
|
||||
with_nested:
|
||||
- [ "system:kubectl" ]
|
||||
- "{{ groups['kube-master'] }}"
|
||||
register: gentoken
|
||||
changed_when: "'Added' in gentoken.stdout"
|
||||
when: inventory_hostname == groups['kube-master'][0]
|
||||
|
||||
- name: tokens | generate tokens for node components
|
||||
command: "{{ kube_script_dir }}/kube-gen-token.sh {{ item[0] }}-{{ item[1] }}"
|
||||
environment:
|
||||
TOKEN_DIR: "{{ kube_token_dir }}"
|
||||
with_nested:
|
||||
- [ 'system:kubelet' ]
|
||||
- "{{ groups['kube-node'] }}"
|
||||
register: gentoken
|
||||
changed_when: "'Added' in gentoken.stdout"
|
||||
when: inventory_hostname == groups['kube-master'][0]
|
||||
|
||||
- name: tokens | generate tokens for calico
|
||||
command: "{{ kube_script_dir }}/kube-gen-token.sh {{ item[0] }}-{{ item[1] }}"
|
||||
environment:
|
||||
TOKEN_DIR: "{{ kube_token_dir }}"
|
||||
with_nested:
|
||||
- [ "system:calico" ]
|
||||
- "{{ groups['k8s-cluster'] }}"
|
||||
register: gentoken
|
||||
changed_when: "'Added' in gentoken.stdout"
|
||||
when: kube_network_plugin == "calico"
|
||||
delegate_to: "{{ groups['kube-master'][0] }}"
|
||||
|
||||
- name: tokens | get the calico token values
|
||||
slurp:
|
||||
src: "{{ kube_token_dir }}/system:calico-{{ inventory_hostname }}.token"
|
||||
register: calico_token
|
||||
when: kube_network_plugin == "calico"
|
||||
delegate_to: "{{ groups['kube-master'][0] }}"
|
||||
@@ -0,0 +1,48 @@
|
||||
---
|
||||
- debug: msg="{{init_system == "systemd"}}"
|
||||
- debug: msg="{{init_system}}"
|
||||
|
||||
- name: install | Write kubelet systemd init file
|
||||
template: src=kubelet.service.j2 dest=/etc/systemd/system/kubelet.service backup=yes
|
||||
when: init_system == "systemd"
|
||||
notify: restart systemd-kubelet
|
||||
|
||||
- name: install | Write kubelet initd script
|
||||
template: src=deb-kubelet.initd.j2 dest=/etc/init.d/kubelet owner=root mode=755 backup=yes
|
||||
when: init_system == "sysvinit" and ansible_os_family == "Debian"
|
||||
notify: restart kubelet
|
||||
|
||||
- name: install | Write kubelet initd script
|
||||
template: src=rh-kubelet.initd.j2 dest=/etc/init.d/kubelet owner=root mode=755 backup=yes
|
||||
when: init_system == "sysvinit" and ansible_os_family == "RedHat"
|
||||
notify: restart kubelet
|
||||
|
||||
- name: install | Install kubelet binary
|
||||
synchronize:
|
||||
src: "{{ local_release_dir }}/kubernetes/bin/kubelet"
|
||||
dest: "{{ bin_dir }}/kubelet"
|
||||
times: yes
|
||||
archive: no
|
||||
delegate_to: "{{ groups['downloader'][0] }}"
|
||||
notify:
|
||||
- restart kubelet
|
||||
|
||||
- name: install | Perms kubelet binary
|
||||
file: path={{ bin_dir }}/kubelet owner=kube mode=0755 state=file
|
||||
|
||||
- name: install | Calico-plugin | Directory
|
||||
file: path=/usr/libexec/kubernetes/kubelet-plugins/net/exec/calico/ state=directory
|
||||
when: kube_network_plugin == "calico"
|
||||
|
||||
- name: install | Calico-plugin | Binary
|
||||
synchronize:
|
||||
src: "{{ local_release_dir }}/calico/bin/calico"
|
||||
dest: "/usr/libexec/kubernetes/kubelet-plugins/net/exec/calico/calico"
|
||||
times: yes
|
||||
archive: no
|
||||
delegate_to: "{{ groups['downloader'][0] }}"
|
||||
when: kube_network_plugin == "calico"
|
||||
notify: restart kubelet
|
||||
|
||||
- name: install | Perms calico plugin binary
|
||||
file: path=/usr/libexec/kubernetes/kubelet-plugins/net/exec/calico/calico owner=kube mode=0755 state=file
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
- name: create kubernetes config directory
|
||||
file: path={{ kube_config_dir }} state=directory
|
||||
|
||||
- name: create kubernetes script directory
|
||||
file: path={{ kube_script_dir }} state=directory
|
||||
|
||||
- name: Make sure manifest directory exists
|
||||
file: path={{ kube_manifest_dir }} state=directory
|
||||
|
||||
|
||||
- name: certs | create system kube-cert groups
|
||||
group: name={{ kube_cert_group }} state=present system=yes
|
||||
|
||||
- name: create system kube user
|
||||
user:
|
||||
name=kube
|
||||
comment="Kubernetes user"
|
||||
shell=/sbin/nologin
|
||||
state=present
|
||||
system=yes
|
||||
groups={{ kube_cert_group }}
|
||||
|
||||
- include: secrets.yml
|
||||
tags:
|
||||
- secrets
|
||||
|
||||
- include: install.yml
|
||||
|
||||
- name: Write kubelet config file
|
||||
template: src=kubelet.j2 dest={{ kube_config_dir }}/kubelet backup=yes
|
||||
notify:
|
||||
- restart kubelet
|
||||
|
||||
- name: write the kubecfg (auth) file for kubelet
|
||||
template: src=node-kubeconfig.yaml.j2 dest={{ kube_config_dir }}/node-kubeconfig.yaml backup=yes
|
||||
notify:
|
||||
- restart kubelet
|
||||
|
||||
- name: Write proxy manifest
|
||||
template:
|
||||
src: manifests/kube-proxy.manifest.j2
|
||||
dest: "{{ kube_manifest_dir }}/kube-proxy.manifest"
|
||||
|
||||
- name: Enable kubelet
|
||||
service:
|
||||
name: kubelet
|
||||
enabled: yes
|
||||
state: started
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
- name: certs | make sure the certificate directory exits
|
||||
file:
|
||||
path={{ kube_cert_dir }}
|
||||
state=directory
|
||||
mode=o-rwx
|
||||
group={{ kube_cert_group }}
|
||||
|
||||
- name: tokens | make sure the tokens directory exits
|
||||
file:
|
||||
path={{ kube_token_dir }}
|
||||
state=directory
|
||||
mode=o-rwx
|
||||
group={{ kube_cert_group }}
|
||||
|
||||
- include: gen_certs.yml
|
||||
run_once: true
|
||||
when: inventory_hostname == groups['kube-master'][0]
|
||||
|
||||
- include: gen_tokens.yml
|
||||
|
||||
# Sync certs between nodes
|
||||
- user:
|
||||
name: '{{ansible_user_id}}'
|
||||
generate_ssh_key: yes
|
||||
delegate_to: "{{ groups['kube-master'][0] }}"
|
||||
run_once: yes
|
||||
|
||||
- name: 'get ssh keypair'
|
||||
slurp: path=~/.ssh/id_rsa.pub
|
||||
register: public_key
|
||||
delegate_to: "{{ groups['kube-master'][0] }}"
|
||||
|
||||
- name: 'setup keypair on nodes'
|
||||
authorized_key:
|
||||
user: '{{ansible_user_id}}'
|
||||
key: "{{public_key.content|b64decode }}"
|
||||
|
||||
- name: synchronize certificates for nodes
|
||||
synchronize:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ kube_cert_dir }}"
|
||||
recursive: yes
|
||||
delete: yes
|
||||
rsync_opts: [ '--one-file-system']
|
||||
set_remote_user: false
|
||||
with_items:
|
||||
- "{{ kube_cert_dir}}/ca.pem"
|
||||
- "{{ kube_cert_dir}}/node.pem"
|
||||
- "{{ kube_cert_dir}}/node-key.pem"
|
||||
delegate_to: "{{ groups['kube-master'][0] }}"
|
||||
when: inventory_hostname not in "{{ groups['kube-master'] }}"
|
||||
@@ -0,0 +1,119 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: kubelet
|
||||
# Required-Start: $local_fs $network $syslog
|
||||
# Required-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: The Kubernetes node container manager
|
||||
# Description:
|
||||
# The Kubernetes container manager maintains docker state against a state file.
|
||||
### END INIT INFO
|
||||
|
||||
|
||||
# PATH should only include /usr/* if it runs after the mountnfs.sh script
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="The Kubernetes container manager"
|
||||
NAME=kubelet
|
||||
DAEMON={{ bin_dir }}/kubelet
|
||||
DAEMON_ARGS=""
|
||||
DAEMON_LOG_FILE=/var/log/$NAME.log
|
||||
PIDFILE=/var/run/$NAME.pid
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
DAEMON_USER=root
|
||||
|
||||
# Exit if the package is not installed
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/kubernetes/$NAME ] && . /etc/kubernetes/$NAME
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
||||
# and status_of_proc is working.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
#
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been started
|
||||
# 1 if daemon was already running
|
||||
# 2 if daemon could not be started
|
||||
start-stop-daemon --start --quiet --background --no-close \
|
||||
--make-pidfile --pidfile $PIDFILE \
|
||||
--exec $DAEMON -c $DAEMON_USER --test > /dev/null \
|
||||
|| return 1
|
||||
start-stop-daemon --start --quiet --background --no-close \
|
||||
--make-pidfile --pidfile $PIDFILE \
|
||||
--exec $DAEMON -c $DAEMON_USER -- \
|
||||
$DAEMON_ARGS >> $DAEMON_LOG_FILE 2>&1 \
|
||||
|| return 2
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
# Return
|
||||
# 0 if daemon has been stopped
|
||||
# 1 if daemon was already stopped
|
||||
# 2 if daemon could not be stopped
|
||||
# other if a failure occurred
|
||||
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME
|
||||
RETVAL="$?"
|
||||
[ "$RETVAL" = 2 ] && return 2
|
||||
# Many daemons don't delete their pidfiles when they exit.
|
||||
rm -f $PIDFILE
|
||||
return "$RETVAL"
|
||||
}
|
||||
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
log_daemon_msg "Starting $DESC" "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) log_end_msg 0 || exit 0 ;;
|
||||
2) log_end_msg 1 || exit 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1) log_end_msg 0 ;;
|
||||
2) exit 1 ;;
|
||||
esac
|
||||
;;
|
||||
status)
|
||||
status_of_proc -p $PIDFILE "$DAEMON" "$NAME" && exit 0 || exit $?
|
||||
;;
|
||||
|
||||
restart|force-reload)
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
do_stop
|
||||
case "$?" in
|
||||
0|1)
|
||||
do_start
|
||||
case "$?" in
|
||||
0) log_end_msg 0 ;;
|
||||
1) log_end_msg 1 ;; # Old process is still running
|
||||
*) log_end_msg 1 ;; # Failed to start
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
# Failed to stop
|
||||
log_end_msg 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,28 @@
|
||||
KUBE_LOGTOSTDERR="--logtostderr=true"
|
||||
KUBE_LOG_LEVEL="--v={{ kube_log_level | default('2') }}"
|
||||
KUBE_ALLOW_PRIV="--allow_privileged=true"
|
||||
KUBELET_API_SERVER="--api_servers={% for host in groups['kube-master'] %}https://{{ hostvars[host]['ip'] | default(hostvars[host]['ansible_default_ipv4']['address']) }}:{{ kube_apiserver_port }}{% if not loop.last %},{% endif %}{% endfor %}"
|
||||
# The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces)
|
||||
KUBELET_ADDRESS="--address=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
|
||||
KUBELET_HOSTNAME="--hostname_override={{ inventory_hostname }}"
|
||||
{% if inventory_hostname in groups['kube-master'] and inventory_hostname not in groups['kube-node'] %}
|
||||
KUBELET_REGISTER_NODE="--register-node=false"
|
||||
{% endif %}
|
||||
# location of the api-server
|
||||
{% if dns_setup %}
|
||||
KUBELET_ARGS="--cluster_dns={{ dns_server }} --cluster_domain={{ dns_domain }} --kubeconfig={{ kube_config_dir}}/node-kubeconfig.yaml --config={{ kube_manifest_dir }}"
|
||||
{% else %}
|
||||
KUBELET_ARGS="--kubeconfig={{ kube_config_dir}}/kubelet.kubeconfig --config={{ kube_manifest_dir }}"
|
||||
{% endif %}
|
||||
{% if kube_network_plugin is defined and kube_network_plugin == "calico" %}
|
||||
KUBELET_NETWORK_PLUGIN="--network_plugin={{ kube_network_plugin }}"
|
||||
{% endif %}
|
||||
# Should this cluster be allowed to run privileged docker containers
|
||||
KUBE_ALLOW_PRIV="--allow_privileged=true"
|
||||
{% if init_system == "sysvinit" %}
|
||||
DAEMON_ARGS="$KUBE_LOGTOSTDERR $KUBE_LOG_LEVEL $KUBE_ALLOW_PRIV $KUBELET_API_SERVER $KUBELET_ADDRESS \
|
||||
$KUBELET_HOSTNAME $KUBELET_REGISTER_NODE $KUBELET_ARGS $KUBELET_ARGS $KUBELET_NETWORK_PLUGIN"
|
||||
{% endif %}
|
||||
@@ -0,0 +1,26 @@
|
||||
[Unit]
|
||||
Description=Kubernetes Kubelet Server
|
||||
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
|
||||
{% if kube_network_plugin is defined and kube_network_plugin == "calico" %}
|
||||
After=docker.service calico-node.service
|
||||
{% else %}
|
||||
After=docker.service
|
||||
{% endif %}
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=/etc/kubernetes/kubelet
|
||||
ExecStart={{ bin_dir }}/kubelet \
|
||||
$KUBE_LOGTOSTDERR \
|
||||
$KUBE_LOG_LEVEL \
|
||||
$KUBELET_API_SERVER \
|
||||
$KUBELET_ADDRESS \
|
||||
$KUBELET_PORT \
|
||||
$KUBELET_HOSTNAME \
|
||||
$KUBE_ALLOW_PRIV \
|
||||
$KUBELET_ARGS \
|
||||
$KUBELET_REGISTER_NODE \
|
||||
$KUBELET_NETWORK_PLUGIN
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,46 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: kube-proxy
|
||||
namespace: kube-system
|
||||
spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: kube-proxy
|
||||
image: {{ hyperkube_image_repo }}:{{ hyperkube_image_tag }}
|
||||
command:
|
||||
- /hyperkube
|
||||
- proxy
|
||||
- --v={{ kube_log_level | default('2') }}
|
||||
{% if inventory_hostname in groups['kube-master'] %}
|
||||
- --master=http://127.0.0.1:{{kube_apiserver_insecure_port}}
|
||||
{% else %}
|
||||
{% if loadbalancer_apiserver is defined and apiserver_loadbalancer_domain_name is defined %}
|
||||
- --master=https://{{ apiserver_loadbalancer_domain_name }}:{{ loadbalancer_apiserver.port }}
|
||||
{% else %}
|
||||
- --master=https://{{ hostvars[groups['kube-master'][0]]['ip'] | default(hostvars[groups['kube-master'][0]]['ansible_default_ipv4']['address']) }}:{{ kube_apiserver_port }}
|
||||
{% endif%}
|
||||
- --kubeconfig=/etc/kubernetes/node-kubeconfig.yaml
|
||||
{% endif %}
|
||||
securityContext:
|
||||
privileged: true
|
||||
volumeMounts:
|
||||
- mountPath: /etc/ssl/certs
|
||||
name: ssl-certs-host
|
||||
readOnly: true
|
||||
- mountPath: /etc/kubernetes/node-kubeconfig.yaml
|
||||
name: "kubeconfig"
|
||||
readOnly: true
|
||||
- mountPath: /etc/kubernetes/ssl
|
||||
name: "etc-kube-ssl"
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: ssl-certs-host
|
||||
hostPath:
|
||||
path: /usr/share/ca-certificates
|
||||
- name: "kubeconfig"
|
||||
hostPath:
|
||||
path: "/etc/kubernetes/node-kubeconfig.yaml"
|
||||
- name: "etc-kube-ssl"
|
||||
hostPath:
|
||||
path: "/etc/kubernetes/ssl"
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: v1
|
||||
kind: Config
|
||||
clusters:
|
||||
- name: local
|
||||
cluster:
|
||||
certificate-authority: {{ kube_cert_dir }}/ca.pem
|
||||
users:
|
||||
- name: kubelet
|
||||
user:
|
||||
client-certificate: {{ kube_cert_dir }}/node.pem
|
||||
client-key: {{ kube_cert_dir }}/node-key.pem
|
||||
contexts:
|
||||
- context:
|
||||
cluster: local
|
||||
user: kubelet
|
||||
name: kubelet-{{ cluster_name }}
|
||||
current-context: kubelet-{{ cluster_name }}
|
||||
@@ -0,0 +1,20 @@
|
||||
[req]
|
||||
req_extensions = v3_req
|
||||
distinguished_name = req_distinguished_name
|
||||
[req_distinguished_name]
|
||||
[ v3_req ]
|
||||
basicConstraints = CA:FALSE
|
||||
keyUsage = nonRepudiation, digitalSignature, keyEncipherment
|
||||
subjectAltName = @alt_names
|
||||
[alt_names]
|
||||
DNS.1 = kubernetes
|
||||
DNS.2 = kubernetes.default
|
||||
DNS.3 = kubernetes.default.svc.{{ dns_domain }}
|
||||
{% if loadbalancer_apiserver is defined and apiserver_loadbalancer_domain_name is defined %}
|
||||
DNS.4 = {{ apiserver_loadbalancer_domain_name }}
|
||||
{% endif %}
|
||||
{% for host in groups['kube-master'] %}
|
||||
IP.{{ loop.index }} = {{ hostvars[host]['ip'] | default(hostvars[host]['ansible_default_ipv4']['address']) }}
|
||||
{% endfor %}
|
||||
{% set idx = groups['kube-master'] | length | int + 1 %}
|
||||
IP.{{ idx | string }} = {{ kube_apiserver_ip }}
|
||||
@@ -0,0 +1,129 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# /etc/rc.d/init.d/kubelet
|
||||
#
|
||||
# chkconfig: 2345 95 95
|
||||
# description: Daemon for kubelet (kubernetes.io)
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: kubelet
|
||||
# Required-Start: $local_fs $network $syslog cgconfig
|
||||
# Required-Stop:
|
||||
# Should-Start:
|
||||
# Should-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: start and stop kubelet
|
||||
# Description:
|
||||
# The Kubernetes container manager maintains docker state against a state file.
|
||||
### END INIT INFO
|
||||
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
prog="kubelet"
|
||||
exec="{{ bin_dir }}/$prog"
|
||||
pidfile="/var/run/$prog.pid"
|
||||
lockfile="/var/lock/subsys/$prog"
|
||||
logfile="/var/log/$prog"
|
||||
|
||||
[ -e /etc/kubernetes/$prog ] && . /etc/kubernetes/$prog
|
||||
|
||||
start() {
|
||||
if [ ! -x $exec ]; then
|
||||
if [ ! -e $exec ]; then
|
||||
echo "Docker executable $exec not found"
|
||||
else
|
||||
echo "You do not have permission to execute the Docker executable $exec"
|
||||
fi
|
||||
exit 5
|
||||
fi
|
||||
|
||||
check_for_cleanup
|
||||
|
||||
if ! [ -f $pidfile ]; then
|
||||
printf "Starting $prog:\t"
|
||||
echo "\n$(date)\n" >> $logfile
|
||||
$exec $DAEMON_ARGS &>> $logfile &
|
||||
pid=$!
|
||||
echo $pid >> $pidfile
|
||||
touch $lockfile
|
||||
success
|
||||
echo
|
||||
else
|
||||
failure
|
||||
echo
|
||||
printf "$pidfile still exists...\n"
|
||||
exit 7
|
||||
fi
|
||||
}
|
||||
|
||||
stop() {
|
||||
echo -n $"Stopping $prog: "
|
||||
killproc -p $pidfile -d 300 $prog
|
||||
retval=$?
|
||||
echo
|
||||
[ $retval -eq 0 ] && rm -f $lockfile
|
||||
return $retval
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
reload() {
|
||||
restart
|
||||
}
|
||||
|
||||
force_reload() {
|
||||
restart
|
||||
}
|
||||
|
||||
rh_status() {
|
||||
status -p $pidfile $prog
|
||||
}
|
||||
|
||||
rh_status_q() {
|
||||
rh_status >/dev/null 2>&1
|
||||
}
|
||||
|
||||
|
||||
check_for_cleanup() {
|
||||
if [ -f ${pidfile} ]; then
|
||||
/bin/ps -fp $(cat ${pidfile}) > /dev/null || rm ${pidfile}
|
||||
fi
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
rh_status_q && exit 0
|
||||
$1
|
||||
;;
|
||||
stop)
|
||||
rh_status_q || exit 0
|
||||
$1
|
||||
;;
|
||||
restart)
|
||||
$1
|
||||
;;
|
||||
reload)
|
||||
rh_status_q || exit 7
|
||||
$1
|
||||
;;
|
||||
force-reload)
|
||||
force_reload
|
||||
;;
|
||||
status)
|
||||
rh_status
|
||||
;;
|
||||
condrestart|try-restart)
|
||||
rh_status_q || exit 0
|
||||
restart
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
|
||||
exit 2
|
||||
esac
|
||||
|
||||
exit $?
|
||||
@@ -0,0 +1,15 @@
|
||||
---
|
||||
common_required_pkgs:
|
||||
- python-httplib2
|
||||
- openssl
|
||||
- curl
|
||||
|
||||
debian_required_pkgs:
|
||||
- python-apt
|
||||
- python-pip
|
||||
|
||||
rh_required_pkgs:
|
||||
- libselinux-python
|
||||
|
||||
pypy_version: 2.4.0
|
||||
python_pypy_url: "https://bitbucket.org/pypy/pypy/downloads/pypy-{{ pypy_version }}.tar.bz2"
|
||||
@@ -0,0 +1,29 @@
|
||||
#/bin/bash
|
||||
set -e
|
||||
|
||||
BINDIR="/usr/local/bin"
|
||||
|
||||
cd $BINDIR
|
||||
|
||||
if [[ -e $BINDIR/.bootstrapped ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
PYPY_VERSION=2.4.0
|
||||
|
||||
wget -O - https://bitbucket.org/pypy/pypy/downloads/pypy-$PYPY_VERSION-linux64.tar.bz2 |tar -xjf -
|
||||
mv -n pypy-$PYPY_VERSION-linux64 pypy
|
||||
|
||||
## library fixup
|
||||
mkdir -p pypy/lib
|
||||
ln -snf /lib64/libncurses.so.5.9 $BINDIR/pypy/lib/libtinfo.so.5
|
||||
|
||||
cat > $BINDIR/python <<EOF
|
||||
#!/bin/bash
|
||||
LD_LIBRARY_PATH=$BINDIR/pypy/lib:$LD_LIBRARY_PATH exec $BINDIR/pypy/bin/pypy "\$@"
|
||||
EOF
|
||||
|
||||
chmod +x $BINDIR/python
|
||||
$BINDIR/python --version
|
||||
|
||||
touch $BINDIR/.bootstrapped
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
BINDIR="/usr/local/bin"
|
||||
LD_LIBRARY_PATH=$BINDIR/pypy/lib:$LD_LIBRARY_PATH $BINDIR/pypy/bin/$(basename $0) $@
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
- name: "Identify init system"
|
||||
shell: >
|
||||
$(pgrep systemd > /dev/null && systemctl status > /dev/null);
|
||||
if [ $? -eq 0 ] ; then
|
||||
echo systemd;
|
||||
else
|
||||
echo sysvinit;
|
||||
fi
|
||||
always_run: True
|
||||
register: init_system_output
|
||||
changed_when: False
|
||||
|
||||
- set_fact:
|
||||
init_system: "{{ init_system_output.stdout }}"
|
||||
|
||||
- name: Install packages requirements
|
||||
action:
|
||||
module: "{{ ansible_pkg_mgr }}"
|
||||
name: "{{ item }}"
|
||||
state: latest
|
||||
with_items: common_required_pkgs
|
||||
|
||||
- name: Install debian packages requirements
|
||||
apt:
|
||||
name: "{{ item }}"
|
||||
state: latest
|
||||
when: ansible_os_family == "Debian"
|
||||
with_items: debian_required_pkgs
|
||||
|
||||
- name: Install redhat packages requirements
|
||||
action:
|
||||
module: "{{ ansible_pkg_mgr }}"
|
||||
name: "{{ item }}"
|
||||
state: latest
|
||||
when: ansible_os_family == "RedHat"
|
||||
with_items: rh_required_pkgs
|
||||
|
||||
- include: python-bootstrap.yml
|
||||
when: ansible_os_family not in [ "Debian", "RedHat" ]
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
- name: Python | Check if bootstrap is needed
|
||||
raw: stat {{ bin_dir}}/.bootstrapped
|
||||
register: need_bootstrap
|
||||
ignore_errors: True
|
||||
|
||||
- name: Python | Run bootstrap.sh
|
||||
script: bootstrap.sh
|
||||
when: need_bootstrap | failed
|
||||
|
||||
- set_fact:
|
||||
ansible_python_interpreter: "{{ bin_dir }}/python"
|
||||
|
||||
- name: Python | Check if we need to install pip
|
||||
shell: "{{ansible_python_interpreter}} -m pip --version"
|
||||
register: need_pip
|
||||
ignore_errors: True
|
||||
changed_when: false
|
||||
when: need_bootstrap | failed
|
||||
|
||||
- name: Python | Copy get-pip.py
|
||||
copy: src=get-pip.py dest=~/get-pip.py
|
||||
when: need_pip | failed
|
||||
|
||||
- name: Python | Install pip
|
||||
shell: "{{ansible_python_interpreter}} ~/get-pip.py"
|
||||
when: need_pip | failed
|
||||
|
||||
- name: Python | Remove get-pip.py
|
||||
file: path=~/get-pip.py state=absent
|
||||
when: need_pip | failed
|
||||
|
||||
- name: Python | Install pip launcher
|
||||
copy: src=runner dest={{ bin_dir }}/pip mode=0755
|
||||
when: need_pip | failed
|
||||
|
||||
- name: Install required python modules
|
||||
pip:
|
||||
name: "{{ item }}"
|
||||
with_items: pip_python_modules
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
---
|
||||
- name : reload systemd
|
||||
shell: systemctl daemon-reload
|
||||
|
||||
- name: restart systemd-calico-node
|
||||
command: /bin/true
|
||||
notify:
|
||||
- reload systemd
|
||||
- restart calico-node
|
||||
|
||||
- name: restart calico-node
|
||||
service:
|
||||
name: calico-node
|
||||
state: restarted
|
||||
|
||||
- name: restart docker
|
||||
service: name=docker state=restarted
|
||||
|
||||
- name: restart flannel
|
||||
service: name=flannel state=restarted
|
||||
notify:
|
||||
- reload systemd
|
||||
- stop docker
|
||||
- delete docker0
|
||||
- start docker
|
||||
when: inventory_hostname in groups['kube-node']
|
||||
|
||||
- name: stop docker
|
||||
service: name=docker state=stopped
|
||||
|
||||
- name: delete docker0
|
||||
command: ip link delete docker0
|
||||
ignore_errors: yes
|
||||
|
||||
- name: start docker
|
||||
service: name=docker state=started
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
|
||||
- name: Calico | Install calicoctl bin
|
||||
synchronize:
|
||||
src: "{{ local_release_dir }}/calico/bin/calicoctl"
|
||||
dest: "{{ bin_dir }}/calicoctl"
|
||||
archive: no
|
||||
times: yes
|
||||
delegate_to: "{{ groups['downloader'][0] }}"
|
||||
notify: restart calico-node
|
||||
|
||||
- name: Calico | install calicoctl
|
||||
file: path={{ bin_dir }}/calicoctl mode=0755 state=file
|
||||
|
||||
- name: Calico | Create calicoctl symlink (needed by kubelet)
|
||||
file:
|
||||
src: /usr/local/bin/calicoctl
|
||||
dest: /usr/bin/calicoctl
|
||||
state: link
|
||||
|
||||
- name: Calico | Check if calico network pool has already been configured
|
||||
uri:
|
||||
url: "http://127.0.0.1:2379/v2/keys/calico/v1/ipam/v4/pool"
|
||||
return_content: yes
|
||||
status_code: 200,404
|
||||
register: calico_conf
|
||||
run_once: true
|
||||
delegate_to: "{{ groups['etcd'][0] }}"
|
||||
|
||||
- name: Calico | Configure calico network pool
|
||||
shell: calicoctl pool add {{ kube_pods_subnet }}
|
||||
run_once: true
|
||||
when: calico_conf.status == 404
|
||||
delegate_to: "{{ groups['etcd'][0] }}"
|
||||
|
||||
- name: Calico | Get calico configuration from etcd
|
||||
uri:
|
||||
url: "http://127.0.0.1:2379/v2/keys/calico/v1/ipam/v4/pool"
|
||||
return_content: yes
|
||||
register: calico_pools
|
||||
run_once: true
|
||||
delegate_to: "{{ groups['etcd'][0] }}"
|
||||
|
||||
- name: Calico | Check if calico pool is properly configured
|
||||
fail:
|
||||
msg: 'Only one network pool must be configured and it must be the subnet {{ kube_pods_subnet }}.
|
||||
Please erase calico configuration and run the playbook again ("etcdctl rm --recursive /calico/v1/ipam/v4/pool")'
|
||||
when: ( calico_pools.json['node']['nodes'] | length > 1 ) or
|
||||
( not calico_pools.json['node']['nodes'][0]['key'] | search(".*{{ kube_pods_subnet | ipaddr('network') }}.*") )
|
||||
run_once: true
|
||||
delegate_to: "{{ groups['etcd'][0] }}"
|
||||
|
||||
- name: Calico | Write calico-node configuration
|
||||
template: src=calico/calico.conf.j2 dest=/usr/libexec/kubernetes/kubelet-plugins/net/exec/calico/calico_kubernetes.ini
|
||||
notify: restart calico-node
|
||||
|
||||
- name: Calico | Write calico-node systemd init file
|
||||
template: src=calico/calico-node.service.j2 dest=/etc/systemd/system/calico-node.service
|
||||
when: init_system == "systemd"
|
||||
notify: restart systemd-calico-node
|
||||
|
||||
- name: Calico | Write calico-node initd script
|
||||
template: src=calico/deb-calico.initd.j2 dest=/etc/init.d/calico-node owner=root mode=755
|
||||
when: init_system == "sysvinit" and ansible_os_family == "Debian"
|
||||
notify: restart calico-node
|
||||
|
||||
- name: Calico | Write calico-node initd script
|
||||
template: src=calico/rh-calico.initd.j2 dest=/etc/init.d/calico-node owner=root mode=755
|
||||
when: init_system == "sysvinit" and ansible_os_family == "RedHat"
|
||||
notify: restart calico-node
|
||||
|
||||
- name: Calico | Enable calico-node
|
||||
service: name=calico-node enabled=yes state=started
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
- name: Create flannel user
|
||||
user: name=flannel shell=/bin/nologin
|
||||
|
||||
- name: Install flannel binaries
|
||||
synchronize:
|
||||
src: "{{ local_release_dir }}/flannel/bin/flanneld"
|
||||
dest: "{{ bin_dir }}/flanneld"
|
||||
archive: no
|
||||
times: yes
|
||||
delegate_to: "{{ groups['downloader'][0] }}"
|
||||
notify:
|
||||
- restart flannel
|
||||
|
||||
- name: Perms flannel binary
|
||||
file: path={{ bin_dir }}/flanneld owner=flannel mode=0755 state=file
|
||||
|
||||
- name: Write flannel.service systemd file
|
||||
template:
|
||||
src: flannel/systemd-flannel.service.j2
|
||||
dest: /etc/systemd/system/flannel.service
|
||||
notify: restart flannel
|
||||
|
||||
- name: Write docker.service systemd file
|
||||
template:
|
||||
src: flannel/systemd-docker.service.j2
|
||||
dest: /lib/systemd/system/docker.service
|
||||
notify: restart docker
|
||||
|
||||
- name: Set fact for ectcd command conf file location
|
||||
set_fact:
|
||||
conf_file: "/tmp/flannel-conf.json"
|
||||
run_once: true
|
||||
delegate_to: "{{ groups['kube-master'][0] }}"
|
||||
|
||||
- name: Create flannel config file to go in etcd
|
||||
template: src=flannel/flannel-conf.json.j2 dest={{ conf_file }}
|
||||
run_once: true
|
||||
delegate_to: "{{ groups['kube-master'][0] }}"
|
||||
|
||||
- name: Flannel configuration into etcd
|
||||
shell: "{{ bin_dir }}/etcdctl set /{{ cluster_name }}/network/config < {{ conf_file }}"
|
||||
delegate_to: "{{ groups['kube-master'][0] }}"
|
||||
notify: restart flannel
|
||||
|
||||
- name: Clean up the flannel config file
|
||||
file: path=/tmp/flannel-config.json state=absent
|
||||
run_once: true
|
||||
delegate_to: "{{ groups['kube-master'][0] }}"
|
||||
|
||||
- name: Launch Flannel
|
||||
service: name=flannel state=started enabled=yes
|
||||
notify:
|
||||
- restart flannel
|
||||
|
||||
- name: Enable Docker
|
||||
service: name=docker enabled=yes state=started
|
||||
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: "Test if network plugin is defined"
|
||||
fail: msg="ERROR, One network_plugin variable must be defined (Flannel or Calico)"
|
||||
when: ( kube_network_plugin is defined and kube_network_plugin == "calico" and kube_network_plugin == "flannel" ) or
|
||||
kube_network_plugin is not defined
|
||||
|
||||
- include: flannel.yml
|
||||
when: kube_network_plugin == "flannel"
|
||||
|
||||
- include: calico.yml
|
||||
when: kube_network_plugin == "calico"
|
||||
|
||||
- meta: flush_handlers
|
||||
@@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=Calico per-node agent
|
||||
Documentation=https://github.com/projectcalico/calico-docker
|
||||
Requires=docker.service
|
||||
After=docker.service etcd2.service
|
||||
|
||||
[Service]
|
||||
User=root
|
||||
PermissionsStartOnly=true
|
||||
{% if inventory_hostname in groups['kube-node'] and peer_with_router|default(false)%}
|
||||
ExecStart={{ bin_dir }}/calicoctl node --kubernetes --ip={{ip | default(ansible_default_ipv4.address) }} --as={{ local_as }} --detach=false
|
||||
{% else %}
|
||||
ExecStart={{ bin_dir }}/calicoctl node --kubernetes --ip={{ip | default(ansible_default_ipv4.address) }} --detach=false
|
||||
{% endif %}
|
||||
Restart=always
|
||||
Restart=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,17 @@
|
||||
[config]
|
||||
CALICO_IPAM=true
|
||||
|
||||
# Location of etcd cluster used by Calico. By default, this uses the etcd
|
||||
# instance running on the Kubernetes Master
|
||||
ETCD_AUTHORITY=127.0.0.1:2379
|
||||
|
||||
# The kubernetes-apiserver location - used by the calico plugin
|
||||
{% if loadbalancer_apiserver is defined and apiserver_loadbalancer_domain_name is defined %}
|
||||
KUBE_API_ROOT=https://{{ apiserver_loadbalancer_domain_name }}:{{ loadbalancer_apiserver.port }}/api/v1/
|
||||
{% else %}
|
||||
KUBE_API_ROOT=https://{{ hostvars[groups['kube-master'][0]]['ip'] | default(hostvars[groups['kube-master'][0]]['ansible_default_ipv4']['address']) }}:{{kube_apiserver_port}}/api/v1/
|
||||
{% endif %}
|
||||
# Kubernetes authentication token
|
||||
{% if calico_token is defined | default('') %}
|
||||
KUBE_AUTH_TOKEN={{ calico_token.content|b64decode }}
|
||||
{% endif %}
|
||||
@@ -0,0 +1,114 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
### BEGIN INIT INFO
|
||||
# Provides: calico-node
|
||||
# Required-Start: $local_fs $network $syslog
|
||||
# Required-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: Calico docker container
|
||||
# Description:
|
||||
# Runs calico as a docker container
|
||||
### END INIT INFO
|
||||
|
||||
PATH=/sbin:/usr/sbin:/bin:/usr/bin
|
||||
DESC="Calico-node Docker"
|
||||
NAME=calico-node
|
||||
DAEMON={{ bin_dir }}/calicoctl
|
||||
DAEMON_ARGS=""
|
||||
DOCKER=$(which docker)
|
||||
SCRIPTNAME=/etc/init.d/$NAME
|
||||
DAEMON_USER=root
|
||||
|
||||
# Exit if the binary is not present
|
||||
[ -x "$DAEMON" ] || exit 0
|
||||
|
||||
# Exit if the docker package is not installed
|
||||
[ -x "$DOCKER" ] || exit 0
|
||||
|
||||
# Read configuration variable file if it is present
|
||||
[ -r /etc/network-environment ] && . /etc/network-environment
|
||||
|
||||
# Define LSB log_* functions.
|
||||
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
|
||||
# and status_of_proc is working.
|
||||
. /lib/lsb/init-functions
|
||||
|
||||
do_status()
|
||||
{
|
||||
if [ $($DOCKER ps | awk '{ print $2 }' | grep calico/node | wc -l) -eq 1 ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Function that starts the daemon/service
|
||||
#
|
||||
do_start()
|
||||
{
|
||||
do_status
|
||||
retval=$?
|
||||
if [ $retval -ne 0 ]; then
|
||||
${DAEMON} node --ip=${DEFAULT_IPV4} >>/dev/null && return 0 || return 2
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Function that stops the daemon/service
|
||||
#
|
||||
do_stop()
|
||||
{
|
||||
${DAEMON} node stop >> /dev/null || ${DAEMON} node stop --force >> /dev/null
|
||||
}
|
||||
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
log_daemon_msg "Starting $DESC" "$NAME"
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) log_end_msg 0 || exit 0 ;;
|
||||
2) log_end_msg 1 || exit 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
log_daemon_msg "Stopping $DESC" "$NAME"
|
||||
if do_stop; then
|
||||
log_end_msg 0
|
||||
else
|
||||
log_failure_msg "Can't stop calico-node"
|
||||
log_end_msg 1
|
||||
fi
|
||||
;;
|
||||
status)
|
||||
if do_status; then
|
||||
log_end_msg 0
|
||||
else
|
||||
log_failure_msg "Calico-node is not running"
|
||||
log_end_msg 1
|
||||
fi
|
||||
;;
|
||||
|
||||
restart|force-reload)
|
||||
log_daemon_msg "Restarting $DESC" "$NAME"
|
||||
if do_stop; then
|
||||
if do_start; then
|
||||
log_end_msg 0
|
||||
exit 0
|
||||
else
|
||||
rc="$?"
|
||||
fi
|
||||
else
|
||||
rc="$?"
|
||||
fi
|
||||
log_failure_msg "Can't restart Calico-node"
|
||||
log_end_msg ${rc}
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
|
||||
exit 3
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,130 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# /etc/rc.d/init.d/calico-node
|
||||
#
|
||||
# chkconfig: 2345 95 95
|
||||
# description: Daemon for calico-node (http://www.projectcalico.org/)
|
||||
|
||||
### BEGIN INIT INFO
|
||||
# Provides: calico-node
|
||||
# Required-Start: $local_fs $network $syslog cgconfig
|
||||
# Required-Stop:
|
||||
# Should-Start:
|
||||
# Should-Stop:
|
||||
# Default-Start: 2 3 4 5
|
||||
# Default-Stop: 0 1 6
|
||||
# Short-Description: start and stop calico-node
|
||||
# Description:
|
||||
# Manage calico-docker container
|
||||
### END INIT INFO
|
||||
|
||||
# Source function library.
|
||||
. /etc/rc.d/init.d/functions
|
||||
|
||||
prog="calicoctl"
|
||||
exec="{{ bin_dir }}/$prog"
|
||||
dockerexec="$(which docker)"
|
||||
logfile="/var/log/$prog"
|
||||
|
||||
[ -e /etc/network-environment ] && for i in $(cat /etc/network-environment | egrep '(^$|^#)'); do export $i; done
|
||||
|
||||
do_status()
|
||||
{
|
||||
if [ $($dockerexec ps | awk '{ print $2 }' | grep calico/node | wc -l) -ne 1 ]; then
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
do_start() {
|
||||
if [ ! -x $exec ]; then
|
||||
if [ ! -e $exec ]; then
|
||||
echo "calico-node executable $exec not found"
|
||||
else
|
||||
echo "You do not have permission to execute the calico-node executable $exec"
|
||||
fi
|
||||
exit 5
|
||||
fi
|
||||
|
||||
[ -x "$dockerexec" ] || exit 0
|
||||
|
||||
do_status
|
||||
retval=$?
|
||||
if [ $retval -ne 0 ]; then
|
||||
printf "Starting $prog:\t"
|
||||
echo "\n$(date)\n" >> $logfile
|
||||
$exec node --ip=${DEFAULT_IPV4} &>>$logfile
|
||||
success
|
||||
echo
|
||||
else
|
||||
echo -n "calico-node's already running"
|
||||
success
|
||||
exit 0
|
||||
fi
|
||||
}
|
||||
|
||||
do_stop() {
|
||||
echo -n $"Stopping $prog: "
|
||||
$exec node stop >> /dev/null || $exec node stop --force >> /dev/null
|
||||
retval=$?
|
||||
echo
|
||||
return $retval
|
||||
}
|
||||
|
||||
restart() {
|
||||
do_stop
|
||||
do_start
|
||||
}
|
||||
|
||||
reload() {
|
||||
restart
|
||||
}
|
||||
|
||||
force_reload() {
|
||||
restart
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
start)
|
||||
do_start
|
||||
case "$?" in
|
||||
0|1) success || exit 0 ;;
|
||||
2) failure || exit 1 ;;
|
||||
esac
|
||||
;;
|
||||
stop)
|
||||
echo -n "Stopping $DESC" "$NAME"
|
||||
if do_stop; then
|
||||
success
|
||||
echo
|
||||
else
|
||||
echo -n "Can't stop calico-node"
|
||||
failure
|
||||
echo
|
||||
fi
|
||||
;;
|
||||
restart)
|
||||
$1
|
||||
;;
|
||||
reload)
|
||||
$1
|
||||
;;
|
||||
force-reload)
|
||||
force_reload
|
||||
;;
|
||||
status)
|
||||
if do_status; then
|
||||
echo -n "Calico-node is running"
|
||||
success
|
||||
echo
|
||||
else
|
||||
echo -n "Calico-node is not running"
|
||||
failure
|
||||
echo
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo $"Usage: $0 {start|stop|status|restart|reload|force-reload}"
|
||||
exit 2
|
||||
esac
|
||||
|
||||
exit $?
|
||||
@@ -0,0 +1 @@
|
||||
{ "Network": "{{ kube_service_addresses }}", "SubnetLen": {{ kube_network_node_prefix }}, "Backend": { "Type": "vxlan" } }
|
||||
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=Docker Application Container Engine
|
||||
Documentation=http://docs.docker.com
|
||||
After=network.target docker.socket flannel.service
|
||||
Requires=docker.socket
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=/run/flannel/subnet.env
|
||||
EnvironmentFile=-/etc/default/docker
|
||||
ExecStart=/usr/bin/docker -d -H fd:// --bip=${FLANNEL_SUBNET} --mtu=${FLANNEL_MTU} $DOCKER_OPTS
|
||||
MountFlags=slave
|
||||
LimitNOFILE=1048576
|
||||
LimitNPROC=1048576
|
||||
LimitCORE=infinity
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,12 @@
|
||||
[Unit]
|
||||
Description=Flannel Network Overlay
|
||||
Documentation=https://coreos.com/flannel/docs/latest
|
||||
|
||||
[Service]
|
||||
EnvironmentFile=/etc/network-environment
|
||||
ExecStart={{ bin_dir }}/flanneld \
|
||||
$FLANNEL_ETCD_PREFIX
|
||||
Restart=on-failure
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -1,5 +0,0 @@
|
||||
#!/bin/bash
|
||||
mkdir -p ssh
|
||||
if ! [ -f ssh/id_rsa ] ; then
|
||||
ssh-keygen -N '' -t rsa -f ssh/id_rsa && cp ssh/id_rsa.pub ssh/authorized_keys
|
||||
fi
|
||||
Reference in New Issue
Block a user