Compare commits

...

182 Commits
1.3.0 ... 1.5.0

Author SHA1 Message Date
f49926413a Merge pull request #176 from kubespray/kubernetes-v1.2.0
Kubernetes v1.2.0
2016-03-22 13:52:37 +01:00
e8aec5f4f0 Don't call the apiserver when the server is master only 2016-03-22 13:25:41 +01:00
c51ed4bbb7 use master election option instead of podmaster 2016-03-21 22:25:09 +01:00
ba4ad51c26 add aufs-tools package for debian 2016-03-21 17:25:14 +01:00
785b84fd43 Upgrade to docker 1.10.3 2016-03-21 16:54:14 +01:00
15ce66b2f5 Kubernetes 1.2.0 2016-03-21 16:54:14 +01:00
9949c2b34e Merge pull request #181 from Smana/fix_dnsmasq_as_ds
Dnsmasq runs on all nodes
2016-03-21 11:38:04 +01:00
7e6d7caf4b Dnsmasq runs on all nodes 2016-03-21 11:37:35 +01:00
48c64a1f72 Merge pull request #179 from kubespray/dnsmasq_ds
Dnsmasq ds
2016-03-20 00:08:33 +01:00
6297e5ea93 Use dnsmasq inside pods 2016-03-19 23:41:27 +01:00
0c315e0ff4 Merge pull request #174 from jcsirot/jenkins_pipeline
Move common groovy test code for jenkins into git repo and add test r…
2016-03-15 17:30:09 +01:00
b7fcabea7b Merge pull request #175 from Smana/update_ansible_galaxy
update requirements.yml with the new gitlab url
2016-03-15 16:16:39 +01:00
999141f0fd update requirements.yml with the new gitlab url 2016-03-15 16:15:23 +01:00
f5f6e44369 Move common groovy test code for jenkins into git repo and add test result matrix 2016-03-10 22:45:54 +01:00
0c2183c10a Merge pull request #173 from Smana/redirect_to_docs
redirecting to new doc page
2016-03-07 16:21:25 +01:00
cd38ecc378 redirecting to new doc page 2016-03-07 16:15:40 +01:00
1771f18437 Merge pull request #171 from kubespray/uploads_bin
Uploads bin
2016-03-04 19:33:56 +01:00
72807965a8 Upload files to a separate storage 2016-03-04 17:39:02 +01:00
611c7744a1 Remove submodules 2016-03-04 16:14:01 +01:00
9baf9e569b Merge pull request #169 from kubespray/flannel_backend_option
flannel backend type option
2016-03-04 16:08:38 +01:00
ede3aad2ab flannel backend type option 2016-03-04 14:55:04 +01:00
143a75ccde Merge pull request #167 from kubespray/upgrade_calico_v0.17.0
upgrade calicoctl to v0.17.0
2016-03-02 11:56:44 +01:00
62218c1497 upgrade calicoctl to v0.17.0 2016-03-02 10:42:31 +01:00
8a238cda3d Create LICENSE 2016-03-01 15:37:01 +01:00
706d8c7968 Merge pull request #165 from kubespray/option_proxy_mode
adding option --proxy-mode for kubeproxy
2016-02-29 11:42:18 +01:00
cb3cc6f523 adding option --proxy-mode for kubeproxy 2016-02-29 11:41:08 +01:00
87fd8415da Merge pull request #163 from Smana/upgrade_kube_v1.1.8
Upgrade kuberenetes to v1.1.8
2016-02-26 23:25:00 +01:00
9528caa1d7 Upgrade kuberenetes to v1.1.8 2016-02-25 17:35:38 +01:00
3f32e5973f Merge pull request #158 from Smana/calico_nat_outgoing_opt
calico: enabling nat outgoing by default
2016-02-24 12:11:34 +01:00
a17e466a29 Merge pull request #162 from oneswig/master
On CoreOS, /etc/hosts does not always exist.
2016-02-23 14:27:07 +01:00
ff03c82151 On CoreOS, /etc/hosts does not always exist. 2016-02-23 12:04:58 +00:00
152c409022 calico: enabling nat outgoing by default 2016-02-21 17:11:49 +01:00
a46d4efba6 Merge pull request #156 from Smana/coreos_support
CoreOS support (Calico, Flannel, Weave)
2016-02-21 14:10:14 +01:00
fca384e24c first version of CoreOS on GCE
Please enter the commit message for your changes. Lines starting
2016-02-21 00:06:36 +01:00
ec64eda2bc Merge pull request #152 from rsmitty/issue-151
confirmed working change to mktemp command
2016-02-18 22:12:38 +01:00
20adb604cc confirmed working change to mktemp command 2016-02-18 15:56:10 -05:00
57a1ce28c4 Merge pull request #150 from Smana/update_hyperkube_version
update hyperkube version
2016-02-18 16:40:21 +01:00
39caf94790 update hyperkube version 2016-02-18 16:38:25 +01:00
ba4c89a12e Merge pull request #149 from Smana/upgrade_calico_etcd
Upgrade Calico and etcd
2016-02-15 15:31:32 +01:00
b013b125bc Upgrade Calico and etcd 2016-02-15 12:41:27 +01:00
e786010584 Merge pull request #147 from kubespray/upgrade_kube_1.1.7
upgrade kubernetes to 1.1.7
2016-02-15 12:12:17 +01:00
01397678df upgrade kubernetes to 1.1.7 2016-02-15 10:57:45 +01:00
fae77970ac Allow to fail calico/trusty 2016-02-13 20:55:10 +01:00
e737ed8105 Merge pull request #146 from kubespray/rollback_docker_1.9
Rollback docker 1.9
2016-02-13 18:34:55 +01:00
b2dd01a0b0 Merge pull request #145 from jcsirot/jenkins
Jenkins
2016-02-13 18:03:29 +01:00
323ff78206 Update playbooks for automatic deployment tests 2016-02-13 17:57:10 +01:00
8659693c76 fix testcases 2016-02-13 17:29:41 +01:00
c3a8f379e8 rollback to docker 1.9 2016-02-13 15:38:42 +01:00
ad18f229c5 Merge pull request #143 from Smana/tests_kubectl_path
change tests, full path of kubectl binary
2016-02-13 14:58:46 +01:00
2feac2956a change tests, full path of kubectl binary 2016-02-13 14:47:53 +01:00
60d6195a9e Merge pull request #142 from kubespray/use_ansible_service_mgr
use ansible_service_mgr to detect init system
2016-02-13 14:30:04 +01:00
c0cf506fb4 install epel-release on RHEL7 2016-02-13 13:15:08 +01:00
a649aa8b7e use ansible_service_mgr to detect init system 2016-02-13 11:46:53 +01:00
7fef64dacd Merge pull request #140 from kubespray/secret_from_localhost
generate secrets on deployment machine
2016-02-13 07:27:56 +01:00
91fca69aa0 generate secrets on deployment machine
test travis with sudo=true instead of required
2016-02-13 06:51:54 +01:00
3fef552978 Docker 1.10.1 2016-02-13 06:19:47 +01:00
50364ab571 Merge pull request #141 from ntfrnzn/pin-docker-version
pin docker versions to 1.9 or earlier
2016-02-13 00:07:42 +01:00
a4e32c748a pin docker version actually 2016-02-12 14:45:09 -08:00
c48bc34a34 pin docker versions to 1.9 or earlier 2016-02-12 14:40:13 -08:00
451ee18c4a Merge pull request #138 from kubespray/integration_tests
Integration tests
2016-02-11 14:00:09 +01:00
4ee3699933 Add weave to tests 2016-02-11 10:57:54 +01:00
caa2555b1d Add complete test integration 2016-02-10 22:58:57 +01:00
09851621de Merge pull request #133 from Smana/weave_network_plugin
weave network plugin
2016-02-10 18:39:48 +01:00
05c8a29688 Merge branch 'master' into weave_network_plugin 2016-02-10 18:33:48 +01:00
793d665db4 specify weave version 2016-02-10 18:19:03 +01:00
50da691d45 Merge pull request #134 from rackn/kubeproxy-bind-local
Force kube-proxy to bind to local address
2016-02-10 18:05:50 +01:00
6f1fe0cda2 Force kube-proxy to bind to local address 2016-02-10 10:53:22 -06:00
ab007e4ab8 weave network plugin 2016-02-09 17:55:12 +01:00
03dd43e97d Merge pull request #132 from Smana/net_plugins_distinct_roles
split network plugins into distinct roles
2016-02-09 16:10:15 +01:00
4f92417a5d split network plugins into distinct roles 2016-02-09 11:42:00 +01:00
3016ab79cb Merge pull request #129 from Smana/fedora_23_compat
fix some issues with fedora 23 and dnf
2016-02-04 12:11:51 +01:00
b2d6626363 fix some issues with fedora 23 and dnf 2016-02-03 21:26:49 +01:00
98e2d6957a Merge pull request #128 from ansibl8s/fix_calico_initd_ip
calico uses --ip option
2016-02-01 16:32:19 +01:00
779299de15 calico uses --ip option 2016-02-01 15:53:23 +01:00
bf5582b01f Merge pull request #127 from ansibl8s/increase_timeout
Increase liveness timeout
2016-02-01 14:53:48 +01:00
7e94d31c8b Merge branch 'master' into increase_timeout 2016-02-01 14:32:25 +01:00
896f59267a Merge pull request #126 from ansibl8s/calico_nat_outgoing
add option '--nat-outgoing' for calico on clouds
2016-02-01 14:32:13 +01:00
21b0a3649d Increase liveness timeout 2016-02-01 13:41:49 +01:00
3bb6066558 add option '--nat-outgoing' for calico on clouds 2016-02-01 10:47:34 +01:00
64be24dd20 Merge pull request #123 from Smana/install_epel_rhel
install epel release for rhel
2016-02-01 10:46:10 +01:00
f8ffe53709 Merge pull request #124 from rackn/centos-fixes
Update docker for CentOS issues in AWS and general variables
2016-01-31 22:33:02 +01:00
4d3f6c6533 install epel release for rhel
install required packages before common

roles/kubernetes/preinstall/tasks/main.yml
2016-01-31 22:12:34 +01:00
6163fe166e Update docker for CentOS issues in AWS and general
variables.

1. AWS has issues with ext4 (use xfs instead for CentOS only)
2. Make sure all the centos config files are include in the systemd config
3. Make sure that network options are set in the correct file by os family

This allows downstream items like opencontrail and others change variables
in expected locations.
2016-01-30 21:46:32 -06:00
6eff3f0fce Merge pull request #120 from Smana/fix_etcd_initd
etcd initd startup command fix
2016-01-30 22:42:13 +01:00
6358cf788f etcd initd startup command fix 2016-01-30 22:31:41 +01:00
6915278f65 Merge pull request #118 from ansibl8s/calico
Change calico condition --ipip
2016-01-29 15:51:17 +01:00
b33713da4a Change calico condition --ipip 2016-01-29 14:07:21 +01:00
83c1bd516d Update calico.yml 2016-01-29 12:23:29 +01:00
5d24cabc83 Merge pull request #116 from ansibl8s/calico_on_cloud
Add --ipip to calico if on cloud_proivder
2016-01-28 20:28:15 +01:00
7127e6de54 Add --ipip to calico if on cloud_proivder 2016-01-28 20:13:50 +01:00
cea8f1d381 Merge pull request #109 from rackn/awsify
Add variables and defaults for multiple types of ip addresses.
2016-01-28 14:47:27 +01:00
bedcca922c Add variables and defaults for multiple types of ip addresses.
Each node can have 3 IPs.
1. ansible_default_ip4 - whatever ansible things is the first IPv4 address
   usually with the default gw.
2. ip - An address to use on the local node to bind listeners and do local
   communication.  For example, Vagrant boxes have a first address that is the
   NAT bridge and is common for all nodes.  The second address/interface should
   be used.
3. access_ip - An address to use for node-to-node access.  This is assumed to
   be used by other nodes to access the node and may not be actually assigned
   on the node.  For example, AWS public ip that is not assigned to node.

This updates the places addresses are used to use either ip or access_ip and walk
up the list to find an address.
2016-01-27 16:05:39 -06:00
faf50ea698 Merge pull request #111 from Smana/flannel_pods_subnet
use 'kube_pods_subnet' var for flannel conf
2016-01-27 22:14:20 +01:00
a323335d36 use 'kube_pods_subnet' var for flannel conf 2016-01-27 22:00:12 +01:00
f15dda0248 Merge pull request #110 from Smana/updatedoc
update submodules and documentation
2016-01-27 17:42:52 +01:00
8d71d56809 update submodules and documentation 2016-01-27 17:02:41 +01:00
cf472a6b4c Merge pull request #107 from ansibl8s/race_condition_api_master
Slowdown apimaster restart
2016-01-26 18:00:47 +01:00
fd6ac61afc Use local etcd/etcdproxy for calico 2016-01-26 17:28:30 +01:00
16a1926f94 Drop ansible 1.9 support 2016-01-26 15:31:11 +01:00
839974bad0 Merge pull request #108 from ansibl8s/set_perms_on_unarchive
Set perms on unarchive
2016-01-26 15:25:28 +01:00
4566d60e6f Slowdown apimaster restart 2016-01-26 15:23:16 +01:00
49a7278563 Set perms on unarchive 2016-01-26 12:17:33 +01:00
8676f8761f Merge pull request #99 from ansibl8s/symlink-dnsmasq-conf
Symlink dnsmasq conf
2016-01-26 00:44:13 +01:00
b9781fa7c2 Symlink dnsmasq conf 2016-01-26 00:30:29 +01:00
08052f60da Merge pull request #105 from ansibl8s/fix_handlers
fix some handlers
2016-01-25 23:00:07 +01:00
44230a4e86 Merge pull request #101 from galthaus/patch-1
Fix download reference in cluster.ml
2016-01-25 22:56:48 +01:00
90ffb8489a fix some handlers 2016-01-25 22:49:24 +01:00
238f6e8a0b Remove apt-get update 2016-01-25 22:46:20 +01:00
ef7cf3bf11 Merge pull request #103 from rackn/perm-fix
Force owner and permissions for get_url retrieved files.
2016-01-25 22:01:57 +01:00
e7d5b7af67 Force owner and permissions for get_url retrieved
files.  get_url doesn't honor owner and mode is spotty.
2016-01-25 13:30:48 -06:00
359e55f6e4 Merge pull request #100 from rackn/cache-update-centos
Need to use separate stanzas for each repo because the
2016-01-25 19:00:57 +01:00
dd29c8064f Fix download reference in cluster.ml 2016-01-25 11:23:55 -06:00
c7bd2a2a1e Need to use separate stanzas for each repo because the
args are different.  Sigh.
2016-01-25 11:16:56 -06:00
87fa167efa Merge pull request #95 from Smana/fix_ha_apiserver
workaround_ha_apiserver
2016-01-25 13:01:03 +01:00
baaa6efc2b workaround_ha_apiserver 2016-01-25 12:07:32 +01:00
cece179bd4 Merge pull request #97 from ansibl8s/systemd_reload
Fix systemd reload and calico unit
2016-01-25 11:01:11 +01:00
56b92812fa Fix systemd reload and calico unit 2016-01-25 10:54:07 +01:00
2cbbcee351 Merge pull request #98 from ansibl8s/setup_cache
Use update_cache when possible
2016-01-25 02:12:19 +01:00
f5508b1794 Use update_cache when possible 2016-01-25 02:06:34 +01:00
8f7d552401 Merge pull request #93 from ansibl8s/flannel-info
Add flannel vars to enable vagrant and amazon environments
2016-01-24 16:46:04 +01:00
bcd6ecb7fb Add flannel vars to enable vagrant and amazon environments 2016-01-24 16:18:35 +01:00
65666fc28a Merge pull request #90 from ansibl8s/add_users_role
AddUser Role
2016-01-24 16:17:24 +01:00
b4734c280a Merge branch 'master' into add_users_role 2016-01-24 15:58:10 +01:00
dd61f685b8 AddUser Role 2016-01-24 11:54:34 +01:00
641ce3358a Merge pull request #91 from Smana/rsync_instead_of_copy
use rsync instead of cp
2016-01-23 23:38:42 +01:00
4984b57aa2 use rsync instead of command 2016-01-23 18:26:07 +01:00
87d8d87c6e Merge pull request #87 from Smana/apiserver_on_host
Apiserver on host
2016-01-23 17:46:23 +01:00
283c4169ac run apiserver as a service
reorder master handlers

typo for sysvinit
2016-01-23 14:21:04 +01:00
d5f11b2442 Merge pull request #88 from Smana/complete_remove_downloader
missing commits for the PR #86
2016-01-22 17:25:12 +01:00
5edc81c627 moving kube-cert group into group_vars 2016-01-22 17:18:45 +01:00
391413f7e7 missing commits for the PR #86 2016-01-22 17:10:31 +01:00
c05c60a5d2 Merge pull request #86 from ansibl8s/remove_downloader
Remove downloader host
2016-01-22 17:04:54 +01:00
87b42e34e0 create kube-cert group task 2016-01-22 16:51:54 +01:00
be0bec9eab add kube-cert group 2016-01-22 16:46:06 +01:00
cb59559835 use command instead of synchronize 2016-01-22 16:37:07 +01:00
078b67c50f Remove downloader host 2016-01-22 09:59:39 +01:00
e95c4739f5 Merge pull request #82 from rackn/etcd-sync
Fix etcd synchronize to other nodes from the downloader
2016-01-21 20:39:52 +01:00
32877bdc7b Merge branch 'master' into etcd-sync 2016-01-21 13:13:58 -06:00
5e3af86c26 Merge pull request #84 from rackn/init-system-fix
Test for a systemd service that should be up.
2016-01-21 20:07:47 +01:00
ec1073def8 Test for a systemd service that should be up. 2016-01-21 11:35:15 -06:00
28e530e005 Fix etcd synchronize to other nodes from the downloader 2016-01-21 11:21:25 -06:00
9e9aba4e3a Merge pull request #79 from Smana/gitinfo
script which gives info about the deployment state
2016-01-21 13:49:11 +01:00
de038530ef don't run gitinfos by default 2016-01-21 13:41:01 +01:00
337977e868 script which gives info about the deployment state
fix script location
2016-01-21 13:41:01 +01:00
1c2bdbacb1 Merge pull request #72 from Smana/etcd_on_host
etcd directly in host
2016-01-21 13:20:05 +01:00
9715962356 etcd directly in host
fix etcd configuration for nodes

fix wrong calico checksums

using a var name etcd_bin_dir

fix etcd handlers for sysvinit

using a var name etcd_bin_dir

sysvinit script

review etcd configuration
2016-01-21 11:36:11 +01:00
5afbe181ce Merge pull request #78 from Smana/conf_etc-hosts_preinstall
move /etc/hosts configuration in 'preinstall' role
2016-01-20 19:02:03 +01:00
a5094f2a6a move /etc/hosts configuration in 'preinstall' role 2016-01-20 17:37:23 +01:00
9156d1ecfd Merge pull request #76 from rackn/dns-ip
Use IP is specified, otherwise use the ansible discovered address.
2016-01-20 15:46:27 +01:00
fe5ec398bf Use IP is specified, otherwise use the ansible discovered address.
This fixes cases for use in Vagrant environments.
2016-01-20 08:34:39 -06:00
babf42f03a Merge pull request #71 from ansibl8s/add_set_remote_user
Add set remote user
2016-01-19 22:20:31 +01:00
859f6322a0 Merge branch 'master' into add_set_remote_user 2016-01-19 21:08:52 +01:00
815c5fa43c Merge pull request #74 from rackn/master
run_once only works if master[0] is first in inventory list of all nodes
2016-01-19 20:48:42 +01:00
10b2466d82 run_once only works if master[0] is first in inventory list
of all nodes.
2016-01-19 13:10:54 -06:00
f68d8f3757 Add seT_remote_user in synchronize 2016-01-19 14:20:05 +01:00
9b083b62cf Rename tasks 2016-01-19 14:20:05 +01:00
59614fc60d Merge pull request #70 from Smana/localhost_dnsmasq
Localhost dnsmasq
2016-01-19 14:01:05 +01:00
b54af6b42f reduce dns timeout 2016-01-19 13:49:33 +01:00
7cab7e5fef restarting kubelet is sometimes required after docker restart 2016-01-19 13:47:07 +01:00
4c5735cef8 configure dnsmasq to listen on localhost only 2016-01-19 13:34:30 +01:00
58e1db6aae update kubedns submodule 2016-01-19 13:32:53 +01:00
63ae6ba5b5 dnsmasq runs on all nodes 2016-01-19 10:31:47 +01:00
f58b4d3dd6 dnsmasq listens on localhost 2016-01-19 10:29:33 +01:00
d3a8584212 add timeout options to resolv.conf 2016-01-19 10:18:53 +01:00
51f1ae1e9e Merge pull request #67 from ansibl8s/v1.1.4
Change hyperkube repo
2016-01-18 17:32:05 +01:00
4271126bae Change hyperkube repo 2016-01-18 17:17:08 +01:00
049f5015c1 upgrade hyperkube image version 2016-01-18 16:55:57 +01:00
6ab671c88b update memcached submodule 2016-01-18 16:25:01 +01:00
d73ac90acf udpate k8s-pgbouncer submodule 2016-01-18 11:58:12 +01:00
adf6e2f7b1 update postgres submodule 2016-01-18 11:44:33 +01:00
fb0803cf4c README : update versions 2016-01-17 21:31:38 +01:00
806834a6e9 upgrade kubernetes to 1.1.4 and calico to 0.14.0 2016-01-17 21:30:11 +01:00
8415634016 use google hyperkube image 2016-01-16 22:55:49 +01:00
319f687ced Merge pull request #62 from ansibl8s/flannel
Flannel running as pod
2016-01-15 13:13:56 +01:00
8127e8f8e8 Flannel running as pod 2016-01-15 13:03:27 +01:00
dd46cc64a4 README : Networking title 2016-01-15 12:18:26 +01:00
2d5862a94d README : typo 2016-01-15 12:18:21 +01:00
3d45a81006 README: ansible basics docs link 2016-01-15 12:18:13 +01:00
51a0996087 fix regexp for resolv.conf 2016-01-15 12:18:03 +01:00
80ac2ec6fc update README 2016-01-15 12:17:28 +01:00
5d61b5e813 Fix namespace 2016-01-14 16:22:37 +01:00
b769636435 Ansible 2.0 2016-01-13 16:40:24 +01:00
161 changed files with 23753 additions and 18833 deletions

49
.gitmodules vendored
View File

@ -1,49 +0,0 @@
[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

View File

@ -1,41 +1,150 @@
sudo: required
dist: trusty
language: python
python: "2.7"
sudo: false
addons:
hosts:
- node1
git:
depth: 5
env:
- SITE=cluster.yml
global:
GCE_USER=travis
SSH_USER=$GCE_USER
TEST_ID=$TRAVIS_JOB_NUMBER
CONTAINER_ENGINE=docker
PRIVATE_KEY=$GCE_PRIVATE_KEY
ANSIBLE_KEEP_REMOTE_FILES=1
matrix:
# Debian Jessie
- >-
KUBE_NETWORK_PLUGIN=flannel
CLOUD_IMAGE=debian-8-kubespray
CLOUD_REGION=europe-west1-b
- >-
KUBE_NETWORK_PLUGIN=calico
CLOUD_IMAGE=debian-8-kubespray
CLOUD_REGION=us-central1-c
- >-
KUBE_NETWORK_PLUGIN=weave
CLOUD_IMAGE=debian-8-kubespray
CLOUD_REGION=us-east1-d
# Centos 7
- >-
KUBE_NETWORK_PLUGIN=flannel
CLOUD_IMAGE=centos-7-sudo
CLOUD_REGION=asia-east1-c
- >-
KUBE_NETWORK_PLUGIN=calico
CLOUD_IMAGE=centos-7-sudo
CLOUD_REGION=europe-west1-b
- >-
KUBE_NETWORK_PLUGIN=weave
CLOUD_IMAGE=centos-7-sudo
CLOUD_REGION=us-central1-c
# Redhat 7
- >-
KUBE_NETWORK_PLUGIN=flannel
CLOUD_IMAGE=rhel-7-sudo
CLOUD_REGION=us-east1-d
- >-
KUBE_NETWORK_PLUGIN=calico
CLOUD_IMAGE=rhel-7-sudo
CLOUD_REGION=asia-east1-c
- >-
KUBE_NETWORK_PLUGIN=weave
CLOUD_IMAGE=rhel-7-sudo
CLOUD_REGION=europe-west1-b
# Ubuntu 14.04
- >-
KUBE_NETWORK_PLUGIN=flannel
CLOUD_IMAGE=ubuntu-1404-trusty
CLOUD_REGION=us-central1-c
- >-
KUBE_NETWORK_PLUGIN=calico
CLOUD_IMAGE=ubuntu-1404-trusty
CLOUD_REGION=us-east1-d
- >-
KUBE_NETWORK_PLUGIN=weave
CLOUD_IMAGE=ubuntu-1404-trusty
CLOUD_REGION=asia-east1-c
# Ubuntu 15.10
- >-
KUBE_NETWORK_PLUGIN=flannel
CLOUD_IMAGE=ubuntu-1510-wily
CLOUD_REGION=europe-west1-b
- >-
KUBE_NETWORK_PLUGIN=calico
CLOUD_IMAGE=ubuntu-1510-wily
CLOUD_REGION=us-central1-a
- >-
KUBE_NETWORK_PLUGIN=weave
CLOUD_IMAGE=ubuntu-1510-wily
CLOUD_REGION=us-east1-d
matrix:
allow_failures:
- env: KUBE_NETWORK_PLUGIN=weave CLOUD_IMAGE=ubuntu-1404-trusty CLOUD_REGION=asia-east1-c
- env: KUBE_NETWORK_PLUGIN=calico CLOUD_IMAGE=ubuntu-1404-trusty CLOUD_REGION=us-east1-d
before_install:
- sudo apt-get update -qq
install:
# Install Ansible.
- sudo -H pip install ansible
- sudo -H pip install netaddr
- pip install --user boto -U
- pip install --user ansible
- pip install --user netaddr
- pip install --user apache-libcloud
cache:
directories:
- $HOME/releases
- directories:
- $HOME/.cache/pip
- $HOME/.local
before_script:
- export PATH=$PATH:/usr/local/bin
- echo "RUN $TRAVIS_JOB_NUMBER $KUBE_NETWORK_PLUGIN $CONTAINER_ENGINE "
- mkdir -p $HOME/.ssh
- echo $PRIVATE_KEY | base64 -d > $HOME/.ssh/id_rsa
- echo $GCE_PEM_FILE | base64 -d > $HOME/.ssh/gce
- chmod 400 $HOME/.ssh/id_rsa
- chmod 755 $HOME/.local/bin/ansible-playbook
- $HOME/.local/bin/ansible-playbook --version
- cp tests/ansible.cfg .
# - "echo $HOME/.local/bin/ansible-playbook -i inventory.ini -u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS -b --become-user=root -e '{\"cloud_provider\": true}' $LOG_LEVEL -e kube_network_plugin=${KUBE_NETWORK_PLUGIN} setup-kubernetes/cluster.yml"
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)
$HOME/.local/bin/ansible-playbook tests/cloud_playbooks/create-gce.yml -i tests/local_inventory/hosts -c local $LOG_LEVEL
-e test_id=${TEST_ID}
-e kube_network_plugin=${KUBE_NETWORK_PLUGIN}
-e gce_project_id=${GCE_PROJECT_ID}
-e gce_service_account_email=${GCE_ACCOUNT}
-e gce_pem_file=${HOME}/.ssh/gce
-e cloud_image=${CLOUD_IMAGE}
-e inventory_path=${PWD}/inventory/inventory.ini
-e cloud_region=${CLOUD_REGION}
# Create cluster
- "$HOME/.local/bin/ansible-playbook -i inventory/inventory.ini -u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS -b --become-user=root -e '{\"cloud_provider\": true}' $LOG_LEVEL -e kube_network_plugin=${KUBE_NETWORK_PLUGIN} cluster.yml"
# Tests Cases
## Test Master API
- $HOME/.local/bin/ansible-playbook -i inventory/inventory.ini tests/testcases/010_check-apiserver.yml $LOG_LEVEL
## Create a POD
- $HOME/.local/bin/ansible-playbook -i inventory/inventory.ini -u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS -b --become-user=root tests/testcases/020_check-create-pod.yml $LOG_LEVEL
## Ping the between 2 pod
- $HOME/.local/bin/ansible-playbook -i inventory/inventory.ini -u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS -b --become-user=root tests/testcases/030_check-network.yml $LOG_LEVEL
after_script:
- >
$HOME/.local/bin/ansible-playbook -i inventory/inventory.ini tests/cloud_playbooks/delete-gce.yml -c local $LOG_LEVEL
-e test_id=${TEST_ID}
-e kube_network_plugin=${KUBE_NETWORK_PLUGIN}
-e gce_project_id=${GCE_PROJECT_ID}
-e gce_service_account_email=${GCE_ACCOUNT}
-e gce_pem_file=${HOME}/.ssh/gce
-e cloud_image=${CLOUD_IMAGE}
-e inventory_path=${PWD}/inventory/inventory.ini
-e cloud_region=${CLOUD_REGION}

201
LICENSE Normal file
View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "{}"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright 2016 Kubespray
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.

279
README.md
View File

@ -1,279 +1,6 @@
[![Build Status](https://travis-ci.org/ansibl8s/setup-kubernetes.svg)](https://travis-ci.org/ansibl8s/setup-kubernetes)
kubernetes-ansible
========
Install and configure a Multi-Master/HA kubernetes cluster including network plugin.
![Kubespray Logo](http://s9.postimg.org/md5dyjl67/kubespray_logoandkubespray_small.png)
### 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
The documentation can be found [THERE](https://docs.kubespray.io)
### 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
Quickstart
-------------------------
The following steps will quickly setup a kubernetes cluster with default configuration.
These defaults are good for tests purposes.
Edit the inventory according to the number of servers
```
[downloader]
localhost ansible_connection=local ansible_python_interpreter=python2
[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
```
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)
[![Build Status](https://travis-ci.org/kubespray/kubespray.svg)](https://travis-ci.org/kubespray/kubespray)

4
ansible.cfg Normal file
View File

@ -0,0 +1,4 @@
[ssh_connection]
pipelining=True
[defaults]
host_key_checking=False

View File

@ -1,29 +0,0 @@
---
- 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'}

View File

@ -1,18 +1,18 @@
---
- hosts: downloader
sudo: no
roles:
- { role: download, tags: download }
- hosts: k8s-cluster
roles:
- { role: adduser, tags: adduser }
- { role: download, tags: download }
- { 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'] }
- { role: docker, tags: docker, when: ansible_os_family != "CoreOS" }
- { role: kubernetes/node, tags: node }
- { role: network_plugin, tags: network }
- hosts: kube-master
roles:
- { role: kubernetes/master, tags: master }
- hosts: k8s-cluster
roles:
- { role: dnsmasq, tags: dnsmasq }

5
coreos-bootstrap.yml Normal file
View File

@ -0,0 +1,5 @@
---
- hosts: k8s-cluster
gather_facts: False
roles:
- coreos-bootstrap

View File

@ -1,10 +1,18 @@
# Directory where the binaries will be installed
# 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"
# Uncomment this line for CoreOS only.
# Directory where python binary is installed
# ansible_python_interpreter: "/opt/bin/python"
# This is the group that the cert creation scripts chgrp the
# cert files to. Not really changable...
kube_cert_group: kube-cert
# Cluster Loglevel configuration
kube_log_level: 2
@ -20,8 +28,30 @@ kube_users:
# 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
# For some environments, each node has a pubilcally accessible
# address and an address it should bind services to. These are
# really inventory level variables, but described here for consistency.
#
# When advertising access, the access_ip will be used, but will defer to
# ip and then the default ansible ip when unspecified.
#
# When binding to restrict access, the ip variable will be used, but will
# defer to the default ansible ip when unspecified.
#
# The ip variable is used for specific address binding, e.g. listen address
# for etcd. This is use to help with environments like Vagrant or multi-nic
# systems where one address should be preferred over another.
# ip: 10.2.2.2
#
# The access_ip variable is used to define how other nodes should access
# the node. This is used in flannel to allow other flannel nodes to see
# this node for example. The access_ip is really useful AWS and Google
# environments where the nodes are accessed remotely by the "public" ip,
# but don't know about that address themselves.
# access_ip: 1.1.1.1
# Choose network plugin (calico, weave or flannel)
kube_network_plugin: flannel
# Kubernetes internal network for services, unused block of space.
kube_service_addresses: 10.233.0.0/18
@ -67,7 +97,8 @@ upstream_dns_servers:
dns_setup: true
dns_domain: "{{ cluster_name }}"
#
# # Ip address of the kubernetes dns service
# # Ip address of the kubernetes skydns service
skydns_server: "{{ kube_service_addresses|ipaddr('net')|ipaddr(3)|ipaddr('address') }}"
dns_server: "{{ kube_service_addresses|ipaddr('net')|ipaddr(2)|ipaddr('address') }}"
# For multi masters architecture:

View File

@ -1,6 +1,3 @@
[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

View File

@ -1,8 +1,5 @@
node1 ansible_connection=local local_release_dir={{ansible_env.HOME}}/releases
[downloader]
node1
[kube-master]
node1

View File

@ -1,41 +1,52 @@
---
- src: https://github.com/ansibl8s/k8s-common.git
- src: https://gitlab.com/kubespray-ansibl8s/k8s-common.git
path: roles/apps
version: v1.0
scm: git
- src: https://github.com/ansibl8s/k8s-kubedns.git
- src: https://gitlab.com/kubespray-ansibl8s/k8s-kubedns.git
path: roles/apps
version: v1.0
scm: git
#- 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
- src: https://gitlab.com/kubespray-ansibl8s/k8s-kube-ui.git
path: roles/apps
scm: git
- src: https://gitlab.com/kubespray-ansibl8s/k8s-fabric8.git
path: roles/apps
scm: git
- src: https://gitlab.com/kubespray-ansibl8s/k8s-elasticsearch.git
path: roles/apps
scm: git
- src: https://gitlab.com/kubespray-ansibl8s/k8s-redis.git
path: roles/apps
scm: git
- src: https://gitlab.com/kubespray-ansibl8s/k8s-memcached.git
path: roles/apps
scm: git
- src: https://gitlab.com/kubespray-ansibl8s/k8s-postgres.git
path: roles/apps
scm: git
- src: https://gitlab.com/kubespray-ansibl8s/k8s-pgbouncer.git
path: roles/apps
scm: git
- src: https://gitlab.com/kubespray-ansibl8s/k8s-heapster.git
path: roles/apps
scm: git
- src: https://gitlab.com/kubespray-ansibl8s/k8s-influxdb.git
path: roles/apps
scm: git
- src: https://gitlab.com/kubespray-ansibl8s/k8s-kubedash.git
path: roles/apps
scm: git
- src: https://gitlab.com/kubespray-ansibl8s/k8s-kube-logstash.git
path: roles/apps
scm: git

View File

@ -0,0 +1,28 @@
---
- 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
skip: true
- name: User | Create User Group
group: name={{item.group|default(item.name)}} system={{item.system|default(omit)}}
with_items: addusers
- name: User | Create User
user:
comment: "{{item.comment|default(omit)}}"
createhome: "{{item.create_home|default(omit)}}"
group: "{{item.group|default(item.name)}}"
home: "{{item.home|default(omit)}}"
name: "{{item.name}}"
system: "{{item.system|default(omit)}}"
with_items: addusers

View File

@ -0,0 +1,8 @@
---
addusers:
- name: kube
comment: "Kubernetes user"
shell: /sbin/nologin
system: yes
group: "{{ kube_cert_group }}"
createhome: no

View File

@ -0,0 +1,15 @@
---
addusers:
- name: etcd
comment: "Etcd user"
createhome: yes
home: "/var/lib/etcd"
system: yes
shell: /bin/nologin
- name: kube
comment: "Kubernetes user"
shell: /sbin/nologin
system: yes
group: "{{ kube_cert_group }}"
createhome: no

View File

@ -0,0 +1,15 @@
---
addusers:
- name: etcd
comment: "Etcd user"
createhome: yes
home: "/var/lib/etcd"
system: yes
shell: /bin/nologin
- name: kube
comment: "Kubernetes user"
shell: /sbin/nologin
system: yes
group: "{{ kube_cert_group }}"
createhome: no

View File

@ -0,0 +1,4 @@
---
pypy_version: 2.4.0
pip_python_modules:
- httplib2

View File

@ -1,7 +1,7 @@
#/bin/bash
set -e
BINDIR="/usr/local/bin"
BINDIR="/opt/bin"
cd $BINDIR

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,3 @@
#!/bin/bash
BINDIR="/usr/local/bin"
BINDIR="/opt/bin"
LD_LIBRARY_PATH=$BINDIR/pypy/lib:$LD_LIBRARY_PATH $BINDIR/pypy/bin/$(basename $0) $@

View File

@ -1,41 +1,40 @@
---
- name: Python | Check if bootstrap is needed
raw: stat {{ bin_dir}}/.bootstrapped
- name: Bootstrap | Check if bootstrap is needed
raw: stat /opt/bin/.bootstrapped
register: need_bootstrap
ignore_errors: True
- name: Python | Run bootstrap.sh
- name: Bootstrap | Run bootstrap.sh
script: bootstrap.sh
when: need_bootstrap | failed
- set_fact:
ansible_python_interpreter: "{{ bin_dir }}/python"
ansible_python_interpreter: "/opt/bin/python"
- name: Python | Check if we need to install pip
- name: Bootstrap | 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
- name: Bootstrap | Copy get-pip.py
copy: src=get-pip.py dest=~/get-pip.py
when: need_pip | failed
- name: Python | Install pip
- name: Bootstrap | Install pip
shell: "{{ansible_python_interpreter}} ~/get-pip.py"
when: need_pip | failed
- name: Python | Remove get-pip.py
- name: Bootstrap | 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
- name: Bootstrap | Install pip launcher
copy: src=runner dest=/opt/bin/pip mode=0755
when: need_pip | failed
- name: Install required python modules
pip:
name: "{{ item }}"
with_items: pip_python_modules

View File

@ -0,0 +1,2 @@
#!/bin/bash
LD_LIBRARY_PATH={{ pypy_install_path }}/lib:$LD_LIBRARY_PATH exec {{ pypy_install_path }}/bin/{{ item.src }} "$@"

View File

@ -0,0 +1,318 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
DOCUMENTATION = """
---
module: kube
short_description: Manage Kubernetes Cluster
description:
- Create, replace, remove, and stop resources within a Kubernetes Cluster
version_added: "2.0"
options:
name:
required: false
default: null
description:
- The name associated with resource
filename:
required: false
default: null
description:
- The path and filename of the resource(s) definition file.
kubectl:
required: false
default: null
description:
- The path to the kubectl bin
namespace:
required: false
default: null
description:
- The namespace associated with the resource(s)
resource:
required: false
default: null
description:
- The resource to perform an action on. pods (po), replicationControllers (rc), services (svc)
label:
required: false
default: null
description:
- The labels used to filter specific resources.
server:
required: false
default: null
description:
- The url for the API server that commands are executed against.
api_version:
required: false
choices: ['v1', 'v1beta3']
default: v1
description:
- The API version associated with cluster.
force:
required: false
default: false
description:
- A flag to indicate to force delete, replace, or stop.
all:
required: false
default: false
description:
- A flag to indicate delete all, stop all, or all namespaces when checking exists.
log_level:
required: false
default: 0
description:
- Indicates the level of verbosity of logging by kubectl.
state:
required: false
choices: ['present', 'absent', 'latest', 'reloaded', 'stopped']
default: present
description:
- present handles checking existence or creating if definition file provided,
absent handles deleting resource(s) based on other options,
latest handles creating ore updating based on existence,
reloaded handles updating resource(s) definition using definition file,
stopped handles stopping resource(s) based on other options.
requirements:
- kubectl
author: "Kenny Jones (@kenjones-cisco)"
"""
EXAMPLES = """
- name: test nginx is present
kube: name=nginx resource=rc state=present
- name: test nginx is stopped
kube: name=nginx resource=rc state=stopped
- name: test nginx is absent
kube: name=nginx resource=rc state=absent
- name: test nginx is present
kube: filename=/tmp/nginx.yml
"""
class KubeManager(object):
def __init__(self, module):
self.module = module
self.kubectl = module.params.get('kubectl')
if self.kubectl is None:
self.kubectl = module.get_bin_path('kubectl', True)
self.base_cmd = [self.kubectl]
self.api_version = module.params.get('api_version')
if self.api_version:
self.base_cmd.append('--api-version=' + self.api_version)
if module.params.get('server'):
self.base_cmd.append('--server=' + module.params.get('server'))
if module.params.get('log_level'):
self.base_cmd.append('--v=' + str(module.params.get('log_level')))
if module.params.get('namespace'):
self.base_cmd.append('--namespace=' + module.params.get('namespace'))
self.all = module.params.get('all')
self.force = module.params.get('force')
self.name = module.params.get('name')
self.filename = module.params.get('filename')
self.resource = module.params.get('resource')
self.label = module.params.get('label')
def _execute(self, cmd):
args = self.base_cmd + cmd
try:
rc, out, err = self.module.run_command(args)
if rc != 0:
self.module.fail_json(
msg='error running kubectl (%s) command (rc=%d): %s' % (' '.join(args), rc, out or err))
except Exception as exc:
self.module.fail_json(
msg='error running kubectl (%s) command: %s' % (' '.join(args), str(exc)))
return out.splitlines()
def _execute_nofail(self, cmd):
args = self.base_cmd + cmd
rc, out, err = self.module.run_command(args)
if rc != 0:
return None
return out.splitlines()
def create(self, check=True):
if check and self.exists():
return []
cmd = ['create']
if not self.filename:
self.module.fail_json(msg='filename required to create')
cmd.append('--filename=' + self.filename)
return self._execute(cmd)
def replace(self):
if not self.force and not self.exists():
return []
cmd = ['replace']
if self.api_version != 'v1':
cmd = ['update']
if self.force:
cmd.append('--force')
if not self.filename:
self.module.fail_json(msg='filename required to reload')
cmd.append('--filename=' + self.filename)
return self._execute(cmd)
def delete(self):
if not self.force and not self.exists():
return []
cmd = ['delete']
if self.filename:
cmd.append('--filename=' + self.filename)
else:
if not self.resource:
self.module.fail_json(msg='resource required to delete without filename')
cmd.append(self.resource)
if self.name:
cmd.append(self.name)
if self.label:
cmd.append('--selector=' + self.label)
if self.all:
cmd.append('--all')
if self.force:
cmd.append('--ignore-not-found')
return self._execute(cmd)
def exists(self):
cmd = ['get']
if not self.resource:
return False
cmd.append(self.resource)
if self.name:
cmd.append(self.name)
cmd.append('--no-headers')
if self.label:
cmd.append('--selector=' + self.label)
if self.all:
cmd.append('--all-namespaces')
result = self._execute_nofail(cmd)
if not result:
return False
return True
def stop(self):
if not self.force and not self.exists():
return []
cmd = ['stop']
if self.filename:
cmd.append('--filename=' + self.filename)
else:
if not self.resource:
self.module.fail_json(msg='resource required to stop without filename')
cmd.append(self.resource)
if self.name:
cmd.append(self.name)
if self.label:
cmd.append('--selector=' + self.label)
if self.all:
cmd.append('--all')
if self.force:
cmd.append('--ignore-not-found')
return self._execute(cmd)
def main():
module = AnsibleModule(
argument_spec=dict(
name=dict(),
filename=dict(),
namespace=dict(),
resource=dict(),
label=dict(),
server=dict(),
kubectl=dict(),
api_version=dict(default='v1', choices=['v1', 'v1beta3']),
force=dict(default=False, type='bool'),
all=dict(default=False, type='bool'),
log_level=dict(default=0, type='int'),
state=dict(default='present', choices=['present', 'absent', 'latest', 'reloaded', 'stopped']),
)
)
changed = False
manager = KubeManager(module)
state = module.params.get('state')
if state == 'present':
result = manager.create()
elif state == 'absent':
result = manager.delete()
elif state == 'reloaded':
result = manager.replace()
elif state == 'stopped':
result = manager.stop()
elif state == 'latest':
if manager.exists():
manager.force = True
result = manager.replace()
else:
result = manager.create(check=False)
else:
module.fail_json(msg='Unrecognized state %s.' % state)
if result:
changed = True
module.exit_json(changed=changed,
msg='success: %s' % (' '.join(result))
)
from ansible.module_utils.basic import * # noqa
if __name__ == '__main__':
main()

View File

@ -1,57 +1,62 @@
---
- 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
- name: ensure dnsmasq.d-available directory exists
file:
path: /etc/dnsmasq.d-available
state: directory
- name: Write dnsmasq configuration
template:
src: 01-kube-dns.conf.j2
dest: /etc/dnsmasq.d/01-kube-dns.conf
mode: 755
dest: /etc/dnsmasq.d-available/01-kube-dns.conf
mode: 0755
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: Stat dnsmasq configuration
stat: path=/etc/dnsmasq.d/01-kube-dns.conf
register: sym
- name: Check for dnsmasq port
- name: Move previous configuration
command: mv /etc/dnsmasq.d/01-kube-dns.conf /etc/dnsmasq.d-available/01-kube-dns.conf.bak
changed_when: False
when: sym.stat.islnk is defined and sym.stat.islnk == False
- name: Enable dnsmasq configuration
file:
src: /etc/dnsmasq.d-available/01-kube-dns.conf
dest: /etc/dnsmasq.d/01-kube-dns.conf
state: link
- name: Create dnsmasq manifests
template: src={{item.file}} dest=/etc/kubernetes/{{item.file}}
with_items:
- {file: dnsmasq-ds.yml, type: ds}
- {file: dnsmasq-svc.yml, type: svc}
register: manifests
when: inventory_hostname == groups['kube-master'][0]
- name: Start Resources
kube:
name: dnsmasq
namespace: kube-system
kubectl: /usr/local/bin/kubectl
resource: "{{item.item.type}}"
filename: /etc/kubernetes/{{item.item.file}}
state: "{{item.changed | ternary('latest','present') }}"
with_items: manifests.results
when: inventory_hostname == groups['kube-master'][0]
- name: Check for dnsmasq port (pulling image and running container)
wait_for:
host: "{{dns_server}}"
port: 53
delay: 5
timeout: 100
when: inventory_hostname in groups['kube-master']
when: inventory_hostname == groups['kube-master'][0]
- name: check resolvconf
stat: path=/etc/resolvconf/resolv.conf.d/head
@ -59,34 +64,42 @@
- name: target resolv.conf file
set_fact:
resolvconffile: >
{%- if resolvconf.stat.exists == True -%}
/etc/resolvconf/resolv.conf.d/head
{%- else -%}
/etc/resolv.conf
{%- endif -%}
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(' ') }}
line: "search {{ [ 'default.svc.' + dns_domain, 'svc.' + dns_domain, dns_domain ] | join(' ') }}"
dest: "{{resolvconffile}}"
state: present
insertafter: EOF
insertbefore: BOF
backup: yes
follow: yes
- name: Add all masters as nameserver
- name: Add local dnsmasq to resolv.conf
lineinfile:
line: nameserver {{ hostvars[item]['ansible_default_ipv4']['address'] }}
line: "nameserver {{dns_server}}"
dest: "{{resolvconffile}}"
state: present
insertafter: "^search.*$"
backup: yes
follow: yes
- name: Add options to resolv.conf
lineinfile:
line: options {{ item }}
dest: "{{resolvconffile}}"
state: present
regexp: "^options.*{{ item }}$"
insertafter: EOF
backup: yes
follow: yes
with_items: groups['kube-master']
with_items:
- timeout:2
- attempts:2
- name: disable resolv.conf modification by dhclient
copy: src=dhclient_nodnsupdate dest=/etc/dhcp/dhclient-enter-hooks.d/nodnsupdate mode=u+x backup=yes
copy: src=dhclient_nodnsupdate dest=/etc/dhcp/dhclient-enter-hooks.d/nodnsupdate mode=0755 backup=yes
when: ansible_os_family == "Debian"
- name: disable resolv.conf modification by dhclient

View File

@ -1,5 +1,6 @@
#Listen on all interfaces
interface=*
#Listen on localhost
bind-interfaces
listen-address=0.0.0.0
addn-hosts=/etc/hosts
@ -16,4 +17,4 @@ server={{ srv }}
{% endif %}
# Forward k8s domain to kube-dns
server=/{{ dns_domain }}/{{ dns_server }}
server=/{{ dns_domain }}/{{ skydns_server }}

View File

@ -0,0 +1,52 @@
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: dnsmasq
namespace: kube-system
labels:
k8s-app: dnsmasq
spec:
template:
metadata:
labels:
k8s-app: dnsmasq
spec:
containers:
- name: dnsmasq
image: andyshinn/dnsmasq:2.72
command:
- dnsmasq
args:
- -k
- "-7"
- /etc/dnsmasq.d
securityContext:
capabilities:
add:
- NET_ADMIN
imagePullPolicy: Always
resources:
limits:
cpu: 100m
memory: 256M
ports:
- name: dns
containerPort: 53
protocol: UDP
- name: dns-tcp
containerPort: 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

View File

@ -1,49 +0,0 @@
---
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

View File

@ -0,0 +1,23 @@
---
apiVersion: v1
kind: Service
metadata:
labels:
kubernetes.io/cluster-service: 'true'
k8s-app: dnsmasq
name: dnsmasq
namespace: kube-system
spec:
ports:
- port: 53
name: dns-tcp
targetPort: 53
protocol: TCP
- port: 53
name: dns
targetPort: 53
protocol: UDP
type: ClusterIP
clusterIP: {{dns_server}}
selector:
k8s-app: dnsmasq

View File

@ -0,0 +1 @@
docker_version: 1.10

View File

@ -11,6 +11,7 @@
- defaults.yml
paths:
- ../vars
skip: true
- name: check for minimum kernel version
fail:
@ -20,30 +21,42 @@
{{ 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
args:
id: "{{item}}"
keyserver: "{{docker_repo_key_info.keyserver}}"
state: present
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
args:
repo: "{{item}}"
state: present
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
args:
pkg: "{{item}}"
state: present
with_items: docker_package_info.pkgs
when: docker_package_info.pkgs|length > 0
- name: Centos needs xfs storage type for devicemapper if used
lineinfile:
dest: /etc/sysconfig/docker-storage
line: "DOCKER_STORAGE_OPTIONS='--storage-opt dm.fs=xfs'"
regexp: '^DOCKER_STORAGE_OPTIONS=.*$'
state: present
backup: yes
when: ansible_os_family == "RedHat"
- meta: flush_handlers
- name: ensure docker service is started and enabled
service:
name: "{{ item }}"

View File

@ -1,24 +1,16 @@
docker_kernel_min_version: '2.6.32-431'
# versioning: docker-io itself is pinned at docker 1.5
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: []

View File

@ -1,36 +1,26 @@
docker_kernel_min_version: '3.2'
# https://apt.dockerproject.org/repo/dists/debian-wheezy/main/filelist
docker_versioned_pkg:
latest: docker-engine
1.9: docker-engine=1.9.1-0~{{ ansible_distribution_release|lower }}
1.10: docker-engine=1.10.3-0~{{ ansible_distribution_release|lower }}
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_versioned_pkg[docker_version] }}"
docker_repo_key_info:
pkg_key: apt_key
args:
id: "{{ item }}"
keyserver: hkp://p80.pool.sks-keyservers.net:80
state: present
keyserver: hkp://p80.pool.sks-keyservers.net:80
repo_keys:
- 58118E89F3A912897C070ADBF76221572C52609D
- 58118E89F3A912897C070ADBF76221572C52609D
docker_repo_info:
pkg_repo: apt_repository
args:
repo: "{{ item }}"
update_cache: yes
state: present
repos:
- >
deb https://apt.dockerproject.org/repo
deb https://apt.dockerproject.org/repo
{{ ansible_distribution|lower }}-{{ ansible_distribution_release|lower }}
main

View File

@ -1,22 +1,16 @@
docker_kernel_min_version: '0'
# versioning: docker-io itself is pinned at docker 1.5
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: []

View File

@ -0,0 +1,19 @@
docker_kernel_min_version: '0'
docker_versioned_pkg:
latest: docker
1.9: docker-1:1.9.1
1.10: docker-1:1.10.1
docker_package_info:
pkg_mgr: dnf
pkgs:
- "{{ docker_versioned_pkg[docker_version] }}"
docker_repo_key_info:
pkg_key: ''
repo_keys: []
docker_repo_info:
pkg_repo: ''
repos: []

View File

@ -2,21 +2,13 @@ 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: []

View File

@ -0,0 +1,27 @@
docker_kernel_min_version: '3.2'
# https://apt.dockerproject.org/repo/dists/ubuntu-trusty/main/filelist
docker_versioned_pkg:
latest: docker-engine
1.9: docker-engine=1.9.0-0~{{ ansible_distribution_release|lower }}
1.10: docker-engine=1.10.3-0~{{ ansible_distribution_release|lower }}
docker_package_info:
pkg_mgr: apt
pkgs:
- "{{ docker_versioned_pkg[docker_version] }}"
docker_repo_key_info:
pkg_key: apt_key
keyserver: hkp://p80.pool.sks-keyservers.net:80
repo_keys:
- 58118E89F3A912897C070ADBF76221572C52609D
docker_repo_info:
pkg_repo: apt_repository
repos:
- >
deb https://apt.dockerproject.org/repo
{{ ansible_distribution|lower }}-{{ ansible_distribution_release|lower }}
main

View File

@ -1,42 +1,104 @@
---
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
# Versions
kube_version: v1.2.0
etcd_version: v2.2.5
calico_version: v0.17.0
calico_cni_version: v1.0.0
weave_version: v1.4.4
kubectl_checksum: "01b9bea18061a27b1cf30e34fd8ab45cfc096c9a9d57d0ed21072abb40dd3d1d"
kubelet_checksum: "62191c66f2d670dd52ddf1d88ef81048977abf1ffaa95ee6333299447eb6a482"
# Download URL's
kubelet_download_url: "https://storage.googleapis.com/kubespray/{{kube_version}}_kubernetes-kubelet"
apiserver_download_url: "https://storage.googleapis.com/kubespray/{{kube_version}}_kubernetes-apiserver"
kubectl_download_url: "https://storage.googleapis.com/kubespray/{{kube_version}}_kubernetes-kubectl"
kube_download_url: "https://storage.googleapis.com/kubernetes-release/release/{{ kube_version }}/bin/linux/amd64"
etcd_download_url: "https://storage.googleapis.com/kubespray/{{etcd_version}}_etcd"
calico_download_url: "https://storage.googleapis.com/kubespray/{{calico_version}}_calico"
calico_cni_download_url: "https://storage.googleapis.com/kubespray/{{calico_cni_version}}_calico-cni-plugin"
calico_cni_ipam_download_url: "https://storage.googleapis.com/kubespray/{{calico_cni_version}}_calico-cni-plugin-ipam"
weave_download_url: "https://storage.googleapis.com/kubespray/{{weave_version}}_weave"
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"
# Checksums
calico_checksum: "1fa22c0ee0cc661f56aa09169a3661fb46e552b53fae5fae9aac010e0666b281"
calico_cni_checksum: "cfbb95d4416cb65845a188f3bd991fff232bd5ce3463b2919d586ab77967aecd"
calico_cni_ipam_checksum: "93ebf8756b26314e1e3f612f1e824418cbb0a8df2942664422e697bcb109fbb2"
weave_checksum: "152942c330f87ab475d87d9311b91674b90f25ea685bd4e04e0495d5fe09a957"
etcd_checksum: "aa6037406257d2a1bc48ffa769afe7a4f8a04cc1ffcd36ef84f9ee8bc4eca756"
kubectl_checksum: "0fd51875a4783fb106f769bdbc81012066b4a2785ba88b0280870a25cab76296"
kubelet_checksum: "a1da4b8d0965f66b7243d22f2b307227ec24bbd7ce8522cd3ce4ec1206c3a09e"
kube_apiserver_checksum: "fe50e4014a96897a708b3c847550b4e510a390585209c2b11c02a32123570d43"
downloads:
- name: calico
dest: calico/bin/calicoctl
url: "{{calico_download_url}}"
version: "{{calico_version}}"
sha256: "{{ calico_checksum }}"
source_url: "{{ calico_download_url }}"
url: "{{ calico_download_url }}"
owner: "root"
mode: "0755"
- name: calico-plugin
- name: calico-cni-plugin
dest: calico/bin/calico
url: "{{calico_plugin_download_url}}"
version: "{{calico_cni_version}}"
sha256: "{{ calico_cni_checksum }}"
source_url: "{{ calico_cni_download_url }}"
url: "{{ calico_cni_download_url }}"
owner: "root"
mode: "0755"
- name: flannel
dest: flannel/flannel-{{ flannel_version }}-linux-amd64.tar.gz
url: "{{flannel_download_url}}"
unarchive: yes
- name: calico-cni-plugin-ipam
dest: calico/bin/calico-ipam
version: "{{calico_cni_version}}"
sha256: "{{ calico_cni_ipam_checksum }}"
source_url: "{{ calico_cni_ipam_download_url }}"
url: "{{ calico_cni_ipam_download_url }}"
owner: "root"
mode: "0755"
- name: weave
dest: weave/bin/weave
version: "{{weave_version}}"
source_url: "{{weave_download_url}}"
url: "{{weave_download_url}}"
sha256: "{{ weave_checksum }}"
owner: "root"
mode: "0755"
- name: etcd
version: "{{etcd_version}}"
dest: "etcd/etcd-{{ etcd_version }}-linux-amd64.tar.gz"
sha256: "{{ etcd_checksum }}"
source_url: "{{ etcd_download_url }}"
url: "{{ etcd_download_url }}"
unarchive: true
owner: "etcd"
mode: "0755"
- name: kubernetes-kubelet
version: "{{kube_version}}"
dest: kubernetes/bin/kubelet
sha256: "{{kubelet_checksum}}"
url: "{{ kube_download_url }}/kubelet"
source_url: "{{ kubelet_download_url }}"
url: "{{ kubelet_download_url }}"
owner: "kube"
mode: "0755"
- name: kubernetes-kubectl
dest: kubernetes/bin/kubectl
version: "{{kube_version}}"
sha256: "{{kubectl_checksum}}"
url: "{{ kube_download_url }}/kubectl"
source_url: "{{ kubectl_download_url }}"
url: "{{ kubectl_download_url }}"
owner: "kube"
mode: "0755"
- name: kubernetes-apiserver
dest: kubernetes/bin/kube-apiserver
version: "{{kube_version}}"
sha256: "{{kube_apiserver_checksum}}"
source_url: "{{ apiserver_download_url }}"
url: "{{ apiserver_download_url }}"
owner: "kube"
mode: "0755"

View File

@ -8,12 +8,25 @@
url: "{{item.url}}"
dest: "{{local_release_dir}}/{{item.dest}}"
sha256sum: "{{item.sha256 | default(omit)}}"
owner: "{{ item.owner|default(omit) }}"
mode: "{{ item.mode|default(omit) }}"
with_items: downloads
- name: Extract archives
unarchive:
src: "{{ local_release_dir }}/{{item.dest}}"
dest: "{{ local_release_dir }}/{{item.dest|dirname}}"
copy: no
src: "{{ local_release_dir }}/{{item.dest}}"
dest: "{{ local_release_dir }}/{{item.dest|dirname}}"
owner: "{{ item.owner|default(omit) }}"
mode: "{{ item.mode|default(omit) }}"
copy: no
when: "{{item.unarchive is defined and item.unarchive == True}}"
with_items: downloads
- name: Fix permissions
file:
state: file
path: "{{local_release_dir}}/{{item.dest}}"
owner: "{{ item.owner|default(omit) }}"
mode: "{{ item.mode|default(omit) }}"
when: "{{item.unarchive is not defined or item.unarchive == False}}"
with_items: downloads

View File

@ -0,0 +1,3 @@
---
etcd_version: v2.2.5
etcd_bin_dir: "{{ local_release_dir }}/etcd/etcd-{{ etcd_version }}-linux-amd64/"

View File

@ -0,0 +1,15 @@
---
- name: restart etcd
command: /bin/true
notify:
- reload systemd
- reload etcd
- name: reload systemd
command: systemctl daemon-reload
when: ansible_service_mgr == "systemd"
- name: reload etcd
service:
name: etcd
state: restarted

View File

@ -0,0 +1,23 @@
---
- name: Configure | Copy etcd.service systemd file
template:
src: etcd.service.j2
dest: /etc/systemd/system/etcd.service
backup: yes
when: ansible_service_mgr == "systemd"
notify: restart etcd
- name: Configure | Write etcd initd script
template:
src: deb-etcd.initd.j2
dest: /etc/init.d/etcd
owner: root
mode: 0755
when: ansible_service_mgr in ["sysvinit","upstart"] and ansible_os_family == "Debian"
notify: restart etcd
- name: Configure | Create etcd config file
template:
src: etcd.j2
dest: /etc/etcd.env
notify: restart etcd

View File

@ -0,0 +1,9 @@
---
- name: Install | Copy etcd binary
command: rsync -piu "{{ etcd_bin_dir }}/etcd" "{{ bin_dir }}/etcd"
register: etcd_copy
changed_when: false
- name: Install | Copy etcdctl binary
command: rsync -piu "{{ etcd_bin_dir }}/etcdctl" "{{ bin_dir }}/etcdctl"
changed_when: false

View File

@ -1,13 +1,18 @@
---
- name: ETCD2 | Stop etcd2 service
service: name=etcd state=stopped
ignore_errors: yes
- include: install.yml
- include: configure.yml
- name: ETCD2 | create etcd pod template
template: src=etcd-pod.yml dest=/etc/kubernetes/manifests/etcd-pod.manifest
- name: Restart etcd if binary changed
command: /bin/true
notify: restart etcd
when: etcd_copy.stdout_lines
- name: ETCD2 | Check for etcd2 port
wait_for:
port: 2379
delay: 5
timeout: 100
# reload systemd before starting service
- meta: flush_handlers
- name: Ensure etcd is running
service:
name: etcd
state: started
enabled: yes

View File

@ -0,0 +1,113 @@
#!/bin/sh
set -a
### BEGIN INIT INFO
# Provides: etcd
# Required-Start: $local_fs $network $syslog
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: etcd distributed k/v store
# Description:
# etcd is a distributed, consistent key-value store for shared configuration and service discovery
### END INIT INFO
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="etcd k/v store"
NAME=etcd
DAEMON={{ bin_dir }}/etcd
{% if inventory_hostname in groups['etcd'] %}
DAEMON_ARGS=""
{% else %}
DAEMON_ARGS="-proxy on"
{% endif %}
SCRIPTNAME=/etc/init.d/$NAME
DAEMON_USER=etcd
STOP_SCHEDULE="${STOP_SCHEDULE:-QUIT/5/TERM/5/KILL/5}"
PID=/var/run/etcd.pid
# Exit if the binary is not present
[ -x "$DAEMON" ] || exit 0
# Read configuration variable file if it is present
[ -f /etc/etcd.env ] && . /etc/etcd.env
# 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()
{
status_of_proc -p $PID "$DAEMON" "$NAME" && exit 0 || exit $?
}
# Function that starts the daemon/service
#
do_start()
{
start-stop-daemon --background --start --quiet --make-pidfile --pidfile $PID --user $DAEMON_USER --exec $DAEMON -- \
$DAEMON_ARGS \
|| return 2
}
#
# Function that stops the daemon/service
#
do_stop()
{
start-stop-daemon --stop --quiet --retry=$STOP_SCHEDULE --pidfile $PID --name $NAME
RETVAL="$?"
sleep 1
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"
if do_stop; then
log_end_msg 0
else
log_failure_msg "Can't stop etcd"
log_end_msg 1
fi
;;
status)
if do_status; then
log_end_msg 0
else
log_failure_msg "etcd 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 etcd"
log_end_msg ${rc}
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac

View File

@ -1,54 +0,0 @@
---
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

View File

@ -0,0 +1,17 @@
ETCD_DATA_DIR="/var/lib/etcd"
{% if inventory_hostname in groups['etcd'] %}
{% set etcd = {} %}
{% for host in groups['etcd'] %}
{% if inventory_hostname == host %}
{% set _dummy = etcd.update({'name':"etcd"+loop.index|string}) %}
{% endif %}
{% endfor %}
ETCD_ADVERTISE_CLIENT_URLS="http://{{ hostvars[inventory_hostname]['access_ip'] | default(hostvars[inventory_hostname]['ip'] | default( ansible_default_ipv4.address)) }}:2379"
ETCD_INITIAL_ADVERTISE_PEER_URLS="http://{{ hostvars[inventory_hostname]['access_ip'] | default(hostvars[inventory_hostname]['ip'] | default( ansible_default_ipv4.address)) }}:2380"
ETCD_INITIAL_CLUSTER_STATE="new"
ETCD_INITIAL_CLUSTER_TOKEN="k8s_etcd"
ETCD_LISTEN_PEER_URLS="http://{{ hostvars[inventory_hostname]['ip'] | default( ansible_default_ipv4.address) }}:2380"
ETCD_NAME="{{ etcd.name }}"
{% endif %}
ETCD_INITIAL_CLUSTER="{% for host in groups['etcd'] %}etcd{{ loop.index|string }}=http://{{ hostvars[host]['access_ip'] | default(hostvars[host]['ip'] | default(hostvars[host]['ansible_default_ipv4']['address'])) }}:2380{% if not loop.last %},{% endif %}{% endfor %}"
ETCD_LISTEN_CLIENT_URLS="http://{{ hostvars[inventory_hostname]['ip'] | default( ansible_default_ipv4.address) }}:2379,http://127.0.0.1:2379"

View File

@ -0,0 +1,18 @@
[Unit]
Description=etcd
[Service]
User=etcd
EnvironmentFile=/etc/etcd.env
{% if inventory_hostname in groups['etcd'] %}
ExecStart={{ bin_dir }}/etcd
{% else %}
ExecStart={{ bin_dir }}/etcd -proxy on
{% endif %}
Restart=always
RestartSec=10s
LimitNOFILE=40000
[Install]
WantedBy=multi-user.target

View File

@ -265,6 +265,7 @@ _kubectl_get()
flags_completion=()
flags+=("--all-namespaces")
flags+=("--export")
flags+=("--filename=")
flags_with_completion+=("--filename")
flags_completion+=("__handle_filename_extension_flag json|yaml|yml")
@ -401,10 +402,204 @@ _kubectl_describe()
must_have_one_noun+=("serviceaccount")
}
_kubectl_create_namespace()
{
last_command="kubectl_create_namespace"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--dry-run")
flags+=("--generator=")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--output-version=")
flags+=("--save-config")
flags+=("--schema-cache-dir=")
flags+=("--validate")
flags+=("--alsologtostderr")
flags+=("--api-version=")
flags+=("--certificate-authority=")
flags+=("--client-certificate=")
flags+=("--client-key=")
flags+=("--cluster=")
flags+=("--context=")
flags+=("--insecure-skip-tls-verify")
flags+=("--kubeconfig=")
flags+=("--log-backtrace-at=")
flags+=("--log-dir=")
flags+=("--log-flush-frequency=")
flags+=("--logtostderr")
flags+=("--match-server-version")
flags+=("--namespace=")
flags+=("--password=")
flags+=("--server=")
two_word_flags+=("-s")
flags+=("--stderrthreshold=")
flags+=("--token=")
flags+=("--user=")
flags+=("--username=")
flags+=("--v=")
flags+=("--vmodule=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_create_secret_docker-registry()
{
last_command="kubectl_create_secret_docker-registry"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--docker-email=")
flags+=("--docker-password=")
flags+=("--docker-server=")
flags+=("--docker-username=")
flags+=("--dry-run")
flags+=("--generator=")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--output-version=")
flags+=("--save-config")
flags+=("--schema-cache-dir=")
flags+=("--validate")
flags+=("--alsologtostderr")
flags+=("--api-version=")
flags+=("--certificate-authority=")
flags+=("--client-certificate=")
flags+=("--client-key=")
flags+=("--cluster=")
flags+=("--context=")
flags+=("--insecure-skip-tls-verify")
flags+=("--kubeconfig=")
flags+=("--log-backtrace-at=")
flags+=("--log-dir=")
flags+=("--log-flush-frequency=")
flags+=("--logtostderr")
flags+=("--match-server-version")
flags+=("--namespace=")
flags+=("--password=")
flags+=("--server=")
two_word_flags+=("-s")
flags+=("--stderrthreshold=")
flags+=("--token=")
flags+=("--user=")
flags+=("--username=")
flags+=("--v=")
flags+=("--vmodule=")
must_have_one_flag=()
must_have_one_flag+=("--docker-email=")
must_have_one_flag+=("--docker-password=")
must_have_one_flag+=("--docker-username=")
must_have_one_noun=()
}
_kubectl_create_secret_generic()
{
last_command="kubectl_create_secret_generic"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--dry-run")
flags+=("--from-file=")
flags+=("--from-literal=")
flags+=("--generator=")
flags+=("--output=")
two_word_flags+=("-o")
flags+=("--output-version=")
flags+=("--save-config")
flags+=("--schema-cache-dir=")
flags+=("--type=")
flags+=("--validate")
flags+=("--alsologtostderr")
flags+=("--api-version=")
flags+=("--certificate-authority=")
flags+=("--client-certificate=")
flags+=("--client-key=")
flags+=("--cluster=")
flags+=("--context=")
flags+=("--insecure-skip-tls-verify")
flags+=("--kubeconfig=")
flags+=("--log-backtrace-at=")
flags+=("--log-dir=")
flags+=("--log-flush-frequency=")
flags+=("--logtostderr")
flags+=("--match-server-version")
flags+=("--namespace=")
flags+=("--password=")
flags+=("--server=")
two_word_flags+=("-s")
flags+=("--stderrthreshold=")
flags+=("--token=")
flags+=("--user=")
flags+=("--username=")
flags+=("--v=")
flags+=("--vmodule=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_create_secret()
{
last_command="kubectl_create_secret"
commands=()
commands+=("docker-registry")
commands+=("generic")
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--alsologtostderr")
flags+=("--api-version=")
flags+=("--certificate-authority=")
flags+=("--client-certificate=")
flags+=("--client-key=")
flags+=("--cluster=")
flags+=("--context=")
flags+=("--insecure-skip-tls-verify")
flags+=("--kubeconfig=")
flags+=("--log-backtrace-at=")
flags+=("--log-dir=")
flags+=("--log-flush-frequency=")
flags+=("--logtostderr")
flags+=("--match-server-version")
flags+=("--namespace=")
flags+=("--password=")
flags+=("--server=")
two_word_flags+=("-s")
flags+=("--stderrthreshold=")
flags+=("--token=")
flags+=("--user=")
flags+=("--username=")
flags+=("--v=")
flags+=("--vmodule=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_create()
{
last_command="kubectl_create"
commands=()
commands+=("namespace")
commands+=("secret")
flags=()
two_word_flags=()
@ -945,6 +1140,125 @@ _kubectl_scale()
must_have_one_noun=()
}
_kubectl_cordon()
{
last_command="kubectl_cordon"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--alsologtostderr")
flags+=("--api-version=")
flags+=("--certificate-authority=")
flags+=("--client-certificate=")
flags+=("--client-key=")
flags+=("--cluster=")
flags+=("--context=")
flags+=("--insecure-skip-tls-verify")
flags+=("--kubeconfig=")
flags+=("--log-backtrace-at=")
flags+=("--log-dir=")
flags+=("--log-flush-frequency=")
flags+=("--logtostderr")
flags+=("--match-server-version")
flags+=("--namespace=")
flags+=("--password=")
flags+=("--server=")
two_word_flags+=("-s")
flags+=("--stderrthreshold=")
flags+=("--token=")
flags+=("--user=")
flags+=("--username=")
flags+=("--v=")
flags+=("--vmodule=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_drain()
{
last_command="kubectl_drain"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--force")
flags+=("--grace-period=")
flags+=("--alsologtostderr")
flags+=("--api-version=")
flags+=("--certificate-authority=")
flags+=("--client-certificate=")
flags+=("--client-key=")
flags+=("--cluster=")
flags+=("--context=")
flags+=("--insecure-skip-tls-verify")
flags+=("--kubeconfig=")
flags+=("--log-backtrace-at=")
flags+=("--log-dir=")
flags+=("--log-flush-frequency=")
flags+=("--logtostderr")
flags+=("--match-server-version")
flags+=("--namespace=")
flags+=("--password=")
flags+=("--server=")
two_word_flags+=("-s")
flags+=("--stderrthreshold=")
flags+=("--token=")
flags+=("--user=")
flags+=("--username=")
flags+=("--v=")
flags+=("--vmodule=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_uncordon()
{
last_command="kubectl_uncordon"
commands=()
flags=()
two_word_flags=()
flags_with_completion=()
flags_completion=()
flags+=("--alsologtostderr")
flags+=("--api-version=")
flags+=("--certificate-authority=")
flags+=("--client-certificate=")
flags+=("--client-key=")
flags+=("--cluster=")
flags+=("--context=")
flags+=("--insecure-skip-tls-verify")
flags+=("--kubeconfig=")
flags+=("--log-backtrace-at=")
flags+=("--log-dir=")
flags+=("--log-flush-frequency=")
flags+=("--logtostderr")
flags+=("--match-server-version")
flags+=("--namespace=")
flags+=("--password=")
flags+=("--server=")
two_word_flags+=("-s")
flags+=("--stderrthreshold=")
flags+=("--token=")
flags+=("--user=")
flags+=("--username=")
flags+=("--v=")
flags+=("--vmodule=")
must_have_one_flag=()
must_have_one_noun=()
}
_kubectl_attach()
{
last_command="kubectl_attach"
@ -1164,6 +1478,7 @@ _kubectl_run()
two_word_flags+=("-r")
flags+=("--requests=")
flags+=("--restart=")
flags+=("--rm")
flags+=("--save-config")
flags+=("--service-generator=")
flags+=("--service-overrides=")
@ -2045,6 +2360,9 @@ _kubectl()
commands+=("logs")
commands+=("rolling-update")
commands+=("scale")
commands+=("cordon")
commands+=("drain")
commands+=("uncordon")
commands+=("attach")
commands+=("exec")
commands+=("port-forward")

View File

@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: kube-system

View File

@ -1,14 +1,4 @@
---
- 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
- name: restart kube-apiserver
set_fact:
restart_apimaster: True

View File

@ -3,80 +3,87 @@
copy:
src: kubectl_bash_completion.sh
dest: /etc/bash_completion.d/kubectl.sh
when: ansible_os_family in ["Debian","RedHat"]
- 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: Copy kube-apiserver binary
command: rsync -piu "{{ local_release_dir }}/kubernetes/bin/kube-apiserver" "{{ bin_dir }}/kube-apiserver"
register: kube_apiserver_copy
changed_when: false
- name: Perms kubectl binary
file: path={{ bin_dir }}/kubectl owner=kube mode=0755 state=file
- name: Copy kubectl binary
command: rsync -piu "{{ local_release_dir }}/kubernetes/bin/kubectl" "{{ bin_dir }}/kubectl"
changed_when: false
- 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
- name: install | Write kube-apiserver systemd init file
template:
src: manifests/kube-apiserver.manifest.j2
dest: "{{ kube_manifest_dir }}/kube-apisever.manifest"
notify:
- restart kubelet
src: "kube-apiserver.service.j2"
dest: "/etc/systemd/system/kube-apiserver.service"
backup: yes
when: ansible_service_mgr == "systemd"
notify: restart kube-apiserver
- name: install | Write kube-apiserver initd script
template:
src: "deb-kube-apiserver.initd.j2"
dest: "/etc/init.d/kube-apiserver"
owner: root
mode: 0755
backup: yes
when: ansible_service_mgr in ["sysvinit","upstart"] and ansible_os_family == "Debian"
- name: Write kube-apiserver config file
template:
src: "kube-apiserver.j2"
dest: "{{ kube_config_dir }}/kube-apiserver.env"
backup: yes
notify: restart kube-apiserver
- name: Allow apiserver to bind on both secure and insecure ports
shell: setcap cap_net_bind_service+ep {{ bin_dir }}/kube-apiserver
changed_when: false
- 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
- include: start.yml
with_items: groups['kube-master']
when: "{{ hostvars[item].inventory_hostname == inventory_hostname }}"
- 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
# Create kube-system namespace
- name: copy 'kube-system' namespace manifest
copy: src=namespace.yml dest=/etc/kubernetes/kube-system-ns.yml
run_once: yes
when: inventory_hostname == groups['kube-master'][0]
- name: Check if kube-system exists
command: "{{ bin_dir }}/kubectl get ns kube-system"
register: 'kubesystem'
changed_when: False
ignore_errors: yes
run_once: yes
- name: wait for the apiserver to be running
wait_for:
port: "{{kube_apiserver_insecure_port}}"
timeout: 60
- name: Create 'kube-system' namespace
command: "{{ bin_dir }}/kubectl create -f /etc/kubernetes/kube-system-ns.yml"
changed_when: False
when: kubesystem|failed and inventory_hostname == groups['kube-master'][0]
# Write manifests
- name: Write kube-controller-manager manifest
template:
src: manifests/kube-controller-manager.manifest.j2
dest: "{{ kube_config_dir }}/kube-controller-manager.manifest"
dest: "{{ kube_manifest_dir }}/kube-controller-manager.manifest"
- name: Write kube-scheduler manifest
template:
src: manifests/kube-scheduler.manifest.j2
dest: "{{ kube_config_dir }}/kube-scheduler.manifest"
dest: "{{ kube_manifest_dir }}/kube-scheduler.manifest"
- name: Write podmaster manifest
template:
src: manifests/kube-podmaster.manifest.j2
dest: "{{ kube_manifest_dir }}/kube-podmaster.manifest"
- name: restart kubelet
service:
name: kubelet
state: restarted
changed_when: false

View File

@ -0,0 +1,22 @@
---
- name: Pause
pause: seconds=10
- name: reload systemd
command: systemctl daemon-reload
when: ansible_service_mgr == "systemd" and restart_apimaster is defined and restart_apimaster == True
- name: reload kube-apiserver
service:
name: kube-apiserver
state: restarted
enabled: yes
when: ( restart_apimaster is defined and restart_apimaster == True) or
secret_changed | default(false)
- name: Enable apiserver
service:
name: kube-apiserver
enabled: yes
state: started
when: restart_apimaster is not defined or restart_apimaster == False

View File

@ -0,0 +1,118 @@
#!/bin/bash
#
### BEGIN INIT INFO
# Provides: kube-apiserver
# Required-Start: $local_fs $network $syslog
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: The Kubernetes apiserver
# Description:
# The Kubernetes apiserver.
### 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 apiserver"
NAME=kube-apiserver
DAEMON={{ bin_dir }}/kube-apiserver
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.env ] && . /etc/kubernetes/$NAME.env
# 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

View File

@ -0,0 +1,44 @@
###
# kubernetes system config
#
# The following values are used to configure the kube-apiserver
{% if ansible_service_mgr in ["sysvinit","upstart"] %}
# Logging directory
KUBE_LOGGING="--log-dir={{ kube_log_dir }} --logtostderr=true"
{% else %}
# logging to stderr means we get it in the systemd journal
KUBE_LOGGING="--logtostderr=true"
{% endif %}
# Apiserver Log level, 0 is debug
KUBE_LOG_LEVEL="{{ kube_log_level | default('--v=2') }}"
# Should this cluster be allowed to run privileged docker containers
KUBE_ALLOW_PRIV="--allow_privileged=true"
# The port on the local server to listen on.
KUBE_API_PORT="--insecure-port={{kube_apiserver_insecure_port}} --secure-port={{ kube_apiserver_port }}"
# Address range to use for services
KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range={{ kube_service_addresses }}"
# Location of the etcd cluster
KUBE_ETCD_SERVERS="--etcd_servers={% for host in groups['etcd'] %}http://{{ hostvars[host]['access_ip'] | default(hostvars[host]['ip'] | default(hostvars[host]['ansible_default_ipv4']['address'])) }}:2379{% if not loop.last %},{% endif %}{% endfor %}"
# default admission control policies
KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"
# RUNTIME API CONFIGURATION (e.g. enable extensions)
KUBE_RUNTIME_CONFIG="{% if kube_api_runtime_config is defined %}{% for conf in kube_api_runtime_config %}--runtime-config={{ conf }} {% endfor %}{% endif %}"
# TLS CONFIGURATION
KUBE_TLS_CONFIG="--tls_cert_file={{ kube_cert_dir }}/apiserver.pem --tls_private_key_file={{ kube_cert_dir }}/apiserver-key.pem --client_ca_file={{ kube_cert_dir }}/ca.pem"
# Add you own!
KUBE_API_ARGS="--token_auth_file={{ kube_token_dir }}/known_tokens.csv --basic-auth-file={{ kube_users_dir }}/known_users.csv --service_account_key_file={{ kube_cert_dir }}/apiserver-key.pem"
{% if ansible_service_mgr in ["sysvinit","upstart"] %}
DAEMON_ARGS="$KUBE_LOGGING $KUBE_LOG_LEVEL $KUBE_ALLOW_PRIV $KUBE_API_PORT $KUBE_SERVICE_ADDRESSES \
$KUBE_ETCD_SERVERS $KUBE_ADMISSION_CONTROL $KUBE_RUNTIME_CONFIG $KUBE_TLS_CONFIG $KUBE_API_ARGS"
{% endif %}

View File

@ -0,0 +1,28 @@
[Unit]
Description=Kubernetes API Server
Documentation=https://github.com/GoogleCloudPlatform/kubernetes
Requires=etcd.service
After=etcd.service
[Service]
EnvironmentFile=/etc/kubernetes/kube-apiserver.env
User=kube
ExecStart={{ bin_dir }}/kube-apiserver \
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBE_ETCD_SERVERS \
$KUBE_API_ADDRESS \
$KUBE_API_PORT \
$KUBELET_PORT \
$KUBE_ALLOW_PRIV \
$KUBE_SERVICE_ADDRESSES \
$KUBE_ADMISSION_CONTROL \
$KUBE_RUNTIME_CONFIG \
$KUBE_TLS_CONFIG \
$KUBE_API_ARGS
Restart=on-failure
Type=notify
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target

View File

@ -10,7 +10,7 @@ spec:
command:
- /hyperkube
- apiserver
- --etcd-servers={% for srv in groups['etcd'] %}http://{{ srv }}:2379{% if not loop.last %},{% endif %}{% endfor %}
- --etcd-servers={% for srv in groups['etcd'] %}http://{{ hostvars[srv]['access_ip'] | default(hostvars[srv]['ip']|default(hostvars[srv]['ansible_default_ipv4']['address'])) }}:2379{% if not loop.last %},{% endif %}{% endfor %}
- --admission-control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota
- --service-cluster-ip-range={{ kube_service_addresses }}

View File

@ -12,6 +12,7 @@ spec:
- /hyperkube
- controller-manager
- --master=http://127.0.0.1:{{kube_apiserver_insecure_port}}
- --leader-elect=true
- --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') }}
@ -20,8 +21,8 @@ spec:
host: 127.0.0.1
path: /healthz
port: 10252
initialDelaySeconds: 15
timeoutSeconds: 1
initialDelaySeconds: 30
timeoutSeconds: 10
volumeMounts:
- mountPath: {{ kube_cert_dir }}
name: ssl-certs-kubernetes

View File

@ -1,46 +0,0 @@
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

View File

@ -11,6 +11,7 @@ spec:
command:
- /hyperkube
- scheduler
- --leader-elect=true
- --master=http://127.0.0.1:{{kube_apiserver_insecure_port}}
- --v={{ kube_log_level | default('2') }}
livenessProbe:
@ -18,5 +19,5 @@ spec:
host: 127.0.0.1
path: /healthz
port: 10251
initialDelaySeconds: 15
timeoutSeconds: 1
initialDelaySeconds: 30
timeoutSeconds: 10

View File

@ -0,0 +1,6 @@
---
namespace_kubesystem:
apiVersion: v1
kind: Namespace
metadata:
name: kube-system

View File

@ -24,18 +24,15 @@ kube_users_dir: "{{ kube_config_dir }}/users"
# 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
# Logging directory (sysvinit systems)
kube_log_dir: "/var/log/kubernetes"
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
hyperkube_image_repo: quay.io/ant31/kubernetes-hyperkube
hyperkube_image_tag: v1.2.0
# IP address of the DNS server.
# Kubernetes will create a pod with several containers, serving as the DNS
@ -44,6 +41,6 @@ hyperkube_image_tag: v1.1.3
# 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
# kube_api_runtime_config:
# - extensions/v1beta1/daemonsets=true
# - extensions/v1beta1/deployments=true

View File

@ -1,14 +1,15 @@
---
- name: reload systemd
command: systemctl daemon-reload
when: ansible_service_mgr == "systemd"
- name: restart systemd-kubelet
- name: restart kubelet
command: /bin/true
notify:
- reload systemd
- restart kubelet
- reload kubelet
- name: restart kubelet
- name: reload kubelet
service:
name: kubelet
state: restarted

View File

@ -0,0 +1,3 @@
---
dependencies:
- role: kubernetes/secrets

View File

@ -1,28 +0,0 @@
---
- 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

View File

@ -1,48 +0,0 @@
---
- 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] }}"

View File

@ -1,48 +1,20 @@
---
- 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"
when: ansible_service_mgr == "systemd"
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"
template: src=deb-kubelet.initd.j2 dest=/etc/init.d/kubelet owner=root mode=0755 backup=yes
when: ansible_service_mgr in ["sysvinit","upstart"] 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=0755 backup=yes
when: ansible_service_mgr in ["sysvinit","upstart"] 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
command: rsync -piu "{{ local_release_dir }}/kubernetes/bin/kubelet" "{{ bin_dir }}/kubelet"
register: kubelet_copy
changed_when: false

View File

@ -1,34 +1,15 @@
---
- 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 Calico cni config
template:
src: "cni-calico.conf.j2"
dest: "/etc/cni/net.d/10-calico.conf"
owner: kube
when: kube_network_plugin == "calico"
- name: Write kubelet config file
template: src=kubelet.j2 dest={{ kube_config_dir }}/kubelet backup=yes
template: src=kubelet.j2 dest={{ kube_config_dir }}/kubelet.env backup=yes
notify:
- restart kubelet
@ -38,10 +19,18 @@
- restart kubelet
- name: Write proxy manifest
template:
template:
src: manifests/kube-proxy.manifest.j2
dest: "{{ kube_manifest_dir }}/kube-proxy.manifest"
- name: Restart kubelet if binary changed
command: /bin/true
notify: restart kubelet
when: kubelet_copy.stdout_lines
# reload-systemd
- meta: flush_handlers
- name: Enable kubelet
service:
name: kubelet

View File

@ -1,52 +0,0 @@
---
- 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'] }}"

View File

@ -0,0 +1,9 @@
{
"name": "calico-k8s-network",
"type": "calico",
"etcd_authority": "127.0.0.1:2379",
"log_level": "info",
"ipam": {
"type": "calico-ipam"
}
}

View File

@ -27,7 +27,7 @@ DAEMON_USER=root
[ -x "$DAEMON" ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/kubernetes/$NAME ] && . /etc/kubernetes/$NAME
[ -r /etc/kubernetes/$NAME.env ] && . /etc/kubernetes/$NAME.env
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present

View File

@ -1,7 +1,15 @@
KUBE_LOGTOSTDERR="--logtostderr=true"
{% if ansible_service_mgr in ["sysvinit","upstart"] %}
# Logging directory
KUBE_LOGGING="--log-dir={{ kube_log_dir }} --logtostderr=true"
{% else %}
# logging to stderr means we get it in the systemd journal
KUBE_LOGGING="--logtostderr=true"
{% endif %}
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 %}"
{% if inventory_hostname in groups['kube-node'] %}
KUBELET_API_SERVER="--api_servers={% for host in groups['kube-master'] %}https://{{ hostvars[host]['access_ip'] | default(hostvars[host]['ip'] | default(hostvars[host]['ansible_default_ipv4']['address'])) }}:{{ kube_apiserver_port }}{% if not loop.last %},{% endif %}{% endfor %}"
{% endif %}
# 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
@ -18,11 +26,13 @@ KUBELET_ARGS="--cluster_dns={{ dns_server }} --cluster_domain={{ dns_domain }} -
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 }}"
KUBELET_NETWORK_PLUGIN="--network_plugin=cni --network-plugin-dir=/etc/cni/net.d"
{% elif kube_network_plugin is defined and kube_network_plugin == "weave" %}
DOCKER_SOCKET="--docker-endpoint=unix:/var/run/weave/weave.sock"
{% 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"
{% if ansible_service_mgr in ["sysvinit","upstart"] %}
DAEMON_ARGS="$KUBE_LOGGING $KUBE_LOG_LEVEL $KUBE_ALLOW_PRIV $KUBELET_API_SERVER $KUBELET_ADDRESS \
$KUBELET_HOSTNAME $KUBELET_REGISTER_NODE $KUBELET_ARGS $DOCKER_SOCKET $KUBELET_ARGS $KUBELET_NETWORK_PLUGIN"
{% endif %}

View File

@ -8,18 +8,19 @@ After=docker.service
{% endif %}
[Service]
EnvironmentFile=/etc/kubernetes/kubelet
EnvironmentFile=/etc/kubernetes/kubelet.env
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
$KUBE_LOGTOSTDERR \
$KUBE_LOG_LEVEL \
$KUBELET_API_SERVER \
$KUBELET_ADDRESS \
$KUBELET_PORT \
$KUBELET_HOSTNAME \
$KUBE_ALLOW_PRIV \
$KUBELET_ARGS \
$DOCKER_SOCKET \
$KUBELET_REGISTER_NODE \
$KUBELET_NETWORK_PLUGIN
Restart=on-failure
[Install]

View File

@ -18,10 +18,12 @@ spec:
{% 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 }}
- --master=https://{{ hostvars[groups['kube-master'][0]]['access_ip'] | default(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 %}
- --bind-address={{ ip | default(ansible_default_ipv4.address) }}
- --proxy-mode={{ kube_proxy_mode }}
securityContext:
privileged: true
volumeMounts:

View File

@ -27,7 +27,7 @@ pidfile="/var/run/$prog.pid"
lockfile="/var/lock/subsys/$prog"
logfile="/var/log/$prog"
[ -e /etc/kubernetes/$prog ] && . /etc/kubernetes/$prog
[ -e /etc/kubernetes/$prog.env ] && . /etc/kubernetes/$prog.env
start() {
if [ ! -x $exec ]; then

View File

@ -1,15 +1,10 @@
---
run_gitinfos: false
common_required_pkgs:
- python-httplib2
- openssl
- curl
- rsync
- bash-completion
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"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,73 @@
#!/bin/sh
set -e
# Text color variables
txtbld=$(tput bold) # Bold
bldred=${txtbld}$(tput setaf 1) # red
bldgre=${txtbld}$(tput setaf 2) # green
bldylw=${txtbld}$(tput setaf 3) # yellow
txtrst=$(tput sgr0) # Reset
err=${bldred}ERROR${txtrst}
info=${bldgre}INFO${txtrst}
warn=${bldylw}WARNING${txtrst}
usage()
{
cat << EOF
Generates a file which contains useful git informations
Usage : $(basename $0) [global|diff]
ex :
Generate git information
$(basename $0) global
Generate diff from latest tag
$(basename $0) diff
EOF
}
if [ $# != 1 ]; then
printf "\n$err : Needs 1 argument\n"
usage
exit 2
fi;
current_commit=$(git rev-parse HEAD)
latest_tag=$(git describe --abbrev=0 --tags)
latest_tag_commit=$(git show-ref -s ${latest_tag})
tags_list=$(git tag --points-at "${latest_tag}")
case ${1} in
"global")
cat<<EOF
deployment date="$(date '+%d-%m-%Y %Hh%M')"
deployment_timestamp=$(date '+%s')
user="$USER"
current commit (HEAD)="${current_commit}"
current_commit_timestamp=$(git log -1 --pretty=format:%ct)
latest tag(s) (current branch)="${tags_list}"
latest tag commit="${latest_tag_commit}"
current branch="$(git rev-parse --abbrev-ref HEAD)"
branches list="$(git describe --contains --all HEAD)"
git root directory="$(git rev-parse --show-toplevel)"
EOF
if ! git diff-index --quiet HEAD --; then
printf "unstaged changes=\"/etc/.git-ansible.diff\""
fi
if [ ${current_commit} == ${latest_tag_commit} ]; then
printf "\ncurrent_commit_tag=\"${latest_tag}\""
else
printf "\nlast tag was "$(git describe --tags | awk -F- '{print $2}')" commits ago =\""
printf "$(git log --pretty=format:" %h - %s" ${latest_tag}..HEAD)\""
fi
;;
"diff")
git diff
;;
*)
usage
printf "$err: Unknown argument ${1}"
exit 1;
;;
esac

View File

@ -0,0 +1,36 @@
---
- name: Hosts | populate inventory into hosts file
lineinfile:
dest: /etc/hosts
regexp: "^{{ hostvars[item]['access_ip'] | default(hostvars[item]['ip'] | default(hostvars[item].ansible_default_ipv4.address)) }} {{ item }}$"
line: "{{ hostvars[item]['access_ip'] | default(hostvars[item]['ip'] | default(hostvars[item].ansible_default_ipv4.address)) }} {{ item }}"
state: present
create: yes
backup: yes
when: hostvars[item].ansible_default_ipv4.address is defined
with_items: groups['all']
- name: Hosts | populate kubernetes loadbalancer address into hosts file
lineinfile:
dest: /etc/hosts
regexp: ".*{{ apiserver_loadbalancer_domain_name }}$"
line: "{{ loadbalancer_apiserver.address }} {{ apiserver_loadbalancer_domain_name| default('lb-apiserver.kubernetes.local') }}"
state: present
backup: yes
when: loadbalancer_apiserver is defined and apiserver_loadbalancer_domain_name is defined
- name: Hosts | localhost ipv4 in hosts file
lineinfile:
dest: /etc/hosts
line: "127.0.0.1 localhost localhost.localdomain"
regexp: '^127.0.0.1.*$'
state: present
backup: yes
- name: Hosts | localhost ipv6 in hosts file
lineinfile:
dest: /etc/hosts
line: "::1 localhost6 localhost6.localdomain"
regexp: '^::1.*$'
state: present
backup: yes

View File

@ -0,0 +1,25 @@
---
# Deploy git infos
# ----------------
- name: 'GIT | generate git informations'
local_action: command {{ role_path }}/gen-gitinfos.sh global
register: gitinfo
always_run: yes
- name: 'GIT | copy ansible information'
template:
src: ansible_git.j2
dest: /etc/.ansible.ini
backup: yes
- name: 'GIT | generate diff file'
local_action: command {{ role_path }}/gen-gitinfos.sh diff
register: gitdiff
always_run: yes
- name: 'GIT | copy git diff file'
copy:
content: "{{ gitdiff.stdout }}"
dest: /etc/.git-ansible.diff
backup: yes

View File

@ -1,40 +1,103 @@
---
- 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
- include: gitinfos.yml
when: run_gitinfos
- 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
skip: true
- name: Force binaries directory for CoreOS
set_fact:
bin_dir: "/opt/bin"
when: ansible_os_family == "CoreOS"
- name: Create kubernetes config directory
file:
path: "{{ kube_config_dir }}"
state: directory
owner: kube
- name: Create kubernetes script directory
file:
path: "{{ kube_script_dir }}"
state: directory
owner: kube
- name: Create kubernetes manifests directory
file:
path: "{{ kube_manifest_dir }}"
state: directory
owner: kube
- name: Create kubernetes logs directory
file:
path: "{{ kube_log_dir }}"
state: directory
owner: kube
when: ansible_service_mgr in ["sysvinit","upstart"]
- name: Create cni directories
file:
path: "{{ item }}"
state: directory
owner: kube
with_items:
- "/etc/cni/net.d"
- "/opt/cni/bin"
when: kube_network_plugin == "calico"
- name: Update package management cache (APT)
apt: update_cache=yes
when: ansible_pkg_mgr == 'apt'
- name: Update package management cache (YUM)
yum: update_cache=yes name='*'
when: ansible_pkg_mgr == 'yum'
- name: Install python-apt for Debian distribs
command: apt-get install -y python-apt
when: ansible_os_family == "Debian"
changed_when: False
- set_fact:
init_system: "{{ init_system_output.stdout }}"
- name: Install python-dnf for latest RedHat versions
command: dnf install -y python-dnf yum
when: ansible_distribution == "Fedora" and
ansible_distribution_major_version > 21
changed_when: False
- name: Install epel-release on RHEL
command: rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm
when: ansible_distribution == "RedHat"
- name: Install epel-release on CentOS
action:
module: "{{ ansible_pkg_mgr }}"
name: "epel-release"
state: latest
when: ansible_distribution == "CentOS"
- name: Install packages requirements
action:
module: "{{ ansible_pkg_mgr }}"
name: "{{ item }}"
state: latest
with_items: common_required_pkgs
with_items: "{{required_pkgs | default([]) | union(common_required_pkgs|default([]))}}"
when: ansible_os_family != "CoreOS"
- 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
# Todo : selinux configuration
- name: Set selinux policy to permissive
selinux: policy=targeted state=permissive
when: ansible_os_family == "RedHat"
with_items: rh_required_pkgs
changed_when: False
- include: python-bootstrap.yml
when: ansible_os_family not in [ "Debian", "RedHat" ]
- include: etchosts.yml

View File

@ -0,0 +1,3 @@
; This file contains the information which identifies the deployment state relative to the git repo
[default]
{{ gitinfo.stdout }}

View File

@ -0,0 +1,3 @@
required_pkgs:
- libselinux-python
- device-mapper-libs

View File

@ -0,0 +1,5 @@
required_pkgs:
- python-apt
- aufs-tools
- apt-transport-https
- software-properties-common

View File

@ -0,0 +1,3 @@
required_pkgs:
- libselinux-python
- device-mapper-libs

View File

@ -0,0 +1,3 @@
required_pkgs:
- libselinux-python
- device-mapper-libs

Some files were not shown because too many files have changed in this diff Show More