mirror of
https://github.com/kubernetes-sigs/kubespray.git
synced 2025-12-14 05:45:06 +03:00
Compare commits
3 Commits
v2.1.1
...
test-tag-1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a222be7fae | ||
|
|
9d43cd86be | ||
|
|
6ed99f1f44 |
4
.gitignore
vendored
4
.gitignore
vendored
@@ -1,8 +1,6 @@
|
||||
.vagrant
|
||||
*.retry
|
||||
inventory/vagrant_ansible_inventory
|
||||
inventory/group_vars/fake_hosts.yml
|
||||
inventory/host_vars/
|
||||
temp
|
||||
.idea
|
||||
.tox
|
||||
@@ -14,5 +12,3 @@ temp
|
||||
*.tfstate.backup
|
||||
**/*.sw[pon]
|
||||
/ssh-bastion.conf
|
||||
**/*.sw[pon]
|
||||
vagrant/
|
||||
|
||||
133
.gitlab-ci.yml
133
.gitlab-ci.yml
@@ -47,20 +47,13 @@ before_script:
|
||||
PRIVATE_KEY: $GCE_PRIVATE_KEY
|
||||
GS_ACCESS_KEY_ID: $GS_KEY
|
||||
GS_SECRET_ACCESS_KEY: $GS_SECRET
|
||||
CLOUD_MACHINE_TYPE: "g1-small"
|
||||
ANSIBLE_KEEP_REMOTE_FILES: "1"
|
||||
ANSIBLE_CONFIG: ./tests/ansible.cfg
|
||||
BOOTSTRAP_OS: none
|
||||
DOWNLOAD_LOCALHOST: "false"
|
||||
DOWNLOAD_RUN_ONCE: "false"
|
||||
IDEMPOT_CHECK: "false"
|
||||
RESET_CHECK: "false"
|
||||
UPGRADE_TEST: "false"
|
||||
RESOLVCONF_MODE: docker_dns
|
||||
LOG_LEVEL: "-vv"
|
||||
ETCD_DEPLOYMENT: "docker"
|
||||
KUBELET_DEPLOYMENT: "docker"
|
||||
VAULT_DEPLOYMENT: "docker"
|
||||
WEAVE_CPU_LIMIT: "100m"
|
||||
MAGIC: "ci check this"
|
||||
|
||||
@@ -79,12 +72,14 @@ before_script:
|
||||
- pip install apache-libcloud==0.20.1
|
||||
- pip install boto==2.9.0
|
||||
- mkdir -p /.ssh
|
||||
- cp tests/ansible.cfg .
|
||||
- mkdir -p $HOME/.ssh
|
||||
- echo $PRIVATE_KEY | base64 -d > $HOME/.ssh/id_rsa
|
||||
- echo $GCE_PEM_FILE | base64 -d > $HOME/.ssh/gce
|
||||
- echo $GCE_CREDENTIALS > $HOME/.ssh/gce.json
|
||||
- chmod 400 $HOME/.ssh/id_rsa
|
||||
- ansible-playbook --version
|
||||
- cp tests/ansible.cfg .
|
||||
- export PYPATH=$([ $BOOTSTRAP_OS = none ] && echo /usr/bin/python || echo /opt/bin/python)
|
||||
script:
|
||||
- pwd
|
||||
@@ -98,18 +93,11 @@ before_script:
|
||||
-e gce_credentials_file=${HOME}/.ssh/gce.json
|
||||
-e gce_project_id=${GCE_PROJECT_ID}
|
||||
-e gce_service_account_email=${GCE_ACCOUNT}
|
||||
-e cloud_machine_type=${CLOUD_MACHINE_TYPE}
|
||||
-e inventory_path=${PWD}/inventory/inventory.ini
|
||||
-e kube_network_plugin=${KUBE_NETWORK_PLUGIN}
|
||||
-e mode=${CLUSTER_MODE}
|
||||
-e test_id=${TEST_ID}
|
||||
|
||||
# Check out latest tag if testing upgrade
|
||||
# Uncomment when gitlab kargo repo has tags
|
||||
#- test "${UPGRADE_TEST}" != "false" && git fetch --all && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))
|
||||
- test "${UPGRADE_TEST}" != "false" && git checkout 031cf565ec3ccd3ebbe80eeef3454c3780e5c598 && pip install ansible==2.2.0
|
||||
|
||||
|
||||
# Create cluster
|
||||
- >
|
||||
ansible-playbook -i inventory/inventory.ini -b --become-user=root --private-key=${HOME}/.ssh/id_rsa -u $SSH_USER
|
||||
@@ -118,57 +106,29 @@ before_script:
|
||||
-e ansible_python_interpreter=${PYPATH}
|
||||
-e ansible_ssh_user=${SSH_USER}
|
||||
-e bootstrap_os=${BOOTSTRAP_OS}
|
||||
-e cert_management=${CERT_MGMT:-script}
|
||||
-e cloud_provider=gce
|
||||
-e deploy_netchecker=true
|
||||
-e download_localhost=${DOWNLOAD_LOCALHOST}
|
||||
-e download_run_once=${DOWNLOAD_RUN_ONCE}
|
||||
-e download_localhost=true
|
||||
-e download_run_once=true
|
||||
-e etcd_deployment_type=${ETCD_DEPLOYMENT}
|
||||
-e kube_network_plugin=${KUBE_NETWORK_PLUGIN}
|
||||
-e kubelet_deployment_type=${KUBELET_DEPLOYMENT}
|
||||
-e local_release_dir=${PWD}/downloads
|
||||
-e resolvconf_mode=${RESOLVCONF_MODE}
|
||||
-e vault_deployment_type=${VAULT_DEPLOYMENT}
|
||||
--limit "all:!fake_hosts"
|
||||
-e weave_cpu_requests=${WEAVE_CPU_LIMIT}
|
||||
-e weave_cpu_limit=${WEAVE_CPU_LIMIT}
|
||||
cluster.yml
|
||||
|
||||
# Repeat deployment if testing upgrade
|
||||
- >
|
||||
if [ "${UPGRADE_TEST}" != "false" ]; then
|
||||
test "${UPGRADE_TEST}" == "basic" && PLAYBOOK="cluster.yml";
|
||||
test "${UPGRADE_TEST}" == "graceful" && PLAYBOOK="upgrade-cluster.yml";
|
||||
pip install ansible==2.2.1.0;
|
||||
git checkout "${CI_BUILD_REF}";
|
||||
ansible-playbook -i inventory/inventory.ini -b --become-user=root --private-key=${HOME}/.ssh/id_rsa -u $SSH_USER
|
||||
${SSH_ARGS}
|
||||
${LOG_LEVEL}
|
||||
-e ansible_python_interpreter=${PYPATH}
|
||||
-e ansible_ssh_user=${SSH_USER}
|
||||
-e bootstrap_os=${BOOTSTRAP_OS}
|
||||
-e cloud_provider=gce
|
||||
-e deploy_netchecker=true
|
||||
-e download_localhost=${DOWNLOAD_LOCALHOST}
|
||||
-e download_run_once=${DOWNLOAD_RUN_ONCE}
|
||||
-e etcd_deployment_type=${ETCD_DEPLOYMENT}
|
||||
-e kube_network_plugin=${KUBE_NETWORK_PLUGIN}
|
||||
-e kubelet_deployment_type=${KUBELET_DEPLOYMENT}
|
||||
-e local_release_dir=${PWD}/downloads
|
||||
-e resolvconf_mode=${RESOLVCONF_MODE}
|
||||
-e weave_cpu_requests=${WEAVE_CPU_LIMIT}
|
||||
-e weave_cpu_limit=${WEAVE_CPU_LIMIT}
|
||||
--limit "all:!fake_hosts"
|
||||
$PLAYBOOK;
|
||||
fi
|
||||
|
||||
# Tests Cases
|
||||
## Test Master API
|
||||
- ansible-playbook -i inventory/inventory.ini -e ansible_python_interpreter=${PYPATH} -u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS -b --become-user=root --limit "all:!fake_hosts" tests/testcases/010_check-apiserver.yml $LOG_LEVEL
|
||||
- ansible-playbook -i inventory/inventory.ini -e ansible_python_interpreter=${PYPATH} -u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS -b --become-user=root tests/testcases/010_check-apiserver.yml $LOG_LEVEL
|
||||
|
||||
## Ping the between 2 pod
|
||||
- ansible-playbook -i inventory/inventory.ini -e ansible_python_interpreter=${PYPATH} -u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS -b --become-user=root --limit "all:!fake_hosts" tests/testcases/030_check-network.yml $LOG_LEVEL
|
||||
- ansible-playbook -i inventory/inventory.ini -e ansible_python_interpreter=${PYPATH} -u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS -b --become-user=root tests/testcases/030_check-network.yml $LOG_LEVEL
|
||||
|
||||
## Advanced DNS checks
|
||||
- ansible-playbook -i inventory/inventory.ini -e ansible_python_interpreter=${PYPATH} -u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS -b --become-user=root --limit "all:!fake_hosts" tests/testcases/040_check-network-adv.yml $LOG_LEVEL
|
||||
- ansible-playbook -i inventory/inventory.ini -e ansible_python_interpreter=${PYPATH} -u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS -b --become-user=root tests/testcases/040_check-network-adv.yml $LOG_LEVEL
|
||||
|
||||
## Idempotency checks 1/5 (repeat deployment)
|
||||
- >
|
||||
@@ -178,14 +138,13 @@ before_script:
|
||||
--private-key=${HOME}/.ssh/id_rsa
|
||||
-e bootstrap_os=${BOOTSTRAP_OS}
|
||||
-e ansible_python_interpreter=${PYPATH}
|
||||
-e download_localhost=${DOWNLOAD_LOCALHOST}
|
||||
-e download_run_once=${DOWNLOAD_RUN_ONCE}
|
||||
-e download_run_once=true
|
||||
-e download_localhost=true
|
||||
-e deploy_netchecker=true
|
||||
-e resolvconf_mode=${RESOLVCONF_MODE}
|
||||
-e local_release_dir=${PWD}/downloads
|
||||
-e etcd_deployment_type=${ETCD_DEPLOYMENT}
|
||||
-e kubelet_deployment_type=${KUBELET_DEPLOYMENT}
|
||||
--limit "all:!fake_hosts"
|
||||
cluster.yml;
|
||||
fi
|
||||
|
||||
@@ -194,48 +153,43 @@ before_script:
|
||||
if [ "${IDEMPOT_CHECK}" = "true" ]; then
|
||||
ansible-playbook -i inventory/inventory.ini -e ansible_python_interpreter=${PYPATH}
|
||||
-u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS -b --become-user=root
|
||||
--limit "all:!fake_hosts"
|
||||
tests/testcases/040_check-network-adv.yml $LOG_LEVEL;
|
||||
fi
|
||||
|
||||
## Idempotency checks 3/5 (reset deployment)
|
||||
- >
|
||||
if [ "${IDEMPOT_CHECK}" = "true" AND "${RESET_CHECK}" = "true" ]; then
|
||||
if [ "${IDEMPOT_CHECK}" = "true" ]; then
|
||||
ansible-playbook -i inventory/inventory.ini -u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS
|
||||
-b --become-user=root -e cloud_provider=gce $LOG_LEVEL -e kube_network_plugin=${KUBE_NETWORK_PLUGIN}
|
||||
--private-key=${HOME}/.ssh/id_rsa
|
||||
-e bootstrap_os=${BOOTSTRAP_OS}
|
||||
-e ansible_python_interpreter=${PYPATH}
|
||||
-e reset_confirmation=yes
|
||||
--limit "all:!fake_hosts"
|
||||
reset.yml;
|
||||
fi
|
||||
|
||||
## Idempotency checks 4/5 (redeploy after reset)
|
||||
- >
|
||||
if [ "${IDEMPOT_CHECK}" = "true" AND "${RESET_CHECK}" = "true" ]; then
|
||||
if [ "${IDEMPOT_CHECK}" = "true" ]; then
|
||||
ansible-playbook -i inventory/inventory.ini -u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS
|
||||
-b --become-user=root -e cloud_provider=gce $LOG_LEVEL -e kube_network_plugin=${KUBE_NETWORK_PLUGIN}
|
||||
--private-key=${HOME}/.ssh/id_rsa
|
||||
-e bootstrap_os=${BOOTSTRAP_OS}
|
||||
-e ansible_python_interpreter=${PYPATH}
|
||||
-e download_localhost=${DOWNLOAD_LOCALHOST}
|
||||
-e download_run_once=${DOWNLOAD_RUN_ONCE}
|
||||
-e download_run_once=true
|
||||
-e download_localhost=true
|
||||
-e deploy_netchecker=true
|
||||
-e resolvconf_mode=${RESOLVCONF_MODE}
|
||||
-e local_release_dir=${PWD}/downloads
|
||||
-e etcd_deployment_type=${ETCD_DEPLOYMENT}
|
||||
-e kubelet_deployment_type=${KUBELET_DEPLOYMENT}
|
||||
--limit "all:!fake_hosts"
|
||||
cluster.yml;
|
||||
fi
|
||||
|
||||
## Idempotency checks 5/5 (Advanced DNS checks)
|
||||
- >
|
||||
if [ "${IDEMPOT_CHECK}" = "true" AND "${RESET_CHECK}" = "true" ]; then
|
||||
if [ "${IDEMPOT_CHECK}" = "true" ]; then
|
||||
ansible-playbook -i inventory/inventory.ini -e ansible_python_interpreter=${PYPATH}
|
||||
-u $SSH_USER -e ansible_ssh_user=$SSH_USER $SSH_ARGS -b --become-user=root
|
||||
--limit "all:!fake_hosts"
|
||||
tests/testcases/040_check-network-adv.yml $LOG_LEVEL;
|
||||
fi
|
||||
|
||||
@@ -256,21 +210,18 @@ before_script:
|
||||
.coreos_calico_sep_variables: &coreos_calico_sep_variables
|
||||
# stage: deploy-gce-part1
|
||||
KUBE_NETWORK_PLUGIN: calico
|
||||
CLOUD_IMAGE: coreos-stable-1298-6-0-v20170315
|
||||
CLOUD_IMAGE: coreos-stable-1235-6-0-v20170111
|
||||
CLOUD_REGION: us-west1-b
|
||||
CLUSTER_MODE: separate
|
||||
BOOTSTRAP_OS: coreos
|
||||
RESOLVCONF_MODE: host_resolvconf # This is required as long as the CoreOS stable channel uses docker < 1.12
|
||||
|
||||
.ubuntu_canal_ha_variables: &ubuntu_canal_ha_variables
|
||||
.debian8_canal_ha_variables: &debian8_canal_ha_variables
|
||||
# stage: deploy-gce-part1
|
||||
KUBE_NETWORK_PLUGIN: canal
|
||||
CLOUD_IMAGE: ubuntu-1604-xenial
|
||||
CLOUD_REGION: europe-west1-b
|
||||
CLOUD_MACHINE_TYPE: "n1-standard-2"
|
||||
UPGRADE_TEST: "basic"
|
||||
CLOUD_IMAGE: debian-8-kubespray
|
||||
CLOUD_REGION: us-east1-b
|
||||
CLUSTER_MODE: ha
|
||||
UPGRADE_TEST: "graceful"
|
||||
|
||||
.rhel7_weave_variables: &rhel7_weave_variables
|
||||
# stage: deploy-gce-part1
|
||||
@@ -296,12 +247,12 @@ before_script:
|
||||
.coreos_canal_variables: &coreos_canal_variables
|
||||
# stage: deploy-gce-part2
|
||||
KUBE_NETWORK_PLUGIN: canal
|
||||
CLOUD_IMAGE: coreos-stable-1298-6-0-v20170315
|
||||
CLOUD_IMAGE: coreos-stable-1235-6-0-v20170111
|
||||
CLOUD_REGION: us-east1-b
|
||||
CLUSTER_MODE: default
|
||||
BOOTSTRAP_OS: coreos
|
||||
IDEMPOT_CHECK: "true"
|
||||
RESOLVCONF_MODE: host_resolvconf # This is required as long as the CoreOS stable channel uses docker < 1.12
|
||||
IDEMPOT_CHECK: "true"
|
||||
|
||||
.rhel7_canal_sep_variables: &rhel7_canal_sep_variables
|
||||
# stage: deploy-gce-special
|
||||
@@ -321,21 +272,18 @@ before_script:
|
||||
.centos7_calico_ha_variables: ¢os7_calico_ha_variables
|
||||
# stage: deploy-gce-special
|
||||
KUBE_NETWORK_PLUGIN: calico
|
||||
DOWNLOAD_LOCALHOST: "true"
|
||||
DOWNLOAD_RUN_ONCE: "true"
|
||||
CLOUD_IMAGE: centos-7
|
||||
CLOUD_REGION: europe-west1-b
|
||||
CLUSTER_MODE: ha-scale
|
||||
CLUSTER_MODE: ha
|
||||
IDEMPOT_CHECK: "true"
|
||||
|
||||
.coreos_alpha_weave_ha_variables: &coreos_alpha_weave_ha_variables
|
||||
# stage: deploy-gce-special
|
||||
KUBE_NETWORK_PLUGIN: weave
|
||||
CLOUD_IMAGE: coreos-alpha-1325-0-0-v20170216
|
||||
CLOUD_IMAGE: coreos-alpha
|
||||
CLOUD_REGION: us-west1-a
|
||||
CLUSTER_MODE: ha-scale
|
||||
CLUSTER_MODE: ha
|
||||
BOOTSTRAP_OS: coreos
|
||||
RESOLVCONF_MODE: host_resolvconf # This is required as long as the CoreOS stable channel uses docker < 1.12
|
||||
|
||||
.ubuntu_rkt_sep_variables: &ubuntu_rkt_sep_variables
|
||||
# stage: deploy-gce-part1
|
||||
@@ -346,14 +294,6 @@ before_script:
|
||||
ETCD_DEPLOYMENT: rkt
|
||||
KUBELET_DEPLOYMENT: rkt
|
||||
|
||||
.ubuntu_vault_sep_variables: &ubuntu_vault_sep_variables
|
||||
# stage: deploy-gce-part1
|
||||
KUBE_NETWORK_PLUGIN: canal
|
||||
CERT_MGMT: vault
|
||||
CLOUD_IMAGE: ubuntu-1604-xenial
|
||||
CLOUD_REGION: us-central1-b
|
||||
CLUSTER_MODE: separate
|
||||
|
||||
# Builds for PRs only (premoderated by unit-tests step) and triggers (auto)
|
||||
coreos-calico-sep:
|
||||
stage: deploy-gce-part1
|
||||
@@ -419,24 +359,24 @@ ubuntu-weave-sep-triggers:
|
||||
only: ['triggers']
|
||||
|
||||
# More builds for PRs/merges (manual) and triggers (auto)
|
||||
ubuntu-canal-ha:
|
||||
debian8-canal-ha:
|
||||
stage: deploy-gce-part1
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_canal_ha_variables
|
||||
<<: *debian8_canal_ha_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
ubuntu-canal-ha-triggers:
|
||||
debian8-canal-ha-triggers:
|
||||
stage: deploy-gce-part1
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_canal_ha_variables
|
||||
<<: *debian8_canal_ha_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
@@ -461,7 +401,7 @@ rhel7-weave-triggers:
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
debian8-calico-upgrade:
|
||||
debian8-calico:
|
||||
stage: deploy-gce-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
@@ -568,17 +508,6 @@ ubuntu-rkt-sep:
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
ubuntu-vault-sep:
|
||||
stage: deploy-gce-part1
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_vault_sep_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
# Premoderated with manual actions
|
||||
ci-authorized:
|
||||
<<: *job
|
||||
@@ -594,8 +523,6 @@ syntax-check:
|
||||
stage: unit-tests
|
||||
script:
|
||||
- ansible-playbook -i inventory/local-tests.cfg -u root -e ansible_ssh_user=root -b --become-user=root cluster.yml -vvv --syntax-check
|
||||
- ansible-playbook -i inventory/local-tests.cfg -u root -e ansible_ssh_user=root -b --become-user=root upgrade-cluster.yml -vvv --syntax-check
|
||||
- ansible-playbook -i inventory/local-tests.cfg -u root -e ansible_ssh_user=root -b --become-user=root reset.yml -vvv --syntax-check
|
||||
except: ['triggers', 'master']
|
||||
|
||||
tox-inventory-builder:
|
||||
|
||||
28
README.md
28
README.md
@@ -1,6 +1,6 @@
|
||||

|
||||
|
||||
## Deploy a production ready kubernetes cluster
|
||||
##Deploy a production ready kubernetes cluster
|
||||
|
||||
If you have questions, join us on the [kubernetes slack](https://slack.k8s.io), channel **#kargo**.
|
||||
|
||||
@@ -55,7 +55,7 @@ Versions of supported components
|
||||
[flanneld](https://github.com/coreos/flannel/releases) v0.6.2 <br>
|
||||
[calicoctl](https://github.com/projectcalico/calico-docker/releases) v0.23.0 <br>
|
||||
[canal](https://github.com/projectcalico/canal) (given calico/flannel versions) <br>
|
||||
[weave](http://weave.works/) v1.8.2 <br>
|
||||
[weave](http://weave.works/) v1.6.1 <br>
|
||||
[docker](https://www.docker.com/) v1.12.5 <br>
|
||||
[rkt](https://coreos.com/rkt/docs/latest/) v1.21.0 <br>
|
||||
|
||||
@@ -67,18 +67,16 @@ plugins can be deployed for a given single cluster.
|
||||
Requirements
|
||||
--------------
|
||||
|
||||
* **Ansible v2.2 (or newer) and python-netaddr is installed on the machine
|
||||
that will run Ansible commands**
|
||||
* **Jinja 2.8 (or newer) is required to run the Ansible Playbooks**
|
||||
* The target servers must have **access to the Internet** in order to pull docker images.
|
||||
* The target servers are configured to allow **IPv4 forwarding**.
|
||||
* **Your ssh key must be copied** to all the servers part of your inventory.
|
||||
* The **firewalls are not managed**, you'll need to implement your own rules the way you used to.
|
||||
in order to avoid any issue during deployment you should disable your firewall.
|
||||
* The target servers are configured to allow **IPv4 forwarding**.
|
||||
* **Copy your ssh keys** to all the servers part of your inventory.
|
||||
* **Ansible v2.2 (or newer) and python-netaddr**
|
||||
|
||||
|
||||
## Network plugins
|
||||
You can choose between 4 network plugins. (default: `calico`)
|
||||
You can choose between 4 network plugins. (default: `flannel` with vxlan backend)
|
||||
|
||||
* [**flannel**](docs/flannel.md): gre/vxlan (layer 2) networking.
|
||||
|
||||
@@ -93,23 +91,11 @@ The choice is defined with the variable `kube_network_plugin`. There is also an
|
||||
option to leverage built-in cloud provider networking instead.
|
||||
See also [Network checker](docs/netcheck.md).
|
||||
|
||||
## Community docs and resources
|
||||
- [kubernetes.io/docs/getting-started-guides/kargo/](https://kubernetes.io/docs/getting-started-guides/kargo/)
|
||||
- [kargo, monitoring and logging](https://github.com/gregbkr/kubernetes-kargo-logging-monitoring) by @gregbkr
|
||||
- [Deploy Kubernetes w/ Ansible & Terraform](https://rsmitty.github.io/Terraform-Ansible-Kubernetes/) by @rsmitty
|
||||
- [Deploy a Kubernets Cluster with Kargo (video)](https://www.youtube.com/watch?v=N9q51JgbWu8)
|
||||
|
||||
## Tools and projects on top of Kargo
|
||||
- [Digital Rebar](https://github.com/digitalrebar/digitalrebar)
|
||||
- [Kargo-cli](https://github.com/kubespray/kargo-cli)
|
||||
- [Fuel-ccp-installer](https://github.com/openstack/fuel-ccp-installer)
|
||||
- [Terraform Contrib](https://github.com/kubernetes-incubator/kargo/tree/master/contrib/terraform)
|
||||
|
||||
## CI Tests
|
||||
|
||||

|
||||
|
||||
[](https://gitlab.com/kargo-ci/kubernetes-incubator__kargo/pipelines) </br>
|
||||
|
||||
CI/end-to-end tests sponsored by Google (GCE), DigitalOcean, [teuto.net](https://teuto.net/) (openstack).
|
||||
CI/end-to-end tests sponsored by Google (GCE), and [teuto.net](https://teuto.net/) for OpenStack.
|
||||
See the [test matrix](docs/test_cases.md) for details.
|
||||
|
||||
@@ -38,3 +38,6 @@ The Kargo Project is released on an as-needed basis. The process is as follows:
|
||||
then Kargo v2.1.0 may be bound to only minor changes to ``kube_version``, like v1.5.1
|
||||
and *any* changes to other components, like etcd v4, or calico 1.2.3.
|
||||
And Kargo v3.x.x shall be bound to ``kube_version: 2.x.x`` respectively.
|
||||
foo
|
||||
foo
|
||||
foo
|
||||
|
||||
30
Vagrantfile
vendored
30
Vagrantfile
vendored
@@ -17,13 +17,6 @@ $shared_folders = {}
|
||||
$forwarded_ports = {}
|
||||
$subnet = "172.17.8"
|
||||
$box = "bento/ubuntu-16.04"
|
||||
# The first three nodes are etcd servers
|
||||
$etcd_instances = $num_instances
|
||||
# The first two nodes are masters
|
||||
$kube_master_instances = $num_instances == 1 ? $num_instances : ($num_instances - 1)
|
||||
# All nodes are kube nodes
|
||||
$kube_node_instances = $num_instances
|
||||
$local_release_dir = "/vagrant/temp"
|
||||
|
||||
host_vars = {}
|
||||
|
||||
@@ -95,14 +88,12 @@ Vagrant.configure("2") do |config|
|
||||
|
||||
ip = "#{$subnet}.#{i+100}"
|
||||
host_vars[vm_name] = {
|
||||
"ip": ip,
|
||||
"flannel_interface": ip,
|
||||
"flannel_backend_type": "host-gw",
|
||||
"local_release_dir" => $local_release_dir,
|
||||
"download_run_once": "False",
|
||||
# Override the default 'calico' with flannel.
|
||||
# inventory/group_vars/k8s-cluster.yml
|
||||
"kube_network_plugin": "flannel",
|
||||
"ip" => ip,
|
||||
#"access_ip" => ip,
|
||||
"flannel_interface" => ip,
|
||||
"flannel_backend_type" => "host-gw",
|
||||
"local_release_dir" => "/vagrant/temp",
|
||||
"download_run_once" => "False"
|
||||
}
|
||||
config.vm.network :private_network, ip: ip
|
||||
|
||||
@@ -121,9 +112,12 @@ Vagrant.configure("2") do |config|
|
||||
ansible.host_vars = host_vars
|
||||
#ansible.tags = ['download']
|
||||
ansible.groups = {
|
||||
"etcd" => ["#{$instance_name_prefix}-0[1:#{$etcd_instances}]"],
|
||||
"kube-master" => ["#{$instance_name_prefix}-0[1:#{$kube_master_instances}]"],
|
||||
"kube-node" => ["#{$instance_name_prefix}-0[1:#{$kube_node_instances}]"],
|
||||
# The first three nodes should be etcd servers
|
||||
"etcd" => ["#{$instance_name_prefix}-0[1:3]"],
|
||||
# The first two nodes should be masters
|
||||
"kube-master" => ["#{$instance_name_prefix}-0[1:2]"],
|
||||
# all nodes should be kube nodes
|
||||
"kube-node" => ["#{$instance_name_prefix}-0[1:#{$num_instances}]"],
|
||||
"k8s-cluster:children" => ["kube-master", "kube-node"],
|
||||
}
|
||||
end
|
||||
|
||||
@@ -9,4 +9,3 @@ fact_caching = jsonfile
|
||||
fact_caching_connection = /tmp
|
||||
stdout_callback = skippy
|
||||
library = ./library
|
||||
callback_whitelist = profile_tasks
|
||||
|
||||
63
cluster.yml
63
cluster.yml
@@ -2,91 +2,64 @@
|
||||
- hosts: localhost
|
||||
gather_facts: False
|
||||
roles:
|
||||
- { role: kargo-defaults}
|
||||
- { role: bastion-ssh-config, tags: ["localhost", "bastion"]}
|
||||
- bastion-ssh-config
|
||||
tags: [localhost, bastion]
|
||||
|
||||
- hosts: k8s-cluster:etcd:calico-rr
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
any_errors_fatal: true
|
||||
gather_facts: false
|
||||
vars:
|
||||
# Need to disable pipelining for bootstrap-os as some systems have requiretty in sudoers set, which makes pipelining
|
||||
# fail. bootstrap-os fixes this on these systems, so in later plays it can be enabled.
|
||||
ansible_ssh_pipelining: false
|
||||
roles:
|
||||
- { role: kargo-defaults}
|
||||
- { role: bootstrap-os, tags: bootstrap-os}
|
||||
- bootstrap-os
|
||||
tags:
|
||||
- bootstrap-os
|
||||
|
||||
- hosts: k8s-cluster:etcd:calico-rr
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
any_errors_fatal: true
|
||||
vars:
|
||||
ansible_ssh_pipelining: true
|
||||
gather_facts: true
|
||||
|
||||
- hosts: k8s-cluster:etcd:calico-rr
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
any_errors_fatal: true
|
||||
roles:
|
||||
- { role: kargo-defaults}
|
||||
- { role: kernel-upgrade, tags: kernel-upgrade, when: kernel_upgrade is defined and kernel_upgrade }
|
||||
- { role: kubernetes/preinstall, tags: preinstall }
|
||||
- { role: docker, tags: docker }
|
||||
- role: rkt
|
||||
tags: rkt
|
||||
when: "'rkt' in [etcd_deployment_type, kubelet_deployment_type, vault_deployment_type]"
|
||||
- { role: rkt, tags: rkt, when: "'rkt' in [ etcd_deployment_type, kubelet_deployment_type ]" }
|
||||
|
||||
- hosts: etcd:k8s-cluster:vault
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
- hosts: etcd:!k8s-cluster
|
||||
any_errors_fatal: true
|
||||
roles:
|
||||
- { role: kargo-defaults, when: "cert_management == 'vault'" }
|
||||
- { role: vault, tags: vault, vault_bootstrap: true, when: "cert_management == 'vault'" }
|
||||
|
||||
- hosts: etcd
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
roles:
|
||||
- { role: kargo-defaults}
|
||||
- { role: etcd, tags: etcd, etcd_cluster_setup: true }
|
||||
- { role: etcd, tags: etcd }
|
||||
|
||||
- hosts: k8s-cluster
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
any_errors_fatal: true
|
||||
roles:
|
||||
- { role: kargo-defaults}
|
||||
- { role: etcd, tags: etcd, etcd_cluster_setup: false }
|
||||
|
||||
- hosts: etcd:k8s-cluster:vault
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
roles:
|
||||
- { role: kargo-defaults}
|
||||
- { role: vault, tags: vault, when: "cert_management == 'vault'"}
|
||||
|
||||
- hosts: k8s-cluster
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
roles:
|
||||
- { role: kargo-defaults}
|
||||
- { role: etcd, tags: etcd }
|
||||
- { role: kubernetes/node, tags: node }
|
||||
- { role: network_plugin, tags: network }
|
||||
|
||||
- hosts: kube-master
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
any_errors_fatal: true
|
||||
roles:
|
||||
- { role: kargo-defaults}
|
||||
- { role: kubernetes/master, tags: master }
|
||||
- { role: kubernetes-apps/network_plugin, tags: network }
|
||||
- { role: kubernetes-apps/policy_controller, tags: policy-controller }
|
||||
|
||||
- hosts: calico-rr
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
any_errors_fatal: true
|
||||
roles:
|
||||
- { role: kargo-defaults}
|
||||
- { role: network_plugin/calico/rr, tags: network }
|
||||
|
||||
- hosts: k8s-cluster
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
any_errors_fatal: true
|
||||
roles:
|
||||
- { role: kargo-defaults}
|
||||
- { role: dnsmasq, when: "dns_mode == 'dnsmasq_kubedns'", tags: dnsmasq }
|
||||
- { role: kubernetes/preinstall, when: "dns_mode != 'none' and resolvconf_mode == 'host_resolvconf'", tags: resolvconf }
|
||||
|
||||
- hosts: kube-master[0]
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
any_errors_fatal: true
|
||||
roles:
|
||||
- { role: kargo-defaults}
|
||||
- { role: kubernetes-apps, tags: apps }
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["ec2:*"],
|
||||
"Resource": ["*"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["elasticloadbalancing:*"],
|
||||
"Resource": ["*"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["route53:*"],
|
||||
"Resource": ["*"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "s3:*",
|
||||
"Resource": [
|
||||
"arn:aws:s3:::kubernetes-*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": { "Service": "ec2.amazonaws.com"},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "s3:*",
|
||||
"Resource": [
|
||||
"arn:aws:s3:::kubernetes-*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:Describe*",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:AttachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:DetachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["route53:*"],
|
||||
"Resource": ["*"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"ecr:GetAuthorizationToken",
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:GetDownloadUrlForLayer",
|
||||
"ecr:GetRepositoryPolicy",
|
||||
"ecr:DescribeRepositories",
|
||||
"ecr:ListImages",
|
||||
"ecr:BatchGetImage"
|
||||
],
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": { "Service": "ec2.amazonaws.com"},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
# Kargo on KVM Virtual Machines hypervisor preparation
|
||||
|
||||
A simple playbook to ensure your system has the right settings to enable Kargo
|
||||
deployment on VMs.
|
||||
|
||||
This playbook does not create Virtual Machines, nor does it run Kargo itself.
|
||||
|
||||
### User creation
|
||||
|
||||
If you want to create a user for running Kargo deployment, you should specify
|
||||
both `k8s_deployment_user` and `k8s_deployment_user_pkey_path`.
|
||||
@@ -1,3 +0,0 @@
|
||||
#k8s_deployment_user: kargo
|
||||
#k8s_deployment_user_pkey_path: /tmp/ssh_rsa
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
- hosts: localhost
|
||||
gather_facts: False
|
||||
become: yes
|
||||
vars:
|
||||
- bootstrap_os: none
|
||||
roles:
|
||||
- kvm-setup
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
|
||||
- name: Upgrade all packages to the latest version (yum)
|
||||
yum:
|
||||
name: '*'
|
||||
state: latest
|
||||
when: ansible_os_family == "RedHat"
|
||||
|
||||
- name: Install required packages
|
||||
yum:
|
||||
name: "{{ item }}"
|
||||
state: latest
|
||||
with_items:
|
||||
- bind-utils
|
||||
- ntp
|
||||
when: ansible_os_family == "RedHat"
|
||||
|
||||
- name: Install required packages
|
||||
apt:
|
||||
upgrade: yes
|
||||
update_cache: yes
|
||||
cache_valid_time: 3600
|
||||
name: "{{ item }}"
|
||||
state: latest
|
||||
install_recommends: no
|
||||
with_items:
|
||||
- dnsutils
|
||||
- ntp
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
- name: Upgrade all packages to the latest version (apt)
|
||||
shell: apt-get -o \
|
||||
Dpkg::Options::=--force-confdef -o \
|
||||
Dpkg::Options::=--force-confold -q -y \
|
||||
dist-upgrade
|
||||
environment:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
when: ansible_os_family == "Debian"
|
||||
|
||||
|
||||
# Create deployment user if required
|
||||
- include: user.yml
|
||||
when: k8s_deployment_user is defined
|
||||
|
||||
# Set proper sysctl values
|
||||
- include: sysctl.yml
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
- name: Load br_netfilter module
|
||||
modprobe:
|
||||
name: br_netfilter
|
||||
state: present
|
||||
register: br_netfilter
|
||||
|
||||
- name: Add br_netfilter into /etc/modules
|
||||
lineinfile:
|
||||
dest: /etc/modules
|
||||
state: present
|
||||
line: 'br_netfilter'
|
||||
when: br_netfilter is defined and ansible_os_family == 'Debian'
|
||||
|
||||
- name: Add br_netfilter into /etc/modules-load.d/kargo.conf
|
||||
copy:
|
||||
dest: /etc/modules-load.d/kargo.conf
|
||||
content: |-
|
||||
### This file is managed by Ansible
|
||||
br-netfilter
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
when: br_netfilter is defined
|
||||
|
||||
|
||||
- name: Enable net.ipv4.ip_forward in sysctl
|
||||
sysctl:
|
||||
name: net.ipv4.ip_forward
|
||||
value: 1
|
||||
sysctl_file: /etc/sysctl.d/ipv4-ip_forward.conf
|
||||
state: present
|
||||
reload: yes
|
||||
|
||||
- name: Set bridge-nf-call-{arptables,iptables} to 0
|
||||
sysctl:
|
||||
name: "{{ item }}"
|
||||
state: present
|
||||
value: 0
|
||||
sysctl_file: /etc/sysctl.d/bridge-nf-call.conf
|
||||
reload: yes
|
||||
with_items:
|
||||
- net.bridge.bridge-nf-call-arptables
|
||||
- net.bridge.bridge-nf-call-ip6tables
|
||||
- net.bridge.bridge-nf-call-iptables
|
||||
when: br_netfilter is defined
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
- name: Create user {{ k8s_deployment_user }}
|
||||
user:
|
||||
name: "{{ k8s_deployment_user }}"
|
||||
groups: adm
|
||||
shell: /bin/bash
|
||||
|
||||
- name: Ensure that .ssh exists
|
||||
file:
|
||||
path: "/home/{{ k8s_deployment_user }}/.ssh"
|
||||
state: directory
|
||||
owner: "{{ k8s_deployment_user }}"
|
||||
group: "{{ k8s_deployment_user }}"
|
||||
|
||||
- name: Configure sudo for deployment user
|
||||
copy:
|
||||
content: |
|
||||
%{{ k8s_deployment_user }} ALL=(ALL) NOPASSWD: ALL
|
||||
dest: "/etc/sudoers.d/55-k8s-deployment"
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
|
||||
- name: Write private SSH key
|
||||
copy:
|
||||
src: "{{ k8s_deployment_user_pkey_path }}"
|
||||
dest: "/home/{{ k8s_deployment_user }}/.ssh/id_rsa"
|
||||
mode: 0400
|
||||
owner: "{{ k8s_deployment_user }}"
|
||||
group: "{{ k8s_deployment_user }}"
|
||||
when: k8s_deployment_user_pkey_path is defined
|
||||
|
||||
- name: Write public SSH key
|
||||
shell: "ssh-keygen -y -f /home/{{ k8s_deployment_user }}/.ssh/id_rsa \
|
||||
> /home/{{ k8s_deployment_user }}/.ssh/authorized_keys"
|
||||
args:
|
||||
creates: "/home/{{ k8s_deployment_user }}/.ssh/authorized_keys"
|
||||
when: k8s_deployment_user_pkey_path is defined
|
||||
|
||||
- name: Fix ssh-pub-key permissions
|
||||
file:
|
||||
path: "/home/{{ k8s_deployment_user }}/.ssh/authorized_keys"
|
||||
mode: 0600
|
||||
owner: "{{ k8s_deployment_user }}"
|
||||
group: "{{ k8s_deployment_user }}"
|
||||
when: k8s_deployment_user_pkey_path is defined
|
||||
2
contrib/terraform/aws/.gitignore
vendored
2
contrib/terraform/aws/.gitignore
vendored
@@ -1,2 +1,2 @@
|
||||
*.tfstate*
|
||||
.terraform
|
||||
inventory
|
||||
|
||||
261
contrib/terraform/aws/00-create-infrastructure.tf
Executable file
261
contrib/terraform/aws/00-create-infrastructure.tf
Executable file
@@ -0,0 +1,261 @@
|
||||
variable "deploymentName" {
|
||||
type = "string"
|
||||
description = "The desired name of your deployment."
|
||||
}
|
||||
|
||||
variable "numControllers"{
|
||||
type = "string"
|
||||
description = "Desired # of controllers."
|
||||
}
|
||||
|
||||
variable "numEtcd" {
|
||||
type = "string"
|
||||
description = "Desired # of etcd nodes. Should be an odd number."
|
||||
}
|
||||
|
||||
variable "numNodes" {
|
||||
type = "string"
|
||||
description = "Desired # of nodes."
|
||||
}
|
||||
|
||||
variable "volSizeController" {
|
||||
type = "string"
|
||||
description = "Volume size for the controllers (GB)."
|
||||
}
|
||||
|
||||
variable "volSizeEtcd" {
|
||||
type = "string"
|
||||
description = "Volume size for etcd (GB)."
|
||||
}
|
||||
|
||||
variable "volSizeNodes" {
|
||||
type = "string"
|
||||
description = "Volume size for nodes (GB)."
|
||||
}
|
||||
|
||||
variable "subnet" {
|
||||
type = "string"
|
||||
description = "The subnet in which to put your cluster."
|
||||
}
|
||||
|
||||
variable "securityGroups" {
|
||||
type = "string"
|
||||
description = "The sec. groups in which to put your cluster."
|
||||
}
|
||||
|
||||
variable "ami"{
|
||||
type = "string"
|
||||
description = "AMI to use for all VMs in cluster."
|
||||
}
|
||||
|
||||
variable "SSHKey" {
|
||||
type = "string"
|
||||
description = "SSH key to use for VMs."
|
||||
}
|
||||
|
||||
variable "master_instance_type" {
|
||||
type = "string"
|
||||
description = "Size of VM to use for masters."
|
||||
}
|
||||
|
||||
variable "etcd_instance_type" {
|
||||
type = "string"
|
||||
description = "Size of VM to use for etcd."
|
||||
}
|
||||
|
||||
variable "node_instance_type" {
|
||||
type = "string"
|
||||
description = "Size of VM to use for nodes."
|
||||
}
|
||||
|
||||
variable "terminate_protect" {
|
||||
type = "string"
|
||||
default = "false"
|
||||
}
|
||||
|
||||
variable "awsRegion" {
|
||||
type = "string"
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
region = "${var.awsRegion}"
|
||||
}
|
||||
|
||||
variable "iam_prefix" {
|
||||
type = "string"
|
||||
description = "Prefix name for IAM profiles"
|
||||
}
|
||||
|
||||
resource "aws_iam_instance_profile" "kubernetes_master_profile" {
|
||||
name = "${var.iam_prefix}_kubernetes_master_profile"
|
||||
roles = ["${aws_iam_role.kubernetes_master_role.name}"]
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "kubernetes_master_role" {
|
||||
name = "${var.iam_prefix}_kubernetes_master_role"
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": { "Service": "ec2.amazonaws.com"},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "kubernetes_master_policy" {
|
||||
name = "${var.iam_prefix}_kubernetes_master_policy"
|
||||
role = "${aws_iam_role.kubernetes_master_role.id}"
|
||||
policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["ec2:*"],
|
||||
"Resource": ["*"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["elasticloadbalancing:*"],
|
||||
"Resource": ["*"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "s3:*",
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_iam_instance_profile" "kubernetes_node_profile" {
|
||||
name = "${var.iam_prefix}_kubernetes_node_profile"
|
||||
roles = ["${aws_iam_role.kubernetes_node_role.name}"]
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "kubernetes_node_role" {
|
||||
name = "${var.iam_prefix}_kubernetes_node_role"
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Principal": { "Service": "ec2.amazonaws.com"},
|
||||
"Action": "sts:AssumeRole"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "kubernetes_node_policy" {
|
||||
name = "${var.iam_prefix}_kubernetes_node_policy"
|
||||
role = "${aws_iam_role.kubernetes_node_role.id}"
|
||||
policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "s3:*",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:Describe*",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:AttachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:DetachVolume",
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_instance" "master" {
|
||||
count = "${var.numControllers}"
|
||||
ami = "${var.ami}"
|
||||
instance_type = "${var.master_instance_type}"
|
||||
subnet_id = "${var.subnet}"
|
||||
vpc_security_group_ids = ["${var.securityGroups}"]
|
||||
key_name = "${var.SSHKey}"
|
||||
disable_api_termination = "${var.terminate_protect}"
|
||||
iam_instance_profile = "${aws_iam_instance_profile.kubernetes_master_profile.id}"
|
||||
root_block_device {
|
||||
volume_size = "${var.volSizeController}"
|
||||
}
|
||||
tags {
|
||||
Name = "${var.deploymentName}-master-${count.index + 1}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_instance" "etcd" {
|
||||
count = "${var.numEtcd}"
|
||||
ami = "${var.ami}"
|
||||
instance_type = "${var.etcd_instance_type}"
|
||||
subnet_id = "${var.subnet}"
|
||||
vpc_security_group_ids = ["${var.securityGroups}"]
|
||||
key_name = "${var.SSHKey}"
|
||||
disable_api_termination = "${var.terminate_protect}"
|
||||
root_block_device {
|
||||
volume_size = "${var.volSizeEtcd}"
|
||||
}
|
||||
tags {
|
||||
Name = "${var.deploymentName}-etcd-${count.index + 1}"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
resource "aws_instance" "minion" {
|
||||
count = "${var.numNodes}"
|
||||
ami = "${var.ami}"
|
||||
instance_type = "${var.node_instance_type}"
|
||||
subnet_id = "${var.subnet}"
|
||||
vpc_security_group_ids = ["${var.securityGroups}"]
|
||||
key_name = "${var.SSHKey}"
|
||||
disable_api_termination = "${var.terminate_protect}"
|
||||
iam_instance_profile = "${aws_iam_instance_profile.kubernetes_node_profile.id}"
|
||||
root_block_device {
|
||||
volume_size = "${var.volSizeNodes}"
|
||||
}
|
||||
tags {
|
||||
Name = "${var.deploymentName}-minion-${count.index + 1}"
|
||||
}
|
||||
}
|
||||
|
||||
output "kubernetes_master_profile" {
|
||||
value = "${aws_iam_instance_profile.kubernetes_master_profile.id}"
|
||||
}
|
||||
|
||||
output "kubernetes_node_profile" {
|
||||
value = "${aws_iam_instance_profile.kubernetes_node_profile.id}"
|
||||
}
|
||||
|
||||
output "master-ip" {
|
||||
value = "${join(", ", aws_instance.master.*.private_ip)}"
|
||||
}
|
||||
|
||||
output "etcd-ip" {
|
||||
value = "${join(", ", aws_instance.etcd.*.private_ip)}"
|
||||
}
|
||||
|
||||
output "minion-ip" {
|
||||
value = "${join(", ", aws_instance.minion.*.private_ip)}"
|
||||
}
|
||||
|
||||
|
||||
37
contrib/terraform/aws/01-create-inventory.tf
Executable file
37
contrib/terraform/aws/01-create-inventory.tf
Executable file
@@ -0,0 +1,37 @@
|
||||
variable "SSHUser" {
|
||||
type = "string"
|
||||
description = "SSH User for VMs."
|
||||
}
|
||||
|
||||
resource "null_resource" "ansible-provision" {
|
||||
|
||||
depends_on = ["aws_instance.master","aws_instance.etcd","aws_instance.minion"]
|
||||
|
||||
##Create Master Inventory
|
||||
provisioner "local-exec" {
|
||||
command = "echo \"[kube-master]\" > inventory"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "echo \"${join("\n",formatlist("%s ansible_ssh_user=%s", aws_instance.master.*.private_ip, var.SSHUser))}\" >> inventory"
|
||||
}
|
||||
|
||||
##Create ETCD Inventory
|
||||
provisioner "local-exec" {
|
||||
command = "echo \"\n[etcd]\" >> inventory"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "echo \"${join("\n",formatlist("%s ansible_ssh_user=%s", aws_instance.etcd.*.private_ip, var.SSHUser))}\" >> inventory"
|
||||
}
|
||||
|
||||
##Create Nodes Inventory
|
||||
provisioner "local-exec" {
|
||||
command = "echo \"\n[kube-node]\" >> inventory"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "echo \"${join("\n",formatlist("%s ansible_ssh_user=%s", aws_instance.minion.*.private_ip, var.SSHUser))}\" >> inventory"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "echo \"\n[k8s-cluster:children]\nkube-node\nkube-master\" >> inventory"
|
||||
}
|
||||
}
|
||||
@@ -2,34 +2,27 @@
|
||||
|
||||
**Overview:**
|
||||
|
||||
This project will create:
|
||||
* VPC with Public and Private Subnets in # Availability Zones
|
||||
* Bastion Hosts and NAT Gateways in the Public Subnet
|
||||
* A dynamic number of masters, etcd, and worker nodes in the Private Subnet
|
||||
* even distributed over the # of Availability Zones
|
||||
* AWS ELB in the Public Subnet for accessing the Kubernetes API from the internet
|
||||
- This will create nodes in a VPC inside of AWS
|
||||
|
||||
**Requirements**
|
||||
- Terraform 0.8.7 or newer
|
||||
- A dynamic number of masters, etcd, and nodes can be created
|
||||
|
||||
- These scripts currently expect Private IP connectivity with the nodes that are created. This means that you may need a tunnel to your VPC or to run these scripts from a VM inside the VPC. Will be looking into how to work around this later.
|
||||
|
||||
**How to Use:**
|
||||
|
||||
- Export the variables for your AWS credentials or edit credentials.tfvars:
|
||||
- Export the variables for your Amazon credentials:
|
||||
|
||||
```
|
||||
export aws_access_key="xxx"
|
||||
export aws_secret_key="yyy"
|
||||
export aws_ssh_key_name="zzz"
|
||||
export AWS_ACCESS_KEY_ID="xxx"
|
||||
export AWS_SECRET_ACCESS_KEY="yyy"
|
||||
```
|
||||
|
||||
- Update contrib/terraform/aws/terraform.tfvars with your data
|
||||
|
||||
- Run with `terraform apply -var-file="credentials.tfvars"` or `terraform apply` depending if you exported your AWS credentials
|
||||
- Run with `terraform apply`
|
||||
|
||||
- Once the infrastructure is created, you can run the kargo playbooks and supply inventory/hosts with the `-i` flag.
|
||||
- Once the infrastructure is created, you can run the kubespray playbooks and supply contrib/terraform/aws/inventory with the `-i` flag.
|
||||
|
||||
**Architecture**
|
||||
**Future Work:**
|
||||
|
||||
Pictured is an AWS Infrastructure created with this Terraform project distributed over two Availability Zones.
|
||||
|
||||

|
||||
- Update the inventory creation file to be something a little more reasonable. It's just a local-exec from Terraform now, using terraform.py or something may make sense in the future.
|
||||
@@ -1,185 +0,0 @@
|
||||
terraform {
|
||||
required_version = ">= 0.8.7"
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
access_key = "${var.AWS_ACCESS_KEY_ID}"
|
||||
secret_key = "${var.AWS_SECRET_ACCESS_KEY}"
|
||||
region = "${var.AWS_DEFAULT_REGION}"
|
||||
}
|
||||
|
||||
/*
|
||||
* Calling modules who create the initial AWS VPC / AWS ELB
|
||||
* and AWS IAM Roles for Kubernetes Deployment
|
||||
*/
|
||||
|
||||
module "aws-vpc" {
|
||||
source = "modules/vpc"
|
||||
|
||||
aws_cluster_name = "${var.aws_cluster_name}"
|
||||
aws_vpc_cidr_block = "${var.aws_vpc_cidr_block}"
|
||||
aws_avail_zones="${var.aws_avail_zones}"
|
||||
|
||||
aws_cidr_subnets_private="${var.aws_cidr_subnets_private}"
|
||||
aws_cidr_subnets_public="${var.aws_cidr_subnets_public}"
|
||||
|
||||
}
|
||||
|
||||
|
||||
module "aws-elb" {
|
||||
source = "modules/elb"
|
||||
|
||||
aws_cluster_name="${var.aws_cluster_name}"
|
||||
aws_vpc_id="${module.aws-vpc.aws_vpc_id}"
|
||||
aws_avail_zones="${var.aws_avail_zones}"
|
||||
aws_subnet_ids_public="${module.aws-vpc.aws_subnet_ids_public}"
|
||||
aws_elb_api_port = "${var.aws_elb_api_port}"
|
||||
k8s_secure_api_port = "${var.k8s_secure_api_port}"
|
||||
|
||||
}
|
||||
|
||||
module "aws-iam" {
|
||||
source = "modules/iam"
|
||||
|
||||
aws_cluster_name="${var.aws_cluster_name}"
|
||||
}
|
||||
|
||||
/*
|
||||
* Create Bastion Instances in AWS
|
||||
*
|
||||
*/
|
||||
resource "aws_instance" "bastion-server" {
|
||||
ami = "${var.aws_bastion_ami}"
|
||||
instance_type = "${var.aws_bastion_size}"
|
||||
count = "${length(var.aws_cidr_subnets_public)}"
|
||||
associate_public_ip_address = true
|
||||
availability_zone = "${element(var.aws_avail_zones,count.index)}"
|
||||
subnet_id = "${element(module.aws-vpc.aws_subnet_ids_public,count.index)}"
|
||||
|
||||
|
||||
vpc_security_group_ids = [ "${module.aws-vpc.aws_security_group}" ]
|
||||
|
||||
key_name = "${var.AWS_SSH_KEY_NAME}"
|
||||
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-bastion-${count.index}"
|
||||
Cluster = "${var.aws_cluster_name}"
|
||||
Role = "bastion-${var.aws_cluster_name}-${count.index}"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create K8s Master and worker nodes and etcd instances
|
||||
*
|
||||
*/
|
||||
|
||||
resource "aws_instance" "k8s-master" {
|
||||
ami = "${var.aws_cluster_ami}"
|
||||
instance_type = "${var.aws_kube_master_size}"
|
||||
|
||||
count = "${var.aws_kube_master_num}"
|
||||
|
||||
|
||||
availability_zone = "${element(var.aws_avail_zones,count.index)}"
|
||||
subnet_id = "${element(module.aws-vpc.aws_subnet_ids_private,count.index)}"
|
||||
|
||||
|
||||
vpc_security_group_ids = [ "${module.aws-vpc.aws_security_group}" ]
|
||||
|
||||
|
||||
iam_instance_profile = "${module.aws-iam.kube-master-profile}"
|
||||
key_name = "${var.AWS_SSH_KEY_NAME}"
|
||||
|
||||
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-master${count.index}"
|
||||
Cluster = "${var.aws_cluster_name}"
|
||||
Role = "master"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_elb_attachment" "attach_master_nodes" {
|
||||
count = "${var.aws_kube_master_num}"
|
||||
elb = "${module.aws-elb.aws_elb_api_id}"
|
||||
instance = "${element(aws_instance.k8s-master.*.id,count.index)}"
|
||||
}
|
||||
|
||||
|
||||
resource "aws_instance" "k8s-etcd" {
|
||||
ami = "${var.aws_cluster_ami}"
|
||||
instance_type = "${var.aws_etcd_size}"
|
||||
|
||||
count = "${var.aws_etcd_num}"
|
||||
|
||||
|
||||
availability_zone = "${element(var.aws_avail_zones,count.index)}"
|
||||
subnet_id = "${element(module.aws-vpc.aws_subnet_ids_private,count.index)}"
|
||||
|
||||
|
||||
vpc_security_group_ids = [ "${module.aws-vpc.aws_security_group}" ]
|
||||
|
||||
key_name = "${var.AWS_SSH_KEY_NAME}"
|
||||
|
||||
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-etcd${count.index}"
|
||||
Cluster = "${var.aws_cluster_name}"
|
||||
Role = "etcd"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
resource "aws_instance" "k8s-worker" {
|
||||
ami = "${var.aws_cluster_ami}"
|
||||
instance_type = "${var.aws_kube_worker_size}"
|
||||
|
||||
count = "${var.aws_kube_worker_num}"
|
||||
|
||||
availability_zone = "${element(var.aws_avail_zones,count.index)}"
|
||||
subnet_id = "${element(module.aws-vpc.aws_subnet_ids_private,count.index)}"
|
||||
|
||||
vpc_security_group_ids = [ "${module.aws-vpc.aws_security_group}" ]
|
||||
|
||||
iam_instance_profile = "${module.aws-iam.kube-worker-profile}"
|
||||
key_name = "${var.AWS_SSH_KEY_NAME}"
|
||||
|
||||
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-worker${count.index}"
|
||||
Cluster = "${var.aws_cluster_name}"
|
||||
Role = "worker"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Create Kargo Inventory File
|
||||
*
|
||||
*/
|
||||
data "template_file" "inventory" {
|
||||
template = "${file("${path.module}/templates/inventory.tpl")}"
|
||||
|
||||
vars {
|
||||
public_ip_address_bastion = "${join("\n",formatlist("bastion ansible_ssh_host=%s" , aws_instance.bastion-server.*.public_ip))}"
|
||||
connection_strings_master = "${join("\n",formatlist("%s ansible_ssh_host=%s",aws_instance.k8s-master.*.tags.Name, aws_instance.k8s-master.*.private_ip))}"
|
||||
connection_strings_node = "${join("\n", formatlist("%s ansible_ssh_host=%s", aws_instance.k8s-worker.*.tags.Name, aws_instance.k8s-worker.*.private_ip))}"
|
||||
connection_strings_etcd = "${join("\n",formatlist("%s ansible_ssh_host=%s", aws_instance.k8s-etcd.*.tags.Name, aws_instance.k8s-etcd.*.private_ip))}"
|
||||
list_master = "${join("\n",aws_instance.k8s-master.*.tags.Name)}"
|
||||
list_node = "${join("\n",aws_instance.k8s-worker.*.tags.Name)}"
|
||||
list_etcd = "${join("\n",aws_instance.k8s-etcd.*.tags.Name)}"
|
||||
elb_api_fqdn = "apiserver_loadbalancer_domain_name=\"${module.aws-elb.aws_elb_api_fqdn}\""
|
||||
elb_api_port = "loadbalancer_apiserver.port=${var.aws_elb_api_port}"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
resource "null_resource" "inventories" {
|
||||
provisioner "local-exec" {
|
||||
command = "echo '${data.template_file.inventory.rendered}' > ../../../inventory/hosts"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
#AWS Access Key
|
||||
AWS_ACCESS_KEY_ID = ""
|
||||
#AWS Secret Key
|
||||
AWS_SECRET_ACCESS_KEY = ""
|
||||
#EC2 SSH Key Name
|
||||
AWS_SSH_KEY_NAME = ""
|
||||
#AWS Region
|
||||
AWS_DEFAULT_REGION = "eu-central-1"
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 114 KiB |
@@ -1,58 +0,0 @@
|
||||
resource "aws_security_group" "aws-elb" {
|
||||
name = "kubernetes-${var.aws_cluster_name}-securitygroup-elb"
|
||||
vpc_id = "${var.aws_vpc_id}"
|
||||
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-securitygroup-elb"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
resource "aws_security_group_rule" "aws-allow-api-access" {
|
||||
type = "ingress"
|
||||
from_port = "${var.aws_elb_api_port}"
|
||||
to_port = "${var.k8s_secure_api_port}"
|
||||
protocol = "TCP"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
security_group_id = "${aws_security_group.aws-elb.id}"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "aws-allow-api-egress" {
|
||||
type = "egress"
|
||||
from_port = 0
|
||||
to_port = 65535
|
||||
protocol = "TCP"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
security_group_id = "${aws_security_group.aws-elb.id}"
|
||||
}
|
||||
|
||||
# Create a new AWS ELB for K8S API
|
||||
resource "aws_elb" "aws-elb-api" {
|
||||
name = "kubernetes-elb-${var.aws_cluster_name}"
|
||||
subnets = ["${var.aws_subnet_ids_public}"]
|
||||
security_groups = ["${aws_security_group.aws-elb.id}"]
|
||||
|
||||
listener {
|
||||
instance_port = "${var.k8s_secure_api_port}"
|
||||
instance_protocol = "tcp"
|
||||
lb_port = "${var.aws_elb_api_port}"
|
||||
lb_protocol = "tcp"
|
||||
}
|
||||
|
||||
health_check {
|
||||
healthy_threshold = 2
|
||||
unhealthy_threshold = 2
|
||||
timeout = 3
|
||||
target = "HTTP:8080/"
|
||||
interval = 30
|
||||
}
|
||||
|
||||
cross_zone_load_balancing = true
|
||||
idle_timeout = 400
|
||||
connection_draining = true
|
||||
connection_draining_timeout = 400
|
||||
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-elb-api"
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
output "aws_elb_api_id" {
|
||||
value = "${aws_elb.aws-elb-api.id}"
|
||||
}
|
||||
|
||||
output "aws_elb_api_fqdn" {
|
||||
value = "${aws_elb.aws-elb-api.dns_name}"
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
variable "aws_cluster_name" {
|
||||
description = "Name of Cluster"
|
||||
}
|
||||
|
||||
variable "aws_vpc_id" {
|
||||
description = "AWS VPC ID"
|
||||
}
|
||||
|
||||
variable "aws_elb_api_port" {
|
||||
description = "Port for AWS ELB"
|
||||
}
|
||||
|
||||
variable "k8s_secure_api_port" {
|
||||
description = "Secure Port of K8S API Server"
|
||||
}
|
||||
|
||||
|
||||
|
||||
variable "aws_avail_zones" {
|
||||
description = "Availability Zones Used"
|
||||
type = "list"
|
||||
}
|
||||
|
||||
|
||||
variable "aws_subnet_ids_public" {
|
||||
description = "IDs of Public Subnets"
|
||||
type = "list"
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
#Add AWS Roles for Kubernetes
|
||||
|
||||
resource "aws_iam_role" "kube-master" {
|
||||
name = "kubernetes-${var.aws_cluster_name}-master"
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "sts:AssumeRole",
|
||||
"Principal": {
|
||||
"Service": "ec2.amazonaws.com"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_iam_role" "kube-worker" {
|
||||
name = "kubernetes-${var.aws_cluster_name}-node"
|
||||
assume_role_policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "sts:AssumeRole",
|
||||
"Principal": {
|
||||
"Service": "ec2.amazonaws.com"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
#Add AWS Policies for Kubernetes
|
||||
|
||||
resource "aws_iam_role_policy" "kube-master" {
|
||||
name = "kubernetes-${var.aws_cluster_name}-master"
|
||||
role = "${aws_iam_role.kube-master.id}"
|
||||
policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["ec2:*"],
|
||||
"Resource": ["*"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["elasticloadbalancing:*"],
|
||||
"Resource": ["*"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["route53:*"],
|
||||
"Resource": ["*"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "s3:*",
|
||||
"Resource": [
|
||||
"arn:aws:s3:::kubernetes-*"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
resource "aws_iam_role_policy" "kube-worker" {
|
||||
name = "kubernetes-${var.aws_cluster_name}-node"
|
||||
role = "${aws_iam_role.kube-worker.id}"
|
||||
policy = <<EOF
|
||||
{
|
||||
"Version": "2012-10-17",
|
||||
"Statement": [
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "s3:*",
|
||||
"Resource": [
|
||||
"arn:aws:s3:::kubernetes-*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:Describe*",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:AttachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": "ec2:DetachVolume",
|
||||
"Resource": "*"
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": ["route53:*"],
|
||||
"Resource": ["*"]
|
||||
},
|
||||
{
|
||||
"Effect": "Allow",
|
||||
"Action": [
|
||||
"ecr:GetAuthorizationToken",
|
||||
"ecr:BatchCheckLayerAvailability",
|
||||
"ecr:GetDownloadUrlForLayer",
|
||||
"ecr:GetRepositoryPolicy",
|
||||
"ecr:DescribeRepositories",
|
||||
"ecr:ListImages",
|
||||
"ecr:BatchGetImage"
|
||||
],
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
EOF
|
||||
}
|
||||
|
||||
|
||||
#Create AWS Instance Profiles
|
||||
|
||||
resource "aws_iam_instance_profile" "kube-master" {
|
||||
name = "kube_${var.aws_cluster_name}_master_profile"
|
||||
roles = ["${aws_iam_role.kube-master.name}"]
|
||||
}
|
||||
|
||||
resource "aws_iam_instance_profile" "kube-worker" {
|
||||
name = "kube_${var.aws_cluster_name}_node_profile"
|
||||
roles = ["${aws_iam_role.kube-worker.name}"]
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
output "kube-master-profile" {
|
||||
value = "${aws_iam_instance_profile.kube-master.name }"
|
||||
}
|
||||
|
||||
output "kube-worker-profile" {
|
||||
value = "${aws_iam_instance_profile.kube-worker.name }"
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
variable "aws_cluster_name" {
|
||||
description = "Name of Cluster"
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
|
||||
resource "aws_vpc" "cluster-vpc" {
|
||||
cidr_block = "${var.aws_vpc_cidr_block}"
|
||||
|
||||
#DNS Related Entries
|
||||
enable_dns_support = true
|
||||
enable_dns_hostnames = true
|
||||
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-vpc"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
resource "aws_eip" "cluster-nat-eip" {
|
||||
count = "${length(var.aws_cidr_subnets_public)}"
|
||||
vpc = true
|
||||
}
|
||||
|
||||
|
||||
|
||||
resource "aws_internet_gateway" "cluster-vpc-internetgw" {
|
||||
vpc_id = "${aws_vpc.cluster-vpc.id}"
|
||||
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-internetgw"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_subnet" "cluster-vpc-subnets-public" {
|
||||
vpc_id = "${aws_vpc.cluster-vpc.id}"
|
||||
count="${length(var.aws_avail_zones)}"
|
||||
availability_zone = "${element(var.aws_avail_zones, count.index)}"
|
||||
cidr_block = "${element(var.aws_cidr_subnets_public, count.index)}"
|
||||
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-${element(var.aws_avail_zones, count.index)}-public"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_nat_gateway" "cluster-nat-gateway" {
|
||||
count = "${length(var.aws_cidr_subnets_public)}"
|
||||
allocation_id = "${element(aws_eip.cluster-nat-eip.*.id, count.index)}"
|
||||
subnet_id = "${element(aws_subnet.cluster-vpc-subnets-public.*.id, count.index)}"
|
||||
|
||||
}
|
||||
|
||||
resource "aws_subnet" "cluster-vpc-subnets-private" {
|
||||
vpc_id = "${aws_vpc.cluster-vpc.id}"
|
||||
count="${length(var.aws_avail_zones)}"
|
||||
availability_zone = "${element(var.aws_avail_zones, count.index)}"
|
||||
cidr_block = "${element(var.aws_cidr_subnets_private, count.index)}"
|
||||
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-${element(var.aws_avail_zones, count.index)}-private"
|
||||
}
|
||||
}
|
||||
|
||||
#Routing in VPC
|
||||
|
||||
#TODO: Do we need two routing tables for each subnet for redundancy or is one enough?
|
||||
|
||||
resource "aws_route_table" "kubernetes-public" {
|
||||
vpc_id = "${aws_vpc.cluster-vpc.id}"
|
||||
route {
|
||||
cidr_block = "0.0.0.0/0"
|
||||
gateway_id = "${aws_internet_gateway.cluster-vpc-internetgw.id}"
|
||||
}
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-routetable-public"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route_table" "kubernetes-private" {
|
||||
count = "${length(var.aws_cidr_subnets_private)}"
|
||||
vpc_id = "${aws_vpc.cluster-vpc.id}"
|
||||
route {
|
||||
cidr_block = "0.0.0.0/0"
|
||||
nat_gateway_id = "${element(aws_nat_gateway.cluster-nat-gateway.*.id, count.index)}"
|
||||
}
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-routetable-private-${count.index}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "kubernetes-public" {
|
||||
count = "${length(var.aws_cidr_subnets_public)}"
|
||||
subnet_id = "${element(aws_subnet.cluster-vpc-subnets-public.*.id,count.index)}"
|
||||
route_table_id = "${aws_route_table.kubernetes-public.id}"
|
||||
|
||||
}
|
||||
|
||||
resource "aws_route_table_association" "kubernetes-private" {
|
||||
count = "${length(var.aws_cidr_subnets_private)}"
|
||||
subnet_id = "${element(aws_subnet.cluster-vpc-subnets-private.*.id,count.index)}"
|
||||
route_table_id = "${element(aws_route_table.kubernetes-private.*.id,count.index)}"
|
||||
|
||||
}
|
||||
|
||||
|
||||
#Kubernetes Security Groups
|
||||
|
||||
resource "aws_security_group" "kubernetes" {
|
||||
name = "kubernetes-${var.aws_cluster_name}-securitygroup"
|
||||
vpc_id = "${aws_vpc.cluster-vpc.id}"
|
||||
|
||||
tags {
|
||||
Name = "kubernetes-${var.aws_cluster_name}-securitygroup"
|
||||
}
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "allow-all-ingress" {
|
||||
type = "ingress"
|
||||
from_port = 0
|
||||
to_port = 65535
|
||||
protocol = "-1"
|
||||
cidr_blocks= ["${var.aws_vpc_cidr_block}"]
|
||||
security_group_id = "${aws_security_group.kubernetes.id}"
|
||||
}
|
||||
|
||||
resource "aws_security_group_rule" "allow-all-egress" {
|
||||
type = "egress"
|
||||
from_port = 0
|
||||
to_port = 65535
|
||||
protocol = "-1"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
security_group_id = "${aws_security_group.kubernetes.id}"
|
||||
}
|
||||
|
||||
|
||||
resource "aws_security_group_rule" "allow-ssh-connections" {
|
||||
type = "ingress"
|
||||
from_port = 22
|
||||
to_port = 22
|
||||
protocol = "TCP"
|
||||
cidr_blocks = ["0.0.0.0/0"]
|
||||
security_group_id = "${aws_security_group.kubernetes.id}"
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
output "aws_vpc_id" {
|
||||
value = "${aws_vpc.cluster-vpc.id}"
|
||||
}
|
||||
|
||||
output "aws_subnet_ids_private" {
|
||||
value = ["${aws_subnet.cluster-vpc-subnets-private.*.id}"]
|
||||
}
|
||||
|
||||
output "aws_subnet_ids_public" {
|
||||
value = ["${aws_subnet.cluster-vpc-subnets-public.*.id}"]
|
||||
}
|
||||
|
||||
output "aws_security_group" {
|
||||
value = ["${aws_security_group.kubernetes.*.id}"]
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
variable "aws_vpc_cidr_block" {
|
||||
description = "CIDR Blocks for AWS VPC"
|
||||
}
|
||||
|
||||
|
||||
variable "aws_cluster_name" {
|
||||
description = "Name of Cluster"
|
||||
}
|
||||
|
||||
|
||||
variable "aws_avail_zones" {
|
||||
description = "AWS Availability Zones Used"
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "aws_cidr_subnets_private" {
|
||||
description = "CIDR Blocks for private subnets in Availability zones"
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "aws_cidr_subnets_public" {
|
||||
description = "CIDR Blocks for public subnets in Availability zones"
|
||||
type = "list"
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
output "bastion_ip" {
|
||||
value = "${join("\n", aws_instance.bastion-server.*.public_ip)}"
|
||||
}
|
||||
|
||||
output "masters" {
|
||||
value = "${join("\n", aws_instance.k8s-master.*.private_ip)}"
|
||||
}
|
||||
|
||||
output "workers" {
|
||||
value = "${join("\n", aws_instance.k8s-worker.*.private_ip)}"
|
||||
}
|
||||
|
||||
output "etcd" {
|
||||
value = "${join("\n", aws_instance.k8s-etcd.*.private_ip)}"
|
||||
}
|
||||
|
||||
|
||||
output "aws_elb_api_fqdn" {
|
||||
value = "${module.aws-elb.aws_elb_api_fqdn}:${var.aws_elb_api_port}"
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
${connection_strings_master}
|
||||
${connection_strings_node}
|
||||
${connection_strings_etcd}
|
||||
|
||||
|
||||
${public_ip_address_bastion}
|
||||
|
||||
[kube-master]
|
||||
${list_master}
|
||||
|
||||
|
||||
[kube-node]
|
||||
${list_node}
|
||||
|
||||
|
||||
[etcd]
|
||||
${list_etcd}
|
||||
|
||||
|
||||
[k8s-cluster:children]
|
||||
kube-node
|
||||
kube-master
|
||||
|
||||
|
||||
[k8s-cluster:vars]
|
||||
${elb_api_fqdn}
|
||||
${elb_api_port}
|
||||
@@ -1,31 +1,22 @@
|
||||
#Global Vars
|
||||
aws_cluster_name = "devtest"
|
||||
deploymentName="test-kube-deploy"
|
||||
|
||||
#VPC Vars
|
||||
aws_vpc_cidr_block = "10.250.192.0/18"
|
||||
aws_cidr_subnets_private = ["10.250.192.0/20","10.250.208.0/20"]
|
||||
aws_cidr_subnets_public = ["10.250.224.0/20","10.250.240.0/20"]
|
||||
aws_avail_zones = ["eu-central-1a","eu-central-1b"]
|
||||
numControllers="2"
|
||||
numEtcd="3"
|
||||
numNodes="2"
|
||||
|
||||
#Bastion Host
|
||||
aws_bastion_ami = "ami-5900cc36"
|
||||
aws_bastion_size = "t2.small"
|
||||
volSizeController="20"
|
||||
volSizeEtcd="20"
|
||||
volSizeNodes="20"
|
||||
|
||||
awsRegion="us-west-2"
|
||||
subnet="subnet-xxxxx"
|
||||
ami="ami-32a85152"
|
||||
securityGroups="sg-xxxxx"
|
||||
SSHUser="core"
|
||||
SSHKey="my-key"
|
||||
|
||||
#Kubernetes Cluster
|
||||
master_instance_type="m3.xlarge"
|
||||
etcd_instance_type="m3.xlarge"
|
||||
node_instance_type="m3.xlarge"
|
||||
|
||||
aws_kube_master_num = 3
|
||||
aws_kube_master_size = "t2.medium"
|
||||
|
||||
aws_etcd_num = 3
|
||||
aws_etcd_size = "t2.medium"
|
||||
|
||||
aws_kube_worker_num = 4
|
||||
aws_kube_worker_size = "t2.medium"
|
||||
|
||||
aws_cluster_ami = "ami-903df7ff"
|
||||
|
||||
#Settings AWS ELB
|
||||
|
||||
aws_elb_api_port = 443
|
||||
k8s_secure_api_port = 443
|
||||
terminate_protect="false"
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
#Global Vars
|
||||
aws_cluster_name = "devtest"
|
||||
aws_region = "eu-central-1"
|
||||
|
||||
#VPC Vars
|
||||
aws_vpc_cidr_block = "10.250.192.0/18"
|
||||
aws_cidr_subnets_private = ["10.250.192.0/20","10.250.208.0/20"]
|
||||
aws_cidr_subnets_public = ["10.250.224.0/20","10.250.240.0/20"]
|
||||
aws_avail_zones = ["eu-central-1a","eu-central-1b"]
|
||||
|
||||
#Bastion Host
|
||||
aws_bastion_ami = "ami-5900cc36"
|
||||
aws_bastion_size = "t2.small"
|
||||
|
||||
|
||||
#Kubernetes Cluster
|
||||
|
||||
aws_kube_master_num = 3
|
||||
aws_kube_master_size = "t2.medium"
|
||||
|
||||
aws_etcd_num = 3
|
||||
aws_etcd_size = "t2.medium"
|
||||
|
||||
aws_kube_worker_num = 4
|
||||
aws_kube_worker_size = "t2.medium"
|
||||
|
||||
aws_cluster_ami = "ami-903df7ff"
|
||||
|
||||
#Settings AWS ELB
|
||||
|
||||
aws_elb_api_port = 443
|
||||
k8s_secure_api_port = 443
|
||||
@@ -1,97 +0,0 @@
|
||||
variable "AWS_ACCESS_KEY_ID" {
|
||||
description = "AWS Access Key"
|
||||
}
|
||||
|
||||
variable "AWS_SECRET_ACCESS_KEY" {
|
||||
description = "AWS Secret Key"
|
||||
}
|
||||
|
||||
variable "AWS_SSH_KEY_NAME" {
|
||||
description = "Name of the SSH keypair to use in AWS."
|
||||
}
|
||||
|
||||
variable "AWS_DEFAULT_REGION" {
|
||||
description = "AWS Region"
|
||||
}
|
||||
|
||||
//General Cluster Settings
|
||||
|
||||
variable "aws_cluster_name" {
|
||||
description = "Name of AWS Cluster"
|
||||
}
|
||||
|
||||
|
||||
//AWS VPC Variables
|
||||
|
||||
variable "aws_vpc_cidr_block" {
|
||||
description = "CIDR Block for VPC"
|
||||
}
|
||||
|
||||
variable "aws_avail_zones" {
|
||||
description = "Availability Zones Used"
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "aws_cidr_subnets_private" {
|
||||
description = "CIDR Blocks for private subnets in Availability Zones"
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "aws_cidr_subnets_public" {
|
||||
description = "CIDR Blocks for public subnets in Availability Zones"
|
||||
type = "list"
|
||||
}
|
||||
|
||||
//AWS EC2 Settings
|
||||
|
||||
variable "aws_bastion_ami" {
|
||||
description = "AMI ID for Bastion Host in chosen AWS Region"
|
||||
}
|
||||
|
||||
variable "aws_bastion_size" {
|
||||
description = "EC2 Instance Size of Bastion Host"
|
||||
}
|
||||
|
||||
/*
|
||||
* AWS EC2 Settings
|
||||
* The number should be divisable by the number of used
|
||||
* AWS Availability Zones without an remainder.
|
||||
*/
|
||||
variable "aws_kube_master_num" {
|
||||
description = "Number of Kubernetes Master Nodes"
|
||||
}
|
||||
|
||||
variable "aws_kube_master_size" {
|
||||
description = "Instance size of Kube Master Nodes"
|
||||
}
|
||||
|
||||
variable "aws_etcd_num" {
|
||||
description = "Number of etcd Nodes"
|
||||
}
|
||||
|
||||
variable "aws_etcd_size" {
|
||||
description = "Instance size of etcd Nodes"
|
||||
}
|
||||
|
||||
variable "aws_kube_worker_num" {
|
||||
description = "Number of Kubernetes Worker Nodes"
|
||||
}
|
||||
|
||||
variable "aws_kube_worker_size" {
|
||||
description = "Instance size of Kubernetes Worker Nodes"
|
||||
}
|
||||
|
||||
variable "aws_cluster_ami" {
|
||||
description = "AMI ID for Kubernetes Cluster"
|
||||
}
|
||||
/*
|
||||
* AWS ELB Settings
|
||||
*
|
||||
*/
|
||||
variable "aws_elb_api_port" {
|
||||
description = "Port for AWS ELB"
|
||||
}
|
||||
|
||||
variable "k8s_secure_api_port" {
|
||||
description = "Secure Port of K8S API Server"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
../../inventory/group_vars
|
||||
@@ -1 +0,0 @@
|
||||
../../../inventory/group_vars
|
||||
1
contrib/terraform/openstack/group_vars/all.yml
Symbolic link
1
contrib/terraform/openstack/group_vars/all.yml
Symbolic link
@@ -0,0 +1 @@
|
||||
../../../../inventory/group_vars/all.yml
|
||||
@@ -68,7 +68,7 @@ resource "openstack_compute_instance_v2" "k8s_master" {
|
||||
floating_ip = "${element(openstack_networking_floatingip_v2.k8s_master.*.address, count.index)}"
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,kube-master,kube-node,k8s-cluster,vault"
|
||||
kubespray_groups = "etcd,kube-master,kube-node,k8s-cluster"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -87,10 +87,10 @@ resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip" {
|
||||
"${openstack_compute_secgroup_v2.k8s.name}" ]
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,kube-master,kube-node,k8s-cluster,vault,no-floating"
|
||||
kubespray_groups = "etcd,kube-master,kube-node,k8s-cluster"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element(openstack_networking_floatingip_v2.k8s_master.*.address, 0)}/ > contrib/terraform/openstack/group_vars/no-floating.yml"
|
||||
command = "sed s/USER/${var.ssh_user}/ contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element(openstack_networking_floatingip_v2.k8s_master.*.address, 0)}/ > contrib/terraform/openstack/group_vars/k8s-cluster.yml"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ resource "openstack_compute_instance_v2" "k8s_node" {
|
||||
floating_ip = "${element(openstack_networking_floatingip_v2.k8s_node.*.address, count.index)}"
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-node,k8s-cluster,vault"
|
||||
kubespray_groups = "kube-node,k8s-cluster"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,10 +123,10 @@ resource "openstack_compute_instance_v2" "k8s_node_no_floating_ip" {
|
||||
security_groups = ["${openstack_compute_secgroup_v2.k8s.name}" ]
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-node,k8s-cluster,vault,no-floating"
|
||||
kubespray_groups = "kube-node,k8s-cluster"
|
||||
}
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element(openstack_networking_floatingip_v2.k8s_master.*.address, 0)}/ > contrib/terraform/openstack/group_vars/no-floating.yml"
|
||||
command = "sed s/USER/${var.ssh_user}/ contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element(openstack_networking_floatingip_v2.k8s_master.*.address, 0)}/ > contrib/terraform/openstack/group_vars/k8s-cluster.yml"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ The inventory is composed of 3 groups:
|
||||
|
||||
* **kube-node** : list of kubernetes nodes where the pods will run.
|
||||
* **kube-master** : list of servers where kubernetes master components (apiserver, scheduler, controller) will run.
|
||||
* **etcd**: list of servers to compose the etcd server. You should have at least 3 servers for failover purpose.
|
||||
* **etcd**: list of server to compose the etcd server. you should have at least 3 servers for failover purposes.
|
||||
|
||||
Note: do not modify the children of _k8s-cluster_, like putting
|
||||
the _etcd_ group into the _k8s-cluster_, unless you are certain
|
||||
@@ -67,9 +67,7 @@ Group vars and overriding variables precedence
|
||||
----------------------------------------------
|
||||
|
||||
The group variables to control main deployment options are located in the directory ``inventory/group_vars``.
|
||||
Optional variables are located in the `inventory/group_vars/all.yml`.
|
||||
Mandatory variables that are common for at least one role (or a node group) can be found in the
|
||||
`inventory/group_vars/k8s-cluster.yml`.
|
||||
|
||||
There are also role vars for docker, rkt, kubernetes preinstall and master roles.
|
||||
According to the [ansible docs](http://docs.ansible.com/ansible/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable),
|
||||
those cannot be overriden from the group vars. In order to override, one should use
|
||||
@@ -162,7 +160,7 @@ ansible-playbook -i inventory/inventory.ini -e dns_server='' cluster.yml --tags
|
||||
And this prepares all container images localy (at the ansible runner node) without installing
|
||||
or upgrading related stuff or trying to upload container to K8s cluster nodes:
|
||||
```
|
||||
ansible-playbook -i inventory/inventory.ini cluster.yml \
|
||||
ansible-playbook -i inventory/inventory.ini cluster.yaml \
|
||||
-e download_run_once=true -e download_localhost=true \
|
||||
--tags download --skip-tags upload,upgrade
|
||||
```
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
Atomic host bootstrap
|
||||
=====================
|
||||
|
||||
Atomic host testing has been done with the network plugin flannel. Change the inventory var `kube_network_plugin: flannel`.
|
||||
|
||||
Note: Flannel is the only plugin that has currently been tested with atomic
|
||||
|
||||
### Vagrant
|
||||
|
||||
* For bootstrapping with Vagrant, use box centos/atomic-host
|
||||
* Update VagrantFile variable `local_release_dir` to `/var/vagrant/temp`.
|
||||
* Update `vm_memory = 2048` and `vm_cpus = 2`
|
||||
* Networking on vagrant hosts has to be brought up manually once they are booted.
|
||||
|
||||
```
|
||||
vagrant ssh
|
||||
sudo /sbin/ifup enp0s8
|
||||
```
|
||||
|
||||
* For users of vagrant-libvirt download qcow2 format from https://wiki.centos.org/SpecialInterestGroup/Atomic/Download/
|
||||
|
||||
Then you can proceed to [cluster deployment](#run-deployment)
|
||||
@@ -3,7 +3,7 @@ AWS
|
||||
|
||||
To deploy kubespray on [AWS](https://aws.amazon.com/) uncomment the `cloud_provider` option in `group_vars/all.yml` and set it to `'aws'`.
|
||||
|
||||
Prior to creating your instances, you **must** ensure that you have created IAM roles and policies for both "kubernetes-master" and "kubernetes-node". You can find the IAM policies [here](https://github.com/kubernetes-incubator/kargo/tree/master/contrib/aws_iam/). See the [IAM Documentation](https://aws.amazon.com/documentation/iam/) if guidance is needed on how to set these up. When you bring your instances online, associate them with the respective IAM role. Nodes that are only to be used for Etcd do not need a role.
|
||||
Prior to creating your instances, you **must** ensure that you have created IAM roles and policies for both "kubernetes-master" and "kubernetes-node". You can find the IAM policies [here](https://github.com/kubernetes/kubernetes/tree/master/cluster/aws/templates/iam). See the [IAM Documentation](https://aws.amazon.com/documentation/iam/) if guidance is needed on how to set these up. When you bring your instances online, associate them with the respective IAM role. Nodes that are only to be used for Etcd do not need a role.
|
||||
|
||||
The next step is to make sure the hostnames in your `inventory` file are identical to your internal hostnames in AWS. This may look something like `ip-111-222-333-444.us-west-2.compute.internal`. You can then specify how Ansible connects to these instances with `ansible_ssh_host` and `ansible_ssh_user`.
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Azure
|
||||
===============
|
||||
|
||||
To deploy Kubernetes on [Azure](https://azure.microsoft.com) uncomment the `cloud_provider` option in `group_vars/all.yml` and set it to `'azure'`.
|
||||
To deploy kubespray on [Azure](https://azure.microsoft.com) uncomment the `cloud_provider` option in `group_vars/all.yml` and set it to `'azure'`.
|
||||
|
||||
All your instances are required to run in a resource group and a routing table has to be attached to the subnet your instances are in.
|
||||
|
||||
@@ -49,8 +49,8 @@ This is the AppId from the last command
|
||||
- Create the role assignment with:
|
||||
`azure role assignment create --spn http://kubernetes -o "Owner" -c /subscriptions/SUBSCRIPTION_ID`
|
||||
|
||||
azure\_aad\_client\_id must be set to the AppId, azure\_aad\_client\_secret is your choosen secret.
|
||||
azure\_aad\_client\_id musst be set to the AppId, azure\_aad\_client\_secret is your choosen secret.
|
||||
|
||||
## Provisioning Azure with Resource Group Templates
|
||||
|
||||
You'll find Resource Group Templates and scripts to provision the required infrastructure to Azure in [*contrib/azurerm*](../contrib/azurerm/README.md)
|
||||
You'll find Resource Group Templates and scripts to provision the required infrastructore to Azure in [*contrib/azurerm*](../contrib/azurerm/README.md)
|
||||
@@ -147,16 +147,6 @@ The inventory above will deploy the following topology assuming that calico's
|
||||
|
||||

|
||||
|
||||
##### Optional : Define default endpoint to host action
|
||||
|
||||
By default Calico blocks traffic from endpoints to the host itself by using an iptables DROP action. When using it in kubernetes the action has to be changed to RETURN (default in kargo) or ACCEPT (see https://github.com/projectcalico/felix/issues/660 and https://github.com/projectcalico/calicoctl/issues/1389). Otherwise all network packets from pods (with hostNetwork=False) to services endpoints (with hostNetwork=True) withing the same node are dropped.
|
||||
|
||||
|
||||
To re-define default action please set the following variable in your inventory:
|
||||
```
|
||||
calico_endpoint_to_host_action: "ACCEPT"
|
||||
```
|
||||
|
||||
Cloud providers configuration
|
||||
=============================
|
||||
|
||||
|
||||
@@ -13,4 +13,12 @@ Before running the cluster playbook you must satisfy the following requirements:
|
||||
|
||||
* On each CoreOS nodes a writable directory **/opt/bin** (~400M disk space)
|
||||
|
||||
* Uncomment the variable **ansible\_python\_interpreter** in the file `inventory/group_vars/all.yml`
|
||||
|
||||
* run the Python bootstrap playbook
|
||||
|
||||
```
|
||||
ansible-playbook -u smana -e ansible_ssh_user=smana -b --become-user=root -i inventory/inventory.cfg coreos-bootstrap.yml
|
||||
```
|
||||
|
||||
Then you can proceed to [cluster deployment](#run-deployment)
|
||||
|
||||
@@ -21,7 +21,7 @@ kargo deploy --aws -u centos -n calico
|
||||
Building your own inventory
|
||||
---------------------------
|
||||
|
||||
Ansible inventory can be stored in 3 formats: YAML, JSON, or INI-like. There is
|
||||
Ansible inventory can be stored in 3 formats: YAML, JSON, or inifile. There is
|
||||
an example inventory located
|
||||
[here](https://github.com/kubernetes-incubator/kargo/blob/master/inventory/inventory.example).
|
||||
|
||||
@@ -47,10 +47,9 @@ Starting custom deployment
|
||||
Once you have an inventory, you may want to customize deployment data vars
|
||||
and start the deployment:
|
||||
|
||||
**IMPORTANT: Edit my_inventory/groups_vars/*.yaml to override data vars**
|
||||
|
||||
```
|
||||
ansible-playbook -i my_inventory/inventory.cfg cluster.yml -b -v \
|
||||
# Edit my_inventory/groups_vars/*.yaml to override data vars
|
||||
ansible-playbook -i my_inventory/inventory.cfg cluster.yaml -b -v \
|
||||
--private-key=~/.ssh/private_key
|
||||
```
|
||||
|
||||
|
||||
@@ -11,11 +11,18 @@ achieve the same goal.
|
||||
Etcd
|
||||
----
|
||||
|
||||
Etcd proxies are deployed on each node in the `k8s-cluster` group. A proxy is
|
||||
a separate etcd process. It has a `localhost:2379` frontend and all of the etcd
|
||||
cluster members as backends. Note that the `access_ip` is used as the backend
|
||||
IP, if specified. Frontend endpoints cannot be accessed externally as they are
|
||||
bound to a localhost only.
|
||||
|
||||
The `etcd_access_endpoint` fact provides an access pattern for clients. And the
|
||||
`etcd_multiaccess` (defaults to `True`) group var controlls that behavior.
|
||||
It makes deployed components to access the etcd cluster members
|
||||
`etcd_multiaccess` (defaults to `false`) group var controlls that behavior.
|
||||
When enabled, it makes deployed components to access the etcd cluster members
|
||||
directly: `http://ip1:2379, http://ip2:2379,...`. This mode assumes the clients
|
||||
do a loadbalancing and handle HA for connections.
|
||||
do a loadbalancing and handle HA for connections. Note, a pod definition of a
|
||||
flannel networking plugin always uses a single `--etcd-server` endpoint!
|
||||
|
||||
|
||||
Kube-apiserver
|
||||
@@ -27,8 +34,8 @@ non-master Kubernetes node. This is referred to as localhost loadbalancing. It
|
||||
is less efficient than a dedicated load balancer because it creates extra
|
||||
health checks on the Kubernetes apiserver, but is more practical for scenarios
|
||||
where an external LB or virtual IP management is inconvenient. This option is
|
||||
configured by the variable `loadbalancer_apiserver_localhost` (defaults to `True`).
|
||||
You may also define the port the local internal loadbalancer users by changing,
|
||||
configured by the variable `loadbalancer_apiserver_localhost`. You may also
|
||||
define the port the local internal loadbalancer users by changing,
|
||||
`nginx_kube_apiserver_port`. This defaults to the value of `kube_apiserver_port`.
|
||||
It is also import to note that Kargo will only configure kubelet and kube-proxy
|
||||
on non-master nodes to use the local internal loadbalancer.
|
||||
@@ -61,8 +68,8 @@ listen kubernetes-apiserver-https
|
||||
mode tcp
|
||||
timeout client 3h
|
||||
timeout server 3h
|
||||
server master1 <IP1>:6443
|
||||
server master2 <IP2>:6443
|
||||
server master1 <IP1>:443
|
||||
server master2 <IP2>:443
|
||||
balance roundrobin
|
||||
```
|
||||
|
||||
@@ -88,9 +95,9 @@ Access endpoints are evaluated automagically, as the following:
|
||||
|
||||
| Endpoint type | kube-master | non-master |
|
||||
|------------------------------|---------------|---------------------|
|
||||
| Local LB (default) | http://lc:p | https://lc:nsp |
|
||||
| Local LB | http://lc:p | https://lc:nsp |
|
||||
| External LB, no internal | https://lb:lp | https://lb:lp |
|
||||
| No ext/int LB | http://lc:p | https://m[0].aip:sp |
|
||||
| No ext/int LB (default) | http://lc:p | https://m[0].aip:sp |
|
||||
|
||||
Where:
|
||||
* `m[0]` - the first node in the `kube-master` group;
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
# Overview
|
||||
|
||||
Distributed system such as Kubernetes are designed to be resilient to the
|
||||
failures. More details about Kubernetes High-Availability (HA) may be found at
|
||||
[Building High-Availability Clusters](https://kubernetes.io/docs/admin/high-availability/)
|
||||
|
||||
To have a simple view the most of parts of HA will be skipped to describe
|
||||
Kubelet<->Controller Manager communication only.
|
||||
|
||||
By default the normal behavior looks like:
|
||||
|
||||
1. Kubelet updates it status to apiserver periodically, as specified by
|
||||
`--node-status-update-frequency`. The default value is **10s**.
|
||||
|
||||
2. Kubernetes controller manager checks the statuses of Kubelets every
|
||||
`–-node-monitor-period`. The default value is **5s**.
|
||||
|
||||
3. In case the status is updated within `--node-monitor-grace-period` of time,
|
||||
Kubernetes controller manager considers healthy status of Kubelet. The
|
||||
default value is **40s**.
|
||||
|
||||
> Kubernetes controller manager and Kubelets work asynchronously. It means that
|
||||
> the delay may include any network latency, API Server latency, etcd latency,
|
||||
> latency caused by load on one's master nodes and so on. So if
|
||||
> `--node-status-update-frequency` is set to 5s in reality it may appear in
|
||||
> etcd in 6-7 seconds or even longer when etcd cannot commit data to quorum
|
||||
> nodes.
|
||||
|
||||
# Failure
|
||||
|
||||
Kubelet will try to make `nodeStatusUpdateRetry` post attempts. Currently
|
||||
`nodeStatusUpdateRetry` is constantly set to 5 in
|
||||
[kubelet.go](https://github.com/kubernetes/kubernetes/blob/release-1.5/pkg/kubelet/kubelet.go#L102).
|
||||
|
||||
Kubelet will try to update the status in
|
||||
[tryUpdateNodeStatus](https://github.com/kubernetes/kubernetes/blob/release-1.5/pkg/kubelet/kubelet_node_status.go#L345)
|
||||
function. Kubelet uses `http.Client()` Golang method, but has no specified
|
||||
timeout. Thus there may be some glitches when API Server is overloaded while
|
||||
TCP connection is established.
|
||||
|
||||
So, there will be `nodeStatusUpdateRetry` * `--node-status-update-frequency`
|
||||
attempts to set a status of node.
|
||||
|
||||
At the same time Kubernetes controller manager will try to check
|
||||
`nodeStatusUpdateRetry` times every `--node-monitor-period` of time. After
|
||||
`--node-monitor-grace-period` it will consider node unhealthy. It will remove
|
||||
its pods based on `--pod-eviction-timeout`
|
||||
|
||||
Kube proxy has a watcher over API. Once pods are evicted, Kube proxy will
|
||||
notice and will update iptables of the node. It will remove endpoints from
|
||||
services so pods from failed node won't be accessible anymore.
|
||||
|
||||
# Recommendations for different cases
|
||||
|
||||
## Fast Update and Fast Reaction
|
||||
|
||||
If `-–node-status-update-frequency` is set to **4s** (10s is default).
|
||||
`--node-monitor-period` to **2s** (5s is default).
|
||||
`--node-monitor-grace-period` to **20s** (40s is default).
|
||||
`--pod-eviction-timeout` is set to **30s** (5m is default)
|
||||
|
||||
In such scenario, pods will be evicted in **50s** because the node will be
|
||||
considered as down after **20s**, and `--pod-eviction-timeout` occurs after
|
||||
**30s** more. However, this scenario creates an overhead on etcd as every node
|
||||
will try to update its status every 2 seconds.
|
||||
|
||||
If the environment has 1000 nodes, there will be 15000 node updates per
|
||||
minute which may require large etcd containers or even dedicated nodes for etcd.
|
||||
|
||||
> If we calculate the number of tries, the division will give 5, but in reality
|
||||
> it will be from 3 to 5 with `nodeStatusUpdateRetry` attempts of each try. The
|
||||
> total number of attemtps will vary from 15 to 25 due to latency of all
|
||||
> components.
|
||||
|
||||
## Medium Update and Average Reaction
|
||||
|
||||
Let's set `-–node-status-update-frequency` to **20s**
|
||||
`--node-monitor-grace-period` to **2m** and `--pod-eviction-timeout` to **1m**.
|
||||
In that case, Kubelet will try to update status every 20s. So, it will be 6 * 5
|
||||
= 30 attempts before Kubernetes controller manager will consider unhealthy
|
||||
status of node. After 1m it will evict all pods. The total time will be 3m
|
||||
before eviction process.
|
||||
|
||||
Such scenario is good for medium environments as 1000 nodes will require 3000
|
||||
etcd updates per minute.
|
||||
|
||||
> In reality, there will be from 4 to 6 node update tries. The total number of
|
||||
> of attempts will vary from 20 to 30.
|
||||
|
||||
## Low Update and Slow reaction
|
||||
|
||||
Let's set `-–node-status-update-frequency` to **1m**.
|
||||
`--node-monitor-grace-period` will set to **5m** and `--pod-eviction-timeout`
|
||||
to **1m**. In this scenario, every kubelet will try to update the status every
|
||||
minute. There will be 5 * 5 = 25 attempts before unhealty status. After 5m,
|
||||
Kubernetes controller manager will set unhealthy status. This means that pods
|
||||
will be evicted after 1m after being marked unhealthy. (6m in total).
|
||||
|
||||
> In reality, there will be from 3 to 5 tries. The total number of attempt will
|
||||
> vary from 15 to 25.
|
||||
|
||||
There can be different combinations such as Fast Update with Slow reaction to
|
||||
satisfy specific cases.
|
||||
@@ -3,8 +3,7 @@ Large deployments of K8s
|
||||
|
||||
For a large scaled deployments, consider the following configuration changes:
|
||||
|
||||
* Tune [ansible settings]
|
||||
(http://docs.ansible.com/ansible/intro_configuration.html)
|
||||
* Tune [ansible settings](http://docs.ansible.com/ansible/intro_configuration.html)
|
||||
for `forks` and `timeout` vars to fit large numbers of nodes being deployed.
|
||||
|
||||
* Override containers' `foo_image_repo` vars to point to intranet registry.
|
||||
@@ -24,15 +23,9 @@ For a large scaled deployments, consider the following configuration changes:
|
||||
* Tune CPU/memory limits and requests. Those are located in roles' defaults
|
||||
and named like ``foo_memory_limit``, ``foo_memory_requests`` and
|
||||
``foo_cpu_limit``, ``foo_cpu_requests``. Note that 'Mi' memory units for K8s
|
||||
will be submitted as 'M', if applied for ``docker run``, and cpu K8s units
|
||||
will end up with the 'm' skipped for docker as well. This is required as
|
||||
docker does not understand k8s units well.
|
||||
|
||||
* Tune ``kubelet_status_update_frequency`` to increase reliability of kubelet.
|
||||
``kube_controller_node_monitor_grace_period``,
|
||||
``kube_controller_node_monitor_period``,
|
||||
``kube_controller_pod_eviction_timeout`` for better Kubernetes reliability.
|
||||
Check out [Kubernetes Reliability](kubernetes-reliability.md)
|
||||
will be submitted as 'M', if applied for ``docker run``, and cpu K8s units will
|
||||
end up with the 'm' skipped for docker as well. This is required as docker does not
|
||||
understand k8s units well.
|
||||
|
||||
* Add calico-rr nodes if you are deploying with Calico or Canal. Nodes recover
|
||||
from host/network interruption much quicker with calico-rr. Note that
|
||||
@@ -40,7 +33,7 @@ For a large scaled deployments, consider the following configuration changes:
|
||||
etcd role is okay).
|
||||
|
||||
* Check out the
|
||||
[Inventory](getting-started.md#building-your-own-inventory)
|
||||
[Inventory](https://github.com/kubernetes-incubator/kargo/blob/master/docs/getting-started.md#building-your-own-inventory)
|
||||
section of the Getting started guide for tips on creating a large scale
|
||||
Ansible inventory.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ Network Checker Application
|
||||
===========================
|
||||
|
||||
With the ``deploy_netchecker`` var enabled (defaults to false), Kargo deploys a
|
||||
Network Checker Application from the 3rd side `l23network/k8s-netchecker` docker
|
||||
Network Checker Application from the 3rd side `l23network/mcp-netchecker` docker
|
||||
images. It consists of the server and agents trying to reach the server by usual
|
||||
for Kubernetes applications network connectivity meanings. Therefore, this
|
||||
automagically verifies a pod to pod connectivity via the cluster IP and checks
|
||||
@@ -25,8 +25,8 @@ There are related application specifc variables:
|
||||
netchecker_port: 31081
|
||||
agent_report_interval: 15
|
||||
netcheck_namespace: default
|
||||
agent_img: "quay.io/l23network/k8s-netchecker-agent:v1.0"
|
||||
server_img: "quay.io/l23network/k8s-netchecker-server:v1.0"
|
||||
agent_img: "quay.io/l23network/mcp-netchecker-agent:v0.1"
|
||||
server_img: "quay.io/l23network/mcp-netchecker-server:v0.1"
|
||||
```
|
||||
|
||||
Note that the application verifies DNS resolve for FQDNs comprising only the
|
||||
|
||||
@@ -5,7 +5,7 @@ Kargo's roadmap
|
||||
- Propose kubeadm as an option in order to setup the kubernetes cluster.
|
||||
That would probably improve deployment speed and certs management [#553](https://github.com/kubespray/kargo/issues/553)
|
||||
|
||||
### Self deployment (pull-mode) [#320](https://github.com/kubespray/kargo/issues/320)
|
||||
### Self deployment (pull-mode) [#320](https://github.com/kubespray/kargo/issues/320)
|
||||
- the playbook would install and configure docker/rkt and the etcd cluster
|
||||
- the following data would be inserted into etcd: certs,tokens,users,inventory,group_vars.
|
||||
- a "kubespray" container would be deployed (kargo-cli, ansible-playbook, kpm)
|
||||
@@ -18,7 +18,7 @@ That would probably improve deployment speed and certs management [#553](https:/
|
||||
- [ ] On Azure autoscaling, create loadbalancer [#297](https://github.com/kubespray/kargo/issues/297)
|
||||
- [ ] On GCE be able to create a loadbalancer automatically (IAM ?) [#280](https://github.com/kubespray/kargo/issues/280)
|
||||
- [x] **TLS boostrap** support for kubelet [#234](https://github.com/kubespray/kargo/issues/234)
|
||||
(related issues: https://github.com/kubernetes/kubernetes/pull/20439 <br>
|
||||
(related issues: https://github.com/kubernetes/kubernetes/pull/20439 <br>
|
||||
https://github.com/kubernetes/kubernetes/issues/18112)
|
||||
|
||||
### Tests
|
||||
@@ -49,7 +49,7 @@ That would probably improve deployment speed and certs management [#553](https:/
|
||||
- [x] Canal
|
||||
- [x] Cloud Provider native networking (instead of our network plugins)
|
||||
|
||||
### High availability
|
||||
### High availability
|
||||
- (to be discussed) option to set a loadbalancer for the apiservers like ucarp/packemaker/keepalived
|
||||
While waiting for the issue [kubernetes/kubernetes#18174](https://github.com/kubernetes/kubernetes/issues/18174) to be fixed.
|
||||
|
||||
@@ -73,7 +73,7 @@ Include optionals deployments to init the cluster:
|
||||
|
||||
##### Others
|
||||
|
||||
##### Dashboards:
|
||||
##### Dashboards:
|
||||
- kubernetes-dashboard
|
||||
- Fabric8
|
||||
- Tectonic
|
||||
|
||||
@@ -4,40 +4,25 @@ Travis CI test matrix
|
||||
GCE instances
|
||||
-------------
|
||||
|
||||
Here is the test matrix for the CI gates:
|
||||
Here is the test matrix for the Travis CI gates:
|
||||
|
||||
| Network plugin| OS type| GCE region| Nodes layout|
|
||||
|-------------------------|-------------------------|-------------------------|-------------------------|
|
||||
| canal| debian-8-kubespray| asia-east1-a| ha-scale|
|
||||
| canal| debian-8-kubespray| asia-east1-a| ha|
|
||||
| calico| debian-8-kubespray| europe-west1-c| default|
|
||||
| flannel| centos-7| asia-northeast1-c| default|
|
||||
| calico| centos-7| us-central1-b| ha|
|
||||
| weave| rhel-7| us-east1-c| default|
|
||||
| canal| coreos-stable| us-west1-b| ha-scale|
|
||||
| canal| coreos-stable| us-west1-b| default|
|
||||
| canal| rhel-7| asia-northeast1-b| separate|
|
||||
| weave| ubuntu-1604-xenial| europe-west1-d| separate|
|
||||
| calico| coreos-stable| us-central1-f| separate|
|
||||
|
||||
|
||||
Node Layouts
|
||||
------------
|
||||
|
||||
There are four node layout types: `default`, `separate`, `ha`, and `scale`.
|
||||
|
||||
|
||||
`default` is a non-HA two nodes setup with one separate `kube-node`
|
||||
and the `etcd` group merged with the `kube-master`.
|
||||
|
||||
`separate` layout is when there is only node of each type, which includes
|
||||
a kube-master, kube-node, and etcd cluster member.
|
||||
|
||||
`ha` layout consists of two etcd nodes, two masters and a single worker node,
|
||||
with role intersection.
|
||||
|
||||
`scale` layout can be combined with above layouts. It includes 200 fake hosts
|
||||
in the Ansible inventory. This helps test TLS certificate generation at scale
|
||||
to prevent regressions and profile certain long-running tasks. These nodes are
|
||||
never actually deployed, but certificates are generated for them.
|
||||
Where the nodes layout `default` is a non-HA two nodes setup with the separate `kube-node`
|
||||
and the `etcd` group merged with the `kube-master`. The `separate` layout is when
|
||||
there is only node of each type, which is a kube master, compute and etcd cluster member.
|
||||
And the `ha` layout stands for a two etcd nodes, two masters and a single worker node,
|
||||
partially intersecting though.
|
||||
|
||||
Note, the canal network plugin deploys flannel as well plus calico policy controller.
|
||||
|
||||
@@ -55,15 +40,15 @@ GCE instances
|
||||
|
||||
| Stage| Network plugin| OS type| GCE region| Nodes layout
|
||||
|--------------------|--------------------|--------------------|--------------------|--------------------|
|
||||
| part1| calico| coreos-stable| us-west1-b| separate|
|
||||
| part1| calico| coreos-stable| us-west1-b| separated|
|
||||
| part1| canal| debian-8-kubespray| us-east1-b| ha|
|
||||
| part1| weave| rhel-7| europe-west1-b| default|
|
||||
| part2| flannel| centos-7| us-west1-a| default|
|
||||
| part2| calico| debian-8-kubespray| us-central1-b| default|
|
||||
| part2| canal| coreos-stable| us-east1-b| default|
|
||||
| special| canal| rhel-7| us-east1-b| separate|
|
||||
| special| weave| ubuntu-1604-xenial| us-central1-b| default|
|
||||
| special| calico| centos-7| europe-west1-b| ha-scale|
|
||||
| special| weave| coreos-alpha| us-west1-a| ha-scale|
|
||||
| special| canal| rhel-7| us-east1-b| separated|
|
||||
| special| weave| ubuntu-1604-xenial| us-central1-b| separated|
|
||||
| special| calico| centos-7| europe-west1-b| ha|
|
||||
| special| weave| coreos-alpha| us-west1-a| ha|
|
||||
|
||||
The "Stage" means a build step of the build pipeline. The steps are ordered as `part1->part2->special`.
|
||||
|
||||
@@ -18,7 +18,7 @@ versions. Here are all version vars for each component:
|
||||
* flannel_version
|
||||
* kubedns_version
|
||||
|
||||
#### Unsafe upgrade example
|
||||
#### Example
|
||||
|
||||
If you wanted to upgrade just kube_version from v1.4.3 to v1.4.6, you could
|
||||
deploy the following way:
|
||||
@@ -33,29 +33,15 @@ And then repeat with v1.4.6 as kube_version:
|
||||
ansible-playbook cluster.yml -i inventory/inventory.cfg -e kube_version=v1.4.6
|
||||
```
|
||||
|
||||
#### Graceful upgrade
|
||||
|
||||
Kargo also supports cordon, drain and uncordoning of nodes when performing
|
||||
a cluster upgrade. There is a separate playbook used for this purpose. It is
|
||||
important to note that upgrade-cluster.yml can only be used for upgrading an
|
||||
existing cluster. That means there must be at least 1 kube-master already
|
||||
deployed.
|
||||
|
||||
```
|
||||
git fetch origin
|
||||
git checkout origin/master
|
||||
ansible-playbook upgrade-cluster.yml -b -i inventory/inventory.cfg
|
||||
```
|
||||
|
||||
#### Upgrade order
|
||||
|
||||
As mentioned above, components are upgraded in the order in which they were
|
||||
installed in the Ansible playbook. The order of component installation is as
|
||||
follows:
|
||||
|
||||
* Docker
|
||||
* etcd
|
||||
* kubelet and kube-proxy
|
||||
* network_plugin (such as Calico or Weave)
|
||||
* kube-apiserver, kube-scheduler, and kube-controller-manager
|
||||
* Add-ons (such as KubeDNS)
|
||||
# Docker
|
||||
# etcd
|
||||
# kubelet and kube-proxy
|
||||
# network_plugin (such as Calico or Weave)
|
||||
# kube-apiserver, kube-scheduler, and kube-controller-manager
|
||||
# Add-ons (such as KubeDNS)
|
||||
|
||||
12
docs/vars.md
12
docs/vars.md
@@ -23,7 +23,7 @@ Some variables of note include:
|
||||
* *hyperkube_image_repo* - Specify the Docker repository where Hyperkube
|
||||
resides
|
||||
* *hyperkube_image_tag* - Specify the Docker tag where Hyperkube resides
|
||||
* *kube_network_plugin* - Sets k8s network plugin (default Calico)
|
||||
* *kube_network_plugin* - Changes k8s plugin to Calico
|
||||
* *kube_proxy_mode* - Changes k8s proxy mode to iptables mode
|
||||
* *kube_version* - Specify a given Kubernetes hyperkube version
|
||||
* *searchdomains* - Array of DNS domains to search when looking up hostnames
|
||||
@@ -41,9 +41,8 @@ Some variables of note include:
|
||||
address instead of localhost for kube-masters and kube-master[0] for
|
||||
kube-nodes. See more details in the
|
||||
[HA guide](https://github.com/kubernetes-incubator/kargo/blob/master/docs/ha-mode.md).
|
||||
* *loadbalancer_apiserver_localhost* - makes all hosts to connect to
|
||||
the apiserver internally load balanced endpoint. Mutual exclusive to the
|
||||
`loadbalancer_apiserver`. See more details in the
|
||||
* *loadbalancer_apiserver_localhost* - If enabled, all hosts will connect to
|
||||
the apiserver internally load balanced endpoint. See more details in the
|
||||
[HA guide](https://github.com/kubernetes-incubator/kargo/blob/master/docs/ha-mode.md).
|
||||
|
||||
#### Cluster variables
|
||||
@@ -93,12 +92,9 @@ Stack](https://github.com/kubernetes-incubator/kargo/blob/master/docs/dns-stack.
|
||||
``--insecure-registry=myregistry.mydomain:5000``
|
||||
* *http_proxy/https_proxy/no_proxy* - Proxy variables for deploying behind a
|
||||
proxy
|
||||
* *kubelet_load_modules* - For some things, kubelet needs to load kernel modules. For example,
|
||||
dynamic kernel services are needed for mounting persistent volumes into containers. These may not be
|
||||
loaded by preinstall kubernetes processes. For example, ceph and rbd backed volumes. Set this variable to
|
||||
true to let kubelet load kernel modules.
|
||||
|
||||
#### User accounts
|
||||
|
||||
Kargo sets up two Kubernetes accounts by default: ``root`` and ``kube``. Their
|
||||
passwords default to changeme. You can set this by changing ``kube_api_pwd``.
|
||||
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
Hashicorp Vault Role
|
||||
====================
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The Vault role is a two-step process:
|
||||
|
||||
1. Bootstrap
|
||||
|
||||
You cannot start your certificate management service securely with SSL (and
|
||||
the datastore behind it) without having the certificates in-hand already. This
|
||||
presents an unfortunate chicken and egg scenario, with one requiring the other.
|
||||
To solve for this, the Bootstrap step was added.
|
||||
|
||||
This step spins up a temporary instance of Vault to issue certificates for
|
||||
Vault itself. It then leaves the temporary instance running, so that the Etcd
|
||||
role can generate certs for itself as well. Eventually, this may be improved
|
||||
to allow alternate backends (such as Consul), but currently the tasks are
|
||||
hardcoded to only create a Vault role for Etcd.
|
||||
|
||||
2. Cluster
|
||||
|
||||
This step is where the long-term Vault cluster is started and configured. Its
|
||||
first task, is to stop any temporary instances of Vault, to free the port for
|
||||
the long-term. At the end of this task, the entire Vault cluster should be up
|
||||
and read to go.
|
||||
|
||||
|
||||
Keys to the Kingdom
|
||||
-------------------
|
||||
|
||||
The two most important security pieces of Vault are the ``root_token``
|
||||
and ``unsealing_keys``. Both of these values are given exactly once, during
|
||||
the initialization of the Vault cluster. For convenience, they are saved
|
||||
to the ``vault_secret_dir`` (default: /etc/vault/secrets) of every host in the
|
||||
vault group.
|
||||
|
||||
It is *highly* recommended that these secrets are removed from the servers after
|
||||
your cluster has been deployed, and kept in a safe location of your choosing.
|
||||
Naturally, the seriousness of the situation depends on what you're doing with
|
||||
your Kargo cluster, but with these secrets, an attacker will have the ability
|
||||
to authenticate to almost everything in Kubernetes and decode all private
|
||||
(HTTPS) traffic on your network signed by Vault certificates.
|
||||
|
||||
For even greater security, you may want to remove and store elsewhere any
|
||||
CA keys generated as well (e.g. /etc/vault/ssl/ca-key.pem).
|
||||
|
||||
Vault by default encrypts all traffic to and from the datastore backend, all
|
||||
resting data, and uses TLS for its TCP listener. It is recommended that you
|
||||
do not change the Vault config to disable TLS, unless you absolutely have to.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
To get the Vault role running, you must to do two things at a minimum:
|
||||
|
||||
1. Assign the ``vault`` group to at least 1 node in your inventory
|
||||
2. Change ``cert_management`` to be ``vault`` instead of ``script``
|
||||
|
||||
Nothing else is required, but customization is possible. Check
|
||||
``roles/vault/defaults/main.yml`` for the different variables that can be
|
||||
overridden, most common being ``vault_config``, ``vault_port``, and
|
||||
``vault_deployment_type``.
|
||||
|
||||
Also, if you intend to use a Root or Intermediate CA generated elsewhere,
|
||||
you'll need to copy the certificate and key to the hosts in the vault group
|
||||
prior to running the vault role. By default, they'll be located at
|
||||
``/etc/vault/ssl/ca.pem`` and ``/etc/vault/ssl/ca-key.pem``, respectively.
|
||||
|
||||
Additional Notes:
|
||||
|
||||
- ``groups.vault|first`` is considered the source of truth for Vault variables
|
||||
- ``vault_leader_url`` is used as pointer for the current running Vault
|
||||
- Each service should have its own role and credentials. Currently those
|
||||
credentials are saved to ``/etc/vault/roles/<role>/``. The service will
|
||||
need to read in those credentials, if they want to interact with Vault.
|
||||
|
||||
|
||||
Potential Work
|
||||
--------------
|
||||
|
||||
- Change the Vault role to not run certain tasks when ``root_token`` and
|
||||
``unseal_keys`` are not present. Alternatively, allow user input for these
|
||||
values when missing.
|
||||
- Add the ability to start temp Vault with Host, Rkt, or Docker
|
||||
- Add a dynamic way to change out the backend role creation during Bootstrap,
|
||||
so other services can be used (such as Consul)
|
||||
- Segregate Server Cert generation from Auth Cert generation (separate CAs).
|
||||
This work was partially started with the `auth_cert_backend` tasks, but would
|
||||
need to be further applied to all roles (particularly Etcd and Kubernetes).
|
||||
@@ -1,59 +1,167 @@
|
||||
## 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
|
||||
# Valid bootstrap options (required): ubuntu, coreos, centos, none
|
||||
bootstrap_os: none
|
||||
|
||||
### LOADBALANCING AND ACCESS MODES
|
||||
## Enable multiaccess to configure etcd clients to access all of the etcd members directly
|
||||
## as the "http://hostX:port, http://hostY:port, ..." and ignore the proxy loadbalancers.
|
||||
## This may be the case if clients support and loadbalance multiple etcd servers natively.
|
||||
#etcd_multiaccess: true
|
||||
# Directory where the binaries will be installed
|
||||
bin_dir: /usr/local/bin
|
||||
|
||||
## External LB example config
|
||||
## apiserver_loadbalancer_domain_name: "elb.some.domain"
|
||||
#loadbalancer_apiserver:
|
||||
# address: 1.2.3.4
|
||||
# port: 1234
|
||||
# Kubernetes configuration dirs and system namespace.
|
||||
# Those are where all the additional config stuff goes
|
||||
# the kubernetes normally puts in /srv/kubernets.
|
||||
# This puts them in a sane location and namespace.
|
||||
# Editting those values will almost surely break something.
|
||||
kube_config_dir: /etc/kubernetes
|
||||
kube_script_dir: "{{ bin_dir }}/kubernetes-scripts"
|
||||
kube_manifest_dir: "{{ kube_config_dir }}/manifests"
|
||||
system_namespace: kube-system
|
||||
|
||||
## Internal loadbalancers for apiservers
|
||||
#loadbalancer_apiserver_localhost: true
|
||||
# This is where all the cert scripts and certs will be located
|
||||
kube_cert_dir: "{{ kube_config_dir }}/ssl"
|
||||
|
||||
## Local loadbalancer should use this port instead, if defined.
|
||||
## Defaults to kube_apiserver_port (6443)
|
||||
#nginx_kube_apiserver_port: 8443
|
||||
# This is where all of the bearer tokens will be stored
|
||||
kube_token_dir: "{{ kube_config_dir }}/tokens"
|
||||
|
||||
### OTHER OPTIONAL VARIABLES
|
||||
## For some things, kubelet needs to load kernel modules. For example, dynamic kernel services are needed
|
||||
## for mounting persistent volumes into containers. These may not be loaded by preinstall kubernetes
|
||||
## processes. For example, ceph and rbd backed volumes. Set to true to allow kubelet to load kernel
|
||||
## modules.
|
||||
# kubelet_load_modules: false
|
||||
# This is where to save basic auth file
|
||||
kube_users_dir: "{{ kube_config_dir }}/users"
|
||||
|
||||
## Internal network total size. This is the prefix of the
|
||||
## entire network. Must be unused in your environment.
|
||||
#kube_network_prefix: 18
|
||||
## Change this to use another Kubernetes version, e.g. a current beta release
|
||||
kube_version: v1.5.1
|
||||
|
||||
## With calico it is possible to distributed routes with border routers of the datacenter.
|
||||
## Warning : enabling router peering will disable calico's default behavior ('node mesh').
|
||||
## The subnets of each nodes will be distributed by the datacenter router
|
||||
#peer_with_router: false
|
||||
# Where the binaries will be downloaded.
|
||||
# Note: ensure that you've enough disk space (about 1G)
|
||||
local_release_dir: "/tmp/releases"
|
||||
# Random shifts for retrying failed ops like pushing/downloading
|
||||
retry_stagger: 5
|
||||
|
||||
# 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
|
||||
|
||||
# Kubernetes 1.5 added a new flag to the apiserver to disable anonymous auth. In previos versions, anonymous auth was
|
||||
# not implemented. As the new flag defaults to true, we have to explicetely disable it. Change this line if you want the
|
||||
# 1.5 default behavior. The flag is actually only added if the used kubernetes version is >= 1.5
|
||||
kube_api_anonymous_auth: false
|
||||
|
||||
# Users to create for basic auth in Kubernetes API via HTTP
|
||||
kube_api_pwd: "changeme"
|
||||
kube_users:
|
||||
kube:
|
||||
pass: "{{kube_api_pwd}}"
|
||||
role: admin
|
||||
root:
|
||||
pass: "{{kube_api_pwd}}"
|
||||
role: admin
|
||||
|
||||
# Kubernetes cluster name, also will be used as DNS domain
|
||||
cluster_name: cluster.local
|
||||
# Subdomains of DNS domain to be resolved via /etc/resolv.conf for hostnet pods
|
||||
ndots: 2
|
||||
# Deploy netchecker app to verify DNS resolve as an HTTP service
|
||||
deploy_netchecker: false
|
||||
|
||||
# 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
|
||||
|
||||
# Etcd access modes:
|
||||
# Enable multiaccess to configure clients to access all of the etcd members directly
|
||||
# as the "http://hostX:port, http://hostY:port, ..." and ignore the proxy loadbalancers.
|
||||
# This may be the case if clients support and loadbalance multiple etcd servers natively.
|
||||
etcd_multiaccess: true
|
||||
|
||||
# Assume there are no internal loadbalancers for apiservers exist and listen on
|
||||
# kube_apiserver_port (default 443)
|
||||
loadbalancer_apiserver_localhost: true
|
||||
|
||||
# Choose network plugin (calico, weave or flannel)
|
||||
# Can also be set to 'cloud', which lets the cloud provider setup appropriate routing
|
||||
kube_network_plugin: flannel
|
||||
|
||||
# Kubernetes internal network for services, unused block of space.
|
||||
kube_service_addresses: 10.233.0.0/18
|
||||
|
||||
# internal network. When used, it will assign IP
|
||||
# addresses from this range to individual pods.
|
||||
# This network must be unused in your network infrastructure!
|
||||
kube_pods_subnet: 10.233.64.0/18
|
||||
|
||||
# internal network total size (optional). This is the prefix of the
|
||||
# entire network. Must be unused in your environment.
|
||||
# kube_network_prefix: 18
|
||||
|
||||
# internal network node size allocation (optional). This is the size allocated
|
||||
# to each node on your network. With these defaults you should have
|
||||
# room for 4096 nodes with 254 pods per node.
|
||||
kube_network_node_prefix: 24
|
||||
|
||||
# With calico it is possible to distributed routes with border routers of the datacenter.
|
||||
peer_with_router: false
|
||||
# Warning : enabling router peering will disable calico's default behavior ('node mesh').
|
||||
# The subnets of each nodes will be distributed by the datacenter router
|
||||
|
||||
# The port the API Server will be listening on.
|
||||
kube_apiserver_ip: "{{ kube_service_addresses|ipaddr('net')|ipaddr(1)|ipaddr('address') }}"
|
||||
kube_apiserver_port: 443 # (https)
|
||||
kube_apiserver_insecure_port: 8080 # (http)
|
||||
# local loadbalancer should use this port instead - default to kube_apiserver_port
|
||||
nginx_kube_apiserver_port: "{{ kube_apiserver_port }}"
|
||||
|
||||
# Internal DNS configuration.
|
||||
# Kubernetes can create and mainatain its own DNS server to resolve service names
|
||||
# into appropriate IP addresses. It's highly advisable to run such DNS server,
|
||||
# as it greatly simplifies configuration of your applications - you can use
|
||||
# service names instead of magic environment variables.
|
||||
|
||||
# Can be dnsmasq_kubedns, kubedns or none
|
||||
dns_mode: dnsmasq_kubedns
|
||||
|
||||
# Can be docker_dns, host_resolvconf or none
|
||||
resolvconf_mode: docker_dns
|
||||
|
||||
## Upstream dns servers used by dnsmasq
|
||||
#upstream_dns_servers:
|
||||
# - 8.8.8.8
|
||||
# - 8.8.4.4
|
||||
|
||||
## There are some changes specific to the cloud providers
|
||||
## for instance we need to encapsulate packets with some network plugins
|
||||
## If set the possible values are either 'gce', 'aws', 'azure', 'openstack', or 'vsphere'
|
||||
## When openstack is used make sure to source in the openstack credentials
|
||||
## like you would do when using nova-client before starting the playbook.
|
||||
#cloud_provider:
|
||||
dns_domain: "{{ cluster_name }}"
|
||||
|
||||
## When azure is used, you need to also set the following variables.
|
||||
## see docs/azure.md for details on how to get these values
|
||||
# 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') }}"
|
||||
|
||||
# There are some changes specific to the cloud providers
|
||||
# for instance we need to encapsulate packets with some network plugins
|
||||
# If set the possible values are either 'gce', 'aws', 'azure' or 'openstack'
|
||||
# When openstack is used make sure to source in the openstack credentials
|
||||
# like you would do when using nova-client before starting the playbook.
|
||||
# When azure is used, you need to also set the following variables.
|
||||
# cloud_provider:
|
||||
|
||||
# see docs/azure.md for details on how to get these values
|
||||
#azure_tenant_id:
|
||||
#azure_subscription_id:
|
||||
#azure_aad_client_id:
|
||||
@@ -65,24 +173,34 @@
|
||||
#azure_vnet_name:
|
||||
#azure_route_table_name:
|
||||
|
||||
|
||||
## Set these proxy values in order to update docker daemon to use proxies
|
||||
#http_proxy: ""
|
||||
#https_proxy: ""
|
||||
#no_proxy: ""
|
||||
# http_proxy: ""
|
||||
# https_proxy: ""
|
||||
# no_proxy: ""
|
||||
|
||||
# Path used to store Docker data
|
||||
docker_daemon_graph: "/var/lib/docker"
|
||||
|
||||
## A string of extra options to pass to the docker daemon.
|
||||
## This string should be exactly as you wish it to appear.
|
||||
## An obvious use case is allowing insecure-registry access
|
||||
## to self hosted registries like so:
|
||||
docker_options: "--insecure-registry={{ kube_service_addresses }} --graph={{ docker_daemon_graph }}"
|
||||
docker_bin_dir: "/usr/bin"
|
||||
|
||||
## Uncomment this if you want to force overlay/overlay2 as docker storage driver
|
||||
## Please note that overlay2 is only supported on newer kernels
|
||||
#docker_storage_options: -s overlay2
|
||||
|
||||
## Default packages to install within the cluster, f.e:
|
||||
#kpm_packages:
|
||||
# K8s image pull policy (imagePullPolicy)
|
||||
k8s_image_pull_policy: IfNotPresent
|
||||
|
||||
# default packages to install within the cluster
|
||||
kpm_packages: []
|
||||
# - name: kube-system/grafana
|
||||
|
||||
## Certificate Management
|
||||
## This setting determines whether certs are generated via scripts or whether a
|
||||
## cluster of Hashicorp's Vault is started to issue certificates (using etcd
|
||||
## as a backend). Options are "script" or "vault"
|
||||
#cert_management: script
|
||||
|
||||
## Please specify true if you want to perform a kernel upgrade
|
||||
kernel_upgrade: false
|
||||
# Settings for containerized control plane (etcd/kubelet)
|
||||
rkt_version: 1.21.0
|
||||
etcd_deployment_type: docker
|
||||
kubelet_deployment_type: docker
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
# Valid bootstrap options (required): ubuntu, coreos, centos, none
|
||||
bootstrap_os: none
|
||||
|
||||
#Directory where etcd data stored
|
||||
etcd_data_dir: /var/lib/etcd
|
||||
|
||||
# Directory where the binaries will be installed
|
||||
bin_dir: /usr/local/bin
|
||||
|
||||
# Kubernetes configuration dirs and system namespace.
|
||||
# Those are where all the additional config stuff goes
|
||||
# the kubernetes normally puts in /srv/kubernets.
|
||||
# This puts them in a sane location and namespace.
|
||||
# Editting those values will almost surely break something.
|
||||
kube_config_dir: /etc/kubernetes
|
||||
kube_script_dir: "{{ bin_dir }}/kubernetes-scripts"
|
||||
kube_manifest_dir: "{{ kube_config_dir }}/manifests"
|
||||
system_namespace: kube-system
|
||||
|
||||
# Logging directory (sysvinit systems)
|
||||
kube_log_dir: "/var/log/kubernetes"
|
||||
|
||||
# This is where all the cert scripts and certs will be located
|
||||
kube_cert_dir: "{{ kube_config_dir }}/ssl"
|
||||
|
||||
# This is where all of the bearer tokens will be stored
|
||||
kube_token_dir: "{{ kube_config_dir }}/tokens"
|
||||
|
||||
# This is where to save basic auth file
|
||||
kube_users_dir: "{{ kube_config_dir }}/users"
|
||||
|
||||
kube_api_anonymous_auth: false
|
||||
|
||||
## Change this to use another Kubernetes version, e.g. a current beta release
|
||||
kube_version: v1.5.3
|
||||
|
||||
# Where the binaries will be downloaded.
|
||||
# Note: ensure that you've enough disk space (about 1G)
|
||||
local_release_dir: "/tmp/releases"
|
||||
# Random shifts for retrying failed ops like pushing/downloading
|
||||
retry_stagger: 5
|
||||
|
||||
# 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
|
||||
|
||||
# Users to create for basic auth in Kubernetes API via HTTP
|
||||
kube_api_pwd: "changeme"
|
||||
kube_users:
|
||||
kube:
|
||||
pass: "{{kube_api_pwd}}"
|
||||
role: admin
|
||||
root:
|
||||
pass: "{{kube_api_pwd}}"
|
||||
role: admin
|
||||
|
||||
|
||||
|
||||
## It is possible to activate / deactivate selected authentication methods (basic auth, static token auth)
|
||||
#kube_oidc_auth: false
|
||||
#kube_basic_auth: false
|
||||
#kube_token_auth: false
|
||||
|
||||
|
||||
## Variables for OpenID Connect Configuration https://kubernetes.io/docs/admin/authentication/
|
||||
## To use OpenID you have to deploy additional an OpenID Provider (e.g Dex, Keycloak, ...)
|
||||
|
||||
# kube_oidc_url: https:// ...
|
||||
# kube_oidc_client_id: kubernetes
|
||||
## Optional settings for OIDC
|
||||
# kube_oidc_ca_file: {{ kube_cert_dir }}/ca.pem
|
||||
# kube_oidc_username_claim: sub
|
||||
# kube_oidc_groups_claim: groups
|
||||
|
||||
|
||||
# Choose network plugin (calico, weave or flannel)
|
||||
# Can also be set to 'cloud', which lets the cloud provider setup appropriate routing
|
||||
kube_network_plugin: calico
|
||||
|
||||
# Enable kubernetes network policies
|
||||
enable_network_policy: false
|
||||
|
||||
# Kubernetes internal network for services, unused block of space.
|
||||
kube_service_addresses: 10.233.0.0/18
|
||||
|
||||
# internal network. When used, it will assign IP
|
||||
# addresses from this range to individual pods.
|
||||
# This network must be unused in your network infrastructure!
|
||||
kube_pods_subnet: 10.233.64.0/18
|
||||
|
||||
# internal network node size allocation (optional). This is the size allocated
|
||||
# to each node on your network. With these defaults you should have
|
||||
# room for 4096 nodes with 254 pods per node.
|
||||
kube_network_node_prefix: 24
|
||||
|
||||
# The port the API Server will be listening on.
|
||||
kube_apiserver_ip: "{{ kube_service_addresses|ipaddr('net')|ipaddr(1)|ipaddr('address') }}"
|
||||
kube_apiserver_port: 6443 # (https)
|
||||
kube_apiserver_insecure_port: 8080 # (http)
|
||||
|
||||
# DNS configuration.
|
||||
# Kubernetes cluster name, also will be used as DNS domain
|
||||
cluster_name: cluster.local
|
||||
# Subdomains of DNS domain to be resolved via /etc/resolv.conf for hostnet pods
|
||||
ndots: 2
|
||||
# Can be dnsmasq_kubedns, kubedns or none
|
||||
dns_mode: dnsmasq_kubedns
|
||||
# Can be docker_dns, host_resolvconf or none
|
||||
resolvconf_mode: docker_dns
|
||||
# Deploy netchecker app to verify DNS resolve as an HTTP service
|
||||
deploy_netchecker: false
|
||||
# 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') }}"
|
||||
dns_domain: "{{ cluster_name }}"
|
||||
|
||||
# Path used to store Docker data
|
||||
docker_daemon_graph: "/var/lib/docker"
|
||||
|
||||
## A string of extra options to pass to the docker daemon.
|
||||
## This string should be exactly as you wish it to appear.
|
||||
## An obvious use case is allowing insecure-registry access
|
||||
## to self hosted registries like so:
|
||||
docker_options: "--insecure-registry={{ kube_service_addresses }} --graph={{ docker_daemon_graph }}"
|
||||
docker_bin_dir: "/usr/bin"
|
||||
|
||||
# Settings for containerized control plane (etcd/kubelet/secrets)
|
||||
etcd_deployment_type: docker
|
||||
kubelet_deployment_type: docker
|
||||
cert_management: script
|
||||
vault_deployment_type: docker
|
||||
|
||||
# K8s image pull policy (imagePullPolicy)
|
||||
k8s_image_pull_policy: IfNotPresent
|
||||
|
||||
# Monitoring apps for k8s
|
||||
efk_enabled: false
|
||||
|
||||
# Helm deployment
|
||||
helm_enabled: false
|
||||
@@ -1,14 +1,2 @@
|
||||
ansible==2.2.1.0
|
||||
ansible>=2.2.1
|
||||
netaddr
|
||||
# Ansible 2.2.1 requires jinja2<2.9, see <https://github.com/ansible/ansible/blob/v2.2.1.0-1/setup.py#L25>,
|
||||
# but without explicit limiting upper jinja2 version here pip ignores
|
||||
# Ansible requirements and installs latest available jinja2
|
||||
# (pip is not very smart here), which is incompatible with with
|
||||
# Ansible 2.2.1.
|
||||
# With incompatible jinja2 version "ansible-vault create" (and probably other parts)
|
||||
# fails with:
|
||||
# ERROR! Unexpected Exception: The 'jinja2<2.9' distribution was not found
|
||||
# and is required by ansible
|
||||
# This upper limit should be removed in 2.2.2 release, see:
|
||||
# <https://github.com/ansible/ansible/commit/978311bf3f91dae5806ab72b665b0937adce38ad>
|
||||
jinja2>=2.8,<2.9
|
||||
|
||||
13
reset.yml
13
reset.yml
@@ -1,18 +1,5 @@
|
||||
---
|
||||
|
||||
- hosts: all
|
||||
vars_prompt:
|
||||
name: "reset_confirmation"
|
||||
prompt: "Are you sure you want to reset cluster state? Type 'yes' to reset your cluster."
|
||||
default: "no"
|
||||
private: no
|
||||
|
||||
pre_tasks:
|
||||
- name: check confirmation
|
||||
fail:
|
||||
msg: "Reset confirmation failed"
|
||||
when: reset_confirmation != "yes"
|
||||
|
||||
roles:
|
||||
- { role: kargo-defaults}
|
||||
- { role: reset, tags: reset }
|
||||
|
||||
@@ -1,13 +1,10 @@
|
||||
---
|
||||
kube_cert_group: kube-cert
|
||||
etcd_data_dir: "/var/lib/etcd"
|
||||
|
||||
addusers:
|
||||
etcd:
|
||||
name: etcd
|
||||
comment: "Etcd user"
|
||||
createhome: yes
|
||||
home: "{{ etcd_data_dir }}"
|
||||
home: "/var/lib/etcd"
|
||||
system: yes
|
||||
shell: /bin/nologin
|
||||
kube:
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
---
|
||||
- name: User | Create User Group
|
||||
group:
|
||||
name: "{{user.group|default(user.name)}}"
|
||||
system: "{{user.system|default(omit)}}"
|
||||
group: name={{user.group|default(user.name)}} system={{user.system|default(omit)}}
|
||||
|
||||
- name: User | Create User
|
||||
user:
|
||||
|
||||
@@ -3,7 +3,7 @@ addusers:
|
||||
- name: etcd
|
||||
comment: "Etcd user"
|
||||
createhome: yes
|
||||
home: "{{ etcd_data_dir }}"
|
||||
home: "/var/lib/etcd"
|
||||
system: yes
|
||||
shell: /bin/nologin
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ addusers:
|
||||
- name: etcd
|
||||
comment: "Etcd user"
|
||||
createhome: yes
|
||||
home: "{{ etcd_data_dir }}"
|
||||
home: "/var/lib/etcd"
|
||||
system: yes
|
||||
shell: /bin/nologin
|
||||
|
||||
|
||||
@@ -15,6 +15,4 @@
|
||||
|
||||
- name: create ssh bastion conf
|
||||
become: false
|
||||
template:
|
||||
src: ssh-bastion.conf
|
||||
dest: "{{ playbook_dir }}/ssh-bastion.conf"
|
||||
template: src=ssh-bastion.conf dest="{{ playbook_dir }}/ssh-bastion.conf"
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
---
|
||||
|
||||
- name: Check presence of fastestmirror.conf
|
||||
stat:
|
||||
path: /etc/yum/pluginconf.d/fastestmirror.conf
|
||||
stat: path=/etc/yum/pluginconf.d/fastestmirror.conf
|
||||
register: fastestmirror
|
||||
|
||||
# fastestmirror plugin actually slows down Ansible deployments
|
||||
|
||||
@@ -18,14 +18,11 @@
|
||||
register: need_pip
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
check_mode: no
|
||||
when: (need_bootstrap | failed)
|
||||
tags: facts
|
||||
|
||||
- name: Bootstrap | Copy get-pip.py
|
||||
copy:
|
||||
src: get-pip.py
|
||||
dest: ~/get-pip.py
|
||||
copy: src=get-pip.py dest=~/get-pip.py
|
||||
when: (need_pip | failed)
|
||||
|
||||
- name: Bootstrap | Install pip
|
||||
@@ -33,16 +30,11 @@
|
||||
when: (need_pip | failed)
|
||||
|
||||
- name: Bootstrap | Remove get-pip.py
|
||||
file:
|
||||
path: ~/get-pip.py
|
||||
state: absent
|
||||
file: path=~/get-pip.py state=absent
|
||||
when: (need_pip | failed)
|
||||
|
||||
- name: Bootstrap | Install pip launcher
|
||||
copy:
|
||||
src: runner
|
||||
dest: /opt/bin/pip
|
||||
mode: 0755
|
||||
copy: src=runner dest=/opt/bin/pip mode=0755
|
||||
when: (need_pip | failed)
|
||||
|
||||
- name: Install required python modules
|
||||
@@ -50,3 +42,10 @@
|
||||
name: "{{ item }}"
|
||||
with_items: "{{pip_python_modules}}"
|
||||
|
||||
- name: Check configured hostname
|
||||
shell: hostname
|
||||
register: configured_hostname
|
||||
|
||||
- name: Assign inventory name to unconfigured hostnames
|
||||
shell: sh -c "echo \"{{inventory_hostname}}\" > /etc/hostname; hostname \"{{inventory_hostname}}\""
|
||||
when: (configured_hostname.stdout == 'localhost')
|
||||
|
||||
@@ -2,20 +2,14 @@
|
||||
# raw: cat /etc/issue.net | grep '{{ bootstrap_versions }}'
|
||||
|
||||
- name: Bootstrap | Check if bootstrap is needed
|
||||
raw: which "{{ item }}"
|
||||
raw: which python
|
||||
register: need_bootstrap
|
||||
failed_when: false
|
||||
with_items:
|
||||
- python
|
||||
- pip
|
||||
tags: facts
|
||||
|
||||
- name: Bootstrap | Install python 2.x and pip
|
||||
raw:
|
||||
apt-get update && \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y python-minimal python-pip
|
||||
when:
|
||||
"{{ need_bootstrap.results | map(attribute='rc') | sort | last | bool }}"
|
||||
- name: Bootstrap | Install python 2.x
|
||||
raw: apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y python-minimal
|
||||
when: need_bootstrap | failed
|
||||
|
||||
- set_fact:
|
||||
ansible_python_interpreter: "/usr/bin/python"
|
||||
|
||||
@@ -8,23 +8,4 @@
|
||||
- include: bootstrap-centos.yml
|
||||
when: bootstrap_os == "centos"
|
||||
|
||||
- include: setup-pipelining.yml
|
||||
|
||||
- name: check if atomic host
|
||||
stat:
|
||||
path: /run/ostree-booted
|
||||
register: ostree
|
||||
|
||||
- set_fact:
|
||||
is_atomic: "{{ ostree.stat.exists }}"
|
||||
|
||||
- name: Gather nodes hostnames
|
||||
setup:
|
||||
gather_subset: '!all'
|
||||
filter: ansible_hostname
|
||||
|
||||
- name: Assign inventory name to unconfigured hostnames
|
||||
hostname:
|
||||
name: "{{inventory_hostname}}"
|
||||
when: ansible_hostname == 'localhost'
|
||||
|
||||
- include: setup-pipelining.yml
|
||||
@@ -2,8 +2,5 @@
|
||||
# Remove requiretty to make ssh pipelining work
|
||||
|
||||
- name: Remove require tty
|
||||
lineinfile:
|
||||
regexp: '^\w+\s+requiretty'
|
||||
dest: /etc/sudoers
|
||||
state: absent
|
||||
lineinfile: regexp="^\w+\s+requiretty" dest=/etc/sudoers state=absent
|
||||
|
||||
|
||||
@@ -24,9 +24,5 @@ dnsmasq_image_tag: "{{ dnsmasq_version }}"
|
||||
# Limits for dnsmasq/kubedns apps
|
||||
dns_cpu_limit: 100m
|
||||
dns_memory_limit: 170Mi
|
||||
dns_cpu_requests: 40m
|
||||
dns_memory_requests: 50Mi
|
||||
|
||||
# Autoscaler parameters
|
||||
dnsmasq_nodes_per_replica: 10
|
||||
dnsmasq_min_replicas: 1
|
||||
dns_cpu_requests: 70m
|
||||
dns_memory_requests: 70Mi
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
---
|
||||
- include: pre_upgrade.yml
|
||||
|
||||
- name: ensure dnsmasq.d directory exists
|
||||
file:
|
||||
path: /etc/dnsmasq.d
|
||||
@@ -13,36 +11,15 @@
|
||||
state: directory
|
||||
tags: bootstrap-os
|
||||
|
||||
- name: check system nameservers
|
||||
shell: awk '/^nameserver/ {print $NF}' /etc/resolv.conf
|
||||
changed_when: False
|
||||
register: system_nameservers
|
||||
|
||||
- name: init system_and_upstream_dns_servers
|
||||
set_fact:
|
||||
system_and_upstream_dns_servers: "{{ upstream_dns_servers|default([]) }}"
|
||||
|
||||
- name: combine upstream_dns_servers and system nameservers (only for docker_dns)
|
||||
set_fact:
|
||||
system_and_upstream_dns_servers: "{{ system_and_upstream_dns_servers | union(system_nameservers.stdout_lines) | unique }}"
|
||||
when: system_nameservers.stdout != "" and resolvconf_mode != 'host_resolvconf'
|
||||
|
||||
- name: Write dnsmasq configuration
|
||||
template:
|
||||
src: 01-kube-dns.conf.j2
|
||||
dest: /etc/dnsmasq.d-available/01-kube-dns.conf
|
||||
mode: 0755
|
||||
backup: yes
|
||||
register: dnsmasq_config
|
||||
|
||||
- name: Stat dnsmasq link
|
||||
stat:
|
||||
path: /etc/dnsmasq.d-available/01-kube-dns.conf
|
||||
register: dnsmasq_stat
|
||||
|
||||
- name: Stat dnsmasq link
|
||||
stat:
|
||||
path: /etc/dnsmasq.d/01-kube-dns.conf
|
||||
- name: Stat dnsmasq configuration
|
||||
stat: path=/etc/dnsmasq.d/01-kube-dns.conf
|
||||
register: sym
|
||||
|
||||
- name: Move previous configuration
|
||||
@@ -57,19 +34,16 @@
|
||||
state: link
|
||||
|
||||
- name: Create dnsmasq manifests
|
||||
template:
|
||||
src: "{{item.file}}"
|
||||
dest: "{{kube_config_dir}}/{{item.file}}"
|
||||
template: src={{item.file}} dest={{kube_config_dir}}/{{item.file}}
|
||||
with_items:
|
||||
- {name: dnsmasq, file: dnsmasq-deploy.yml, type: deployment}
|
||||
- {name: dnsmasq, file: dnsmasq-svc.yml, type: svc}
|
||||
- {name: dnsmasq-autoscaler, file: dnsmasq-autoscaler.yml, type: deployment}
|
||||
- {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: "{{item.item.name}}"
|
||||
name: dnsmasq
|
||||
namespace: "{{system_namespace}}"
|
||||
kubectl: "{{bin_dir}}/kubectl"
|
||||
resource: "{{item.item.type}}"
|
||||
@@ -82,6 +56,6 @@
|
||||
wait_for:
|
||||
host: "{{dns_server}}"
|
||||
port: 53
|
||||
timeout: 180
|
||||
when: inventory_hostname == groups['kube-node'][0] and groups['kube-node'][0] in ansible_play_hosts
|
||||
|
||||
delay: 5
|
||||
when: inventory_hostname == groups['kube-node'][0]
|
||||
tags: facts
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
---
|
||||
- name: Delete legacy dnsmasq daemonset
|
||||
kube:
|
||||
name: dnsmasq
|
||||
namespace: "{{system_namespace}}"
|
||||
kubectl: "{{bin_dir}}/kubectl"
|
||||
resource: "ds"
|
||||
state: absent
|
||||
when: inventory_hostname == groups['kube-master'][0]
|
||||
@@ -11,19 +11,20 @@ server=/{{ dns_domain }}/{{ skydns_server }}
|
||||
local=/{{ bogus_domains }}
|
||||
|
||||
#Set upstream dns servers
|
||||
{% if system_and_upstream_dns_servers|length > 0 %}
|
||||
{% for srv in system_and_upstream_dns_servers %}
|
||||
{% if upstream_dns_servers is defined %}
|
||||
{% for srv in upstream_dns_servers %}
|
||||
server={{ srv }}
|
||||
{% endfor %}
|
||||
no-resolv
|
||||
{% elif resolvconf_mode == 'host_resolvconf' %}
|
||||
{# The default resolver is only needed when the hosts resolv.conf was modified by us. If it was not modified, we can rely on dnsmasq to reuse the systems resolv.conf #}
|
||||
server={{ default_resolver }}
|
||||
no-resolv
|
||||
{% endif %}
|
||||
|
||||
{% if kube_log_level == '4' %}
|
||||
log-queries
|
||||
{% endif %}
|
||||
no-resolv
|
||||
bogus-priv
|
||||
no-negcache
|
||||
cache-size={{ cache_size }}
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# Copyright 2016 The Kubernetes Authors.
|
||||
#
|
||||
# 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.
|
||||
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: dnsmasq-autoscaler
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: dnsmasq-autoscaler
|
||||
kubernetes.io/cluster-service: "true"
|
||||
addonmanager.kubernetes.io/mode: Reconcile
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: dnsmasq-autoscaler
|
||||
annotations:
|
||||
scheduler.alpha.kubernetes.io/critical-pod: ''
|
||||
scheduler.alpha.kubernetes.io/tolerations: '[{"key":"CriticalAddonsOnly", "operator":"Exists"}]'
|
||||
spec:
|
||||
containers:
|
||||
- name: autoscaler
|
||||
image: gcr.io/google_containers/cluster-proportional-autoscaler-amd64:1.1.1
|
||||
resources:
|
||||
requests:
|
||||
cpu: "20m"
|
||||
memory: "10Mi"
|
||||
command:
|
||||
- /cluster-proportional-autoscaler
|
||||
- --namespace=kube-system
|
||||
- --configmap=dnsmasq-autoscaler
|
||||
- --target=ReplicationController/dnsmasq
|
||||
# When cluster is using large nodes(with more cores), "coresPerReplica" should dominate.
|
||||
# If using small nodes, "nodesPerReplica" should dominate.
|
||||
- --default-params={"linear":{"nodesPerReplica":{{ dnsmasq_nodes_per_replica }},"preventSinglePointFailure":true}}
|
||||
- --logtostderr=true
|
||||
- --v={{ kube_log_level }}
|
||||
|
||||
@@ -1,25 +1,16 @@
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: dnsmasq
|
||||
namespace: "{{system_namespace}}"
|
||||
labels:
|
||||
k8s-app: dnsmasq
|
||||
kubernetes.io/cluster-service: "true"
|
||||
spec:
|
||||
replicas: {{ dnsmasq_min_replicas }}
|
||||
selector:
|
||||
matchLabels:
|
||||
k8s-app: dnsmasq
|
||||
strategy:
|
||||
type: "Recreate"
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: dnsmasq
|
||||
kubernetes.io/cluster-service: "true"
|
||||
kargo/dnsmasq-checksum: "{{ dnsmasq_stat.stat.checksum }}"
|
||||
spec:
|
||||
containers:
|
||||
- name: dnsmasq
|
||||
@@ -64,4 +55,3 @@ spec:
|
||||
hostPath:
|
||||
path: /etc/dnsmasq.d-available
|
||||
dnsPolicy: Default # Don't use cluster DNS.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
docker_version: '1.13'
|
||||
docker_version: '1.12'
|
||||
|
||||
docker_package_info:
|
||||
pkgs:
|
||||
|
||||
@@ -4,4 +4,3 @@ baseurl=https://yum.dockerproject.org/repo/main/centos/7
|
||||
enabled=1
|
||||
gpgcheck=1
|
||||
gpgkey=https://yum.dockerproject.org/gpg
|
||||
{% if http_proxy is defined %}proxy={{ http_proxy }}{% endif %}
|
||||
@@ -23,9 +23,7 @@
|
||||
state: restarted
|
||||
|
||||
- name: Docker | pause while Docker restarts
|
||||
pause:
|
||||
seconds: 10
|
||||
prompt: "Waiting for docker restart"
|
||||
pause: seconds=10 prompt="Waiting for docker restart"
|
||||
|
||||
- name: Docker | wait for docker
|
||||
command: "{{ docker_bin_dir }}/docker images"
|
||||
|
||||
@@ -34,11 +34,11 @@
|
||||
keyserver: "{{docker_repo_key_info.keyserver}}"
|
||||
state: present
|
||||
register: keyserver_task_result
|
||||
until: keyserver_task_result|succeeded
|
||||
until: keyserver_task_result|success
|
||||
retries: 4
|
||||
delay: "{{ retry_stagger | random + 3 }}"
|
||||
with_items: "{{ docker_repo_key_info.repo_keys }}"
|
||||
when: not (ansible_os_family in ["CoreOS", "Container Linux by CoreOS"] or is_atomic)
|
||||
when: not ansible_os_family in ["CoreOS", "Container Linux by CoreOS"]
|
||||
|
||||
- name: ensure docker repository is enabled
|
||||
action: "{{ docker_repo_info.pkg_repo }}"
|
||||
@@ -46,13 +46,13 @@
|
||||
repo: "{{item}}"
|
||||
state: present
|
||||
with_items: "{{ docker_repo_info.repos }}"
|
||||
when: not (ansible_os_family in ["CoreOS", "Container Linux by CoreOS"] or is_atomic) and (docker_repo_info.repos|length > 0)
|
||||
when: (not ansible_os_family in ["CoreOS", "Container Linux by CoreOS"]) and (docker_repo_info.repos|length > 0)
|
||||
|
||||
- name: Configure docker repository on RedHat/CentOS
|
||||
template:
|
||||
src: "rh_docker.repo.j2"
|
||||
copy:
|
||||
src: "rh_docker.repo"
|
||||
dest: "/etc/yum.repos.d/docker.repo"
|
||||
when: ansible_distribution in ["CentOS","RedHat"] and not is_atomic
|
||||
when: ansible_distribution in ["CentOS","RedHat"]
|
||||
|
||||
- name: ensure docker packages are installed
|
||||
action: "{{ docker_package_info.pkg_mgr }}"
|
||||
@@ -61,15 +61,15 @@
|
||||
force: "{{item.force|default(omit)}}"
|
||||
state: present
|
||||
register: docker_task_result
|
||||
until: docker_task_result|succeeded
|
||||
until: docker_task_result|success
|
||||
retries: 4
|
||||
delay: "{{ retry_stagger | random + 3 }}"
|
||||
with_items: "{{ docker_package_info.pkgs }}"
|
||||
notify: restart docker
|
||||
when: not (ansible_os_family in ["CoreOS", "Container Linux by CoreOS"] or is_atomic) and (docker_package_info.pkgs|length > 0)
|
||||
when: (not ansible_os_family in ["CoreOS", "Container Linux by CoreOS"]) and (docker_package_info.pkgs|length > 0)
|
||||
|
||||
- name: check minimum docker version for docker_dns mode. You need at least docker version >= 1.12 for resolvconf_mode=docker_dns
|
||||
command: "docker version -f '{{ '{{' }}.Client.Version{{ '}}' }}'"
|
||||
raw: docker version -f "{{ '{{' }}.Client.Version{{ '}}' }}"
|
||||
register: docker_version
|
||||
failed_when: docker_version.stdout|version_compare('1.12', '<')
|
||||
changed_when: false
|
||||
|
||||
@@ -32,13 +32,11 @@
|
||||
shell: grep "^nameserver" /etc/resolv.conf | sed 's/^nameserver\s*//'
|
||||
changed_when: False
|
||||
register: system_nameservers
|
||||
check_mode: no
|
||||
|
||||
- name: check system search domains
|
||||
shell: grep "^search" /etc/resolv.conf | sed 's/^search\s*//'
|
||||
changed_when: False
|
||||
register: system_search_domains
|
||||
check_mode: no
|
||||
|
||||
- name: add system nameservers to docker options
|
||||
set_fact:
|
||||
@@ -51,16 +49,13 @@
|
||||
when: system_search_domains.stdout != ""
|
||||
|
||||
- name: check number of nameservers
|
||||
fail:
|
||||
msg: "Too many nameservers"
|
||||
fail: msg="Too many nameservers"
|
||||
when: docker_dns_servers|length > 3
|
||||
|
||||
- name: check number of search domains
|
||||
fail:
|
||||
msg: "Too many search domains"
|
||||
fail: msg="Too many search domains"
|
||||
when: docker_dns_search_domains|length > 6
|
||||
|
||||
- name: check length of search domains
|
||||
fail:
|
||||
msg: "Search domains exceeded limit of 256 characters"
|
||||
fail: msg="Search domains exceeded limit of 256 characters"
|
||||
when: docker_dns_search_domains|join(' ')|length > 256
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
---
|
||||
- name: Create docker service systemd directory if it doesn't exist
|
||||
file:
|
||||
path: /etc/systemd/system/docker.service.d
|
||||
state: directory
|
||||
file: path=/etc/systemd/system/docker.service.d state=directory
|
||||
|
||||
- name: Write docker proxy drop-in
|
||||
template:
|
||||
@@ -15,14 +13,7 @@
|
||||
src: docker.service.j2
|
||||
dest: /etc/systemd/system/docker.service
|
||||
register: docker_service_file
|
||||
when: not (ansible_os_family in ["CoreOS", "Container Linux by CoreOS"] or is_atomic)
|
||||
|
||||
- name: Write docker.service systemd file for atomic
|
||||
template:
|
||||
src: docker_atomic.service.j2
|
||||
dest: /etc/systemd/system/docker.service
|
||||
notify: restart docker
|
||||
when: is_atomic
|
||||
when: not ansible_os_family in ["CoreOS", "Container Linux by CoreOS"]
|
||||
|
||||
- name: Write docker options systemd drop-in
|
||||
template:
|
||||
|
||||
@@ -3,4 +3,4 @@ Environment="DOCKER_DNS_OPTIONS=\
|
||||
{% for d in docker_dns_servers %}--dns {{ d }} {% endfor %} \
|
||||
{% for d in docker_dns_search_domains %}--dns-search {{ d }} {% endfor %} \
|
||||
{% for o in docker_dns_options %}--dns-opt {{ o }} {% endfor %} \
|
||||
"
|
||||
"
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
[Service]
|
||||
Environment="DOCKER_OPTS={% if docker_options is defined %}{{ docker_options }}{% endif %} --iptables={% if kube_network_plugin == 'flannel' %}true{% else %}false{% endif %}"
|
||||
Environment="DOCKER_OPTS={% if docker_options is defined %}{{ docker_options }}{% endif %}"
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
[Unit]
|
||||
Description=Docker Application Container Engine
|
||||
Documentation=http://docs.docker.com
|
||||
After=network.target
|
||||
Wants=docker-storage-setup.service
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
NotifyAccess=all
|
||||
EnvironmentFile=-/etc/sysconfig/docker
|
||||
EnvironmentFile=-/etc/sysconfig/docker-storage
|
||||
Environment=GOTRACEBACK=crash
|
||||
Environment=DOCKER_HTTP_HOST_COMPAT=1
|
||||
Environment=PATH=/usr/libexec/docker:/usr/bin:/usr/sbin
|
||||
ExecReload=/bin/kill -s HUP $MAINPID
|
||||
Delegate=yes
|
||||
KillMode=process
|
||||
ExecStart=/usr/bin/dockerd-current \
|
||||
--add-runtime docker-runc=/usr/libexec/docker/docker-runc-current \
|
||||
--default-runtime=docker-runc \
|
||||
--exec-opt native.cgroupdriver=systemd \
|
||||
--userland-proxy-path=/usr/libexec/docker/docker-proxy-current \
|
||||
$DOCKER_OPTS \
|
||||
$DOCKER_STORAGE_OPTIONS \
|
||||
$DOCKER_NETWORK_OPTIONS \
|
||||
$DOCKER_DNS_OPTIONS \
|
||||
$ADD_REGISTRY \
|
||||
$BLOCK_REGISTRY \
|
||||
$INSECURE_REGISTRY
|
||||
LimitNOFILE=1048576
|
||||
LimitNPROC=1048576
|
||||
LimitCORE=infinity
|
||||
TimeoutStartSec=1min
|
||||
Restart=on-abnormal
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -5,9 +5,7 @@ docker_versioned_pkg:
|
||||
'latest': docker-engine
|
||||
'1.11': docker-engine=1.11.2-0~{{ ansible_distribution_release|lower }}
|
||||
'1.12': docker-engine=1.12.6-0~debian-{{ ansible_distribution_release|lower }}
|
||||
'1.13': docker-engine=1.13.1-0~debian-{{ ansible_distribution_release|lower }}
|
||||
'stable': docker-engine=17.03.0~ce-0~debian-{{ ansible_distribution_release|lower }}
|
||||
'edge': docker-engine=17.03.0~ce-0~debian-{{ ansible_distribution_release|lower }}
|
||||
'1.13': docker-engine=1.13.0-0~debian-{{ ansible_distribution_release|lower }}
|
||||
|
||||
docker_package_info:
|
||||
pkg_mgr: apt
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
docker_kernel_min_version: '0'
|
||||
|
||||
# https://docs.docker.com/engine/installation/linux/fedora/#install-from-a-package
|
||||
# https://download.docker.com/linux/fedora/7/x86_64/stable/
|
||||
# the package names below are guesses;
|
||||
# docs mention `sudo dnf config-manager --enable docker-ce-edge` for edge
|
||||
docker_versioned_pkg:
|
||||
'latest': docker
|
||||
'1.11': docker-1:1.11.2
|
||||
'1.12': docker-1:1.12.5
|
||||
'stable': docker-ce
|
||||
'edge': docker-ce-edge
|
||||
|
||||
docker_package_info:
|
||||
pkg_mgr: dnf
|
||||
|
||||
@@ -6,12 +6,7 @@ docker_versioned_pkg:
|
||||
'latest': docker-engine
|
||||
'1.11': docker-engine-1.11.2-1.el7.centos
|
||||
'1.12': docker-engine-1.12.6-1.el7.centos
|
||||
'1.13': docker-engine-1.13.1-1.el7.centos
|
||||
'stable': docker-engine-17.03.0.ce-1.el7.centos
|
||||
'edge': docker-engine-17.03.0.ce-1.el7.centos
|
||||
|
||||
# https://docs.docker.com/engine/installation/linux/centos/#install-from-a-package
|
||||
# https://download.docker.com/linux/centos/7/x86_64/stable/Packages/
|
||||
'1.13': docker-engine-1.13.0-1.el7.centos
|
||||
|
||||
docker_package_info:
|
||||
pkg_mgr: yum
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
---
|
||||
docker_version: '1.12'
|
||||
docker_kernel_min_version: '3.10'
|
||||
|
||||
# https://apt.dockerproject.org/repo/dists/ubuntu-xenial/main/filelist
|
||||
@@ -6,9 +7,7 @@ docker_versioned_pkg:
|
||||
'latest': docker-engine
|
||||
'1.11': docker-engine=1.11.1-0~{{ ansible_distribution_release|lower }}
|
||||
'1.12': docker-engine=1.12.6-0~ubuntu-{{ ansible_distribution_release|lower }}
|
||||
'1.13': docker-engine=1.13.1-0~ubuntu-{{ ansible_distribution_release|lower }}
|
||||
'stable': docker-engine=17.03.0~ce-0~ubuntu-{{ ansible_distribution_release|lower }}
|
||||
'edge': docker-engine=17.03.0~ce-0~ubuntu-{{ ansible_distribution_release|lower }}
|
||||
'1.13': docker-engine=1.13.0-0~ubuntu-{{ ansible_distribution_release|lower }}
|
||||
|
||||
docker_package_info:
|
||||
pkg_mgr: apt
|
||||
|
||||
@@ -3,9 +3,9 @@ local_release_dir: /tmp
|
||||
|
||||
# if this is set to true will only download files once. Doesn't work
|
||||
# on Container Linux by CoreOS unless the download_localhost is true and localhost
|
||||
# is running another OS type. Default compress level is 1 (fastest).
|
||||
# is running another OS type. Default compress level is 9 (best).
|
||||
download_run_once: False
|
||||
download_compress: 1
|
||||
download_compress: 9
|
||||
|
||||
# if this is set to true, uses the localhost for download_run_once mode
|
||||
# (requires docker and sudo to access docker). You may want this option for
|
||||
@@ -18,13 +18,11 @@ download_localhost: False
|
||||
download_always_pull: False
|
||||
|
||||
# Versions
|
||||
kube_version: v1.5.3
|
||||
etcd_version: v3.0.6
|
||||
#TODO(mattymo): Move calico versions to roles/network_plugins/calico/defaults
|
||||
# after migration to container download
|
||||
calico_version: "v1.1.0-rc8"
|
||||
calico_cni_version: "v1.5.6"
|
||||
calico_policy_version: "v0.5.4"
|
||||
calico_version: "v1.0.0"
|
||||
calico_cni_version: "v1.5.5"
|
||||
weave_version: 1.8.2
|
||||
flannel_version: v0.6.2
|
||||
pod_infra_version: 3.0
|
||||
@@ -49,7 +47,7 @@ calico_node_image_tag: "{{ calico_version }}"
|
||||
calico_cni_image_repo: "calico/cni"
|
||||
calico_cni_image_tag: "{{ calico_cni_version }}"
|
||||
calico_policy_image_repo: "calico/kube-policy-controller"
|
||||
calico_policy_image_tag: "{{ calico_policy_version }}"
|
||||
calico_policy_image_tag: "v0.5.1"
|
||||
# TODO(adidenko): switch to "calico/routereflector" when
|
||||
# https://github.com/projectcalico/calico-bird/pull/27 is merged
|
||||
calico_rr_image_repo: "quay.io/l23network/routereflector"
|
||||
@@ -61,9 +59,11 @@ hyperkube_image_repo: "quay.io/coreos/hyperkube"
|
||||
hyperkube_image_tag: "{{ kube_version }}_coreos.0"
|
||||
pod_infra_image_repo: "gcr.io/google_containers/pause-amd64"
|
||||
pod_infra_image_tag: "{{ pod_infra_version }}"
|
||||
netcheck_tag: "v1.0"
|
||||
netcheck_agent_img_repo: "quay.io/l23network/k8s-netchecker-agent"
|
||||
netcheck_server_img_repo: "quay.io/l23network/k8s-netchecker-server"
|
||||
netcheck_tag: v0.1
|
||||
netcheck_kubectl_tag: v0.18.0-120-gaeb4ac55ad12b1-dirty
|
||||
netcheck_agent_img_repo: "quay.io/l23network/mcp-netchecker-agent"
|
||||
netcheck_server_img_repo: "quay.io/l23network/mcp-netchecker-server"
|
||||
netcheck_kubectl_img_repo: "gcr.io/google_containers/kubectl"
|
||||
weave_kube_image_repo: "weaveworks/weave-kube"
|
||||
weave_kube_image_tag: "{{ weave_version }}"
|
||||
weave_npc_image_repo: "weaveworks/weave-npc"
|
||||
@@ -82,22 +82,6 @@ kubedns_image_repo: "gcr.io/google_containers/kubedns-amd64"
|
||||
kubedns_image_tag: "{{ kubedns_version }}"
|
||||
test_image_repo: busybox
|
||||
test_image_tag: latest
|
||||
elasticsearch_version: "v2.4.1"
|
||||
elasticsearch_image_repo: "gcr.io/google_containers/elasticsearch"
|
||||
elasticsearch_image_tag: "{{ elasticsearch_version }}"
|
||||
fluentd_version: "1.22"
|
||||
fluentd_image_repo: "gcr.io/google_containers/fluentd-elasticsearch"
|
||||
fluentd_image_tag: "{{ fluentd_version }}"
|
||||
kibana_version: "v4.6.1"
|
||||
kibana_image_repo: "gcr.io/google_containers/kibana"
|
||||
kibana_image_tag: "{{ kibana_version }}"
|
||||
|
||||
helm_version: "v2.2.2"
|
||||
helm_image_repo: "lachlanevenson/k8s-helm"
|
||||
helm_image_tag: "{{ helm_version }}"
|
||||
tiller_version: "{{ helm_version }}"
|
||||
tiller_image_repo: "gcr.io/kubernetes-helm/tiller"
|
||||
tiller_image_tag: "{{ tiller_version }}"
|
||||
|
||||
downloads:
|
||||
netcheck_server:
|
||||
@@ -112,6 +96,12 @@ downloads:
|
||||
tag: "{{ netcheck_tag }}"
|
||||
sha256: "{{ netcheck_agent_digest_checksum|default(None) }}"
|
||||
enabled: "{{ deploy_netchecker|bool }}"
|
||||
netcheck_kubectl:
|
||||
container: true
|
||||
repo: "{{ netcheck_kubectl_img_repo }}"
|
||||
tag: "{{ netcheck_kubectl_tag }}"
|
||||
sha256: "{{ netcheck_kubectl_digest_checksum|default(None) }}"
|
||||
enabled: "{{ deploy_netchecker|bool }}"
|
||||
etcd:
|
||||
version: "{{etcd_version}}"
|
||||
dest: "etcd/etcd-{{ etcd_version }}-linux-amd64.tar.gz"
|
||||
@@ -213,31 +203,6 @@ downloads:
|
||||
repo: "{{ exechealthz_image_repo }}"
|
||||
tag: "{{ exechealthz_image_tag }}"
|
||||
sha256: "{{ exechealthz_digest_checksum|default(None) }}"
|
||||
elasticsearch:
|
||||
container: true
|
||||
repo: "{{ elasticsearch_image_repo }}"
|
||||
tag: "{{ elasticsearch_image_tag }}"
|
||||
sha256: "{{ elasticsearch_digest_checksum|default(None) }}"
|
||||
fluentd:
|
||||
container: true
|
||||
repo: "{{ fluentd_image_repo }}"
|
||||
tag: "{{ fluentd_image_tag }}"
|
||||
sha256: "{{ fluentd_digest_checksum|default(None) }}"
|
||||
kibana:
|
||||
container: true
|
||||
repo: "{{ kibana_image_repo }}"
|
||||
tag: "{{ kibana_image_tag }}"
|
||||
sha256: "{{ kibana_digest_checksum|default(None) }}"
|
||||
helm:
|
||||
container: true
|
||||
repo: "{{ helm_image_repo }}"
|
||||
tag: "{{ helm_image_tag }}"
|
||||
sha256: "{{ helm_digest_checksum|default(None) }}"
|
||||
tiller:
|
||||
container: true
|
||||
repo: "{{ tiller_image_repo }}"
|
||||
tag: "{{ tiller_image_tag }}"
|
||||
sha256: "{{ tiller_digest_checksum|default(None) }}"
|
||||
|
||||
download:
|
||||
container: "{{ file.container|default('false') }}"
|
||||
|
||||
@@ -5,10 +5,7 @@
|
||||
when: "{{ download.enabled|bool and not download.container|bool }}"
|
||||
|
||||
- name: Create dest directories
|
||||
file:
|
||||
path: "{{local_release_dir}}/{{download.dest|dirname}}"
|
||||
state: directory
|
||||
recurse: yes
|
||||
file: path={{local_release_dir}}/{{download.dest|dirname}} state=directory recurse=yes
|
||||
when: "{{ download.enabled|bool and not download.container|bool }}"
|
||||
tags: bootstrap-os
|
||||
|
||||
@@ -47,12 +44,7 @@
|
||||
tags: facts
|
||||
|
||||
- name: Create dest directory for saved/loaded container images
|
||||
file:
|
||||
path: "{{local_release_dir}}/containers"
|
||||
state: directory
|
||||
recurse: yes
|
||||
mode: 0755
|
||||
owner: "{{ansible_ssh_user|default(ansible_user_id)}}"
|
||||
file: path="{{local_release_dir}}/containers" state=directory recurse=yes mode=0755 owner={{ansible_ssh_user|default(ansible_user_id)}}
|
||||
when: "{{ download.enabled|bool and download.container|bool }}"
|
||||
tags: bootstrap-os
|
||||
|
||||
@@ -66,10 +58,7 @@
|
||||
tags: localhost
|
||||
|
||||
- name: Download | create local directory for saved/loaded container images
|
||||
file:
|
||||
path: "{{local_release_dir}}/containers"
|
||||
state: directory
|
||||
recurse: yes
|
||||
file: path="{{local_release_dir}}/containers" state=directory recurse=yes
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
run_once: true
|
||||
@@ -92,7 +81,7 @@
|
||||
- name: Download containers if pull is required or told to always pull
|
||||
command: "{{ docker_bin_dir }}/docker pull {{ pull_args }}"
|
||||
register: pull_task_result
|
||||
until: pull_task_result|succeeded
|
||||
until: pull_task_result|success
|
||||
retries: 4
|
||||
delay: "{{ retry_stagger | random + 3 }}"
|
||||
when: "{{ download.enabled|bool and download.container|bool and pull_required|bool|default(download_always_pull) }}"
|
||||
@@ -105,7 +94,7 @@
|
||||
|
||||
- name: "Set default value for 'container_changed' to false"
|
||||
set_fact:
|
||||
container_changed: "{{pull_required|default(false)|bool}}"
|
||||
container_changed: "{{pull_required|bool|default(false)}}"
|
||||
|
||||
- name: "Update the 'container_changed' fact"
|
||||
set_fact:
|
||||
@@ -116,8 +105,7 @@
|
||||
tags: facts
|
||||
|
||||
- name: Stat saved container image
|
||||
stat:
|
||||
path: "{{fname}}"
|
||||
stat: path="{{fname}}"
|
||||
register: img
|
||||
changed_when: false
|
||||
when: "{{ download.enabled|bool and download.container|bool and download_run_once|bool }}"
|
||||
@@ -150,7 +138,7 @@
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
register: get_task
|
||||
until: get_task|succeeded
|
||||
until: get_task|success
|
||||
retries: 4
|
||||
delay: "{{ retry_stagger | random + 3 }}"
|
||||
when: (not ansible_os_family in ["CoreOS", "Container Linux by CoreOS"] and inventory_hostname != groups['kube-master'][0] or download_delegate == "localhost") and download_run_once|bool and download.enabled|bool and download.container|bool
|
||||
|
||||
@@ -10,16 +10,11 @@
|
||||
- name: Register docker images info
|
||||
raw: >-
|
||||
{{ docker_bin_dir }}/docker images -q | xargs {{ docker_bin_dir }}/docker inspect -f "{{ '{{' }} .RepoTags {{ '}}' }},{{ '{{' }} .RepoDigests {{ '}}' }}"
|
||||
no_log: true
|
||||
register: docker_images_raw
|
||||
failed_when: false
|
||||
changed_when: false
|
||||
check_mode: no
|
||||
when: not download_always_pull|bool
|
||||
|
||||
- set_fact:
|
||||
docker_images: "{{docker_images_raw.stdout|regex_replace('\\[|\\]|\\n]','')|regex_replace('\\s',',')}}"
|
||||
no_log: true
|
||||
- set_fact: docker_images="{{docker_images_raw.stdout|regex_replace('\[|\]|\\n]','')|regex_replace('\s',',')}}"
|
||||
when: not download_always_pull|bool
|
||||
|
||||
- set_fact:
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
---
|
||||
# Set to false to only do certificate management
|
||||
etcd_cluster_setup: true
|
||||
|
||||
etcd_bin_dir: "{{ local_release_dir }}/etcd/etcd-{{ etcd_version }}-linux-amd64/"
|
||||
etcd_data_dir: "/var/lib/etcd"
|
||||
|
||||
etcd_config_dir: /etc/ssl/etcd
|
||||
etcd_cert_dir: "{{ etcd_config_dir }}/ssl"
|
||||
@@ -11,13 +7,6 @@ etcd_cert_group: root
|
||||
|
||||
etcd_script_dir: "{{ bin_dir }}/etcd-scripts"
|
||||
|
||||
etcd_heartbeat_interval: "250"
|
||||
etcd_election_timeout: "5000"
|
||||
|
||||
# Limits
|
||||
etcd_memory_limit: 512M
|
||||
|
||||
# Uncomment to set CPU share for etcd
|
||||
#etcd_cpu_limit: 300m
|
||||
|
||||
etcd_node_cert_hosts: "{{ groups['k8s-cluster'] | union(groups.get('calico-rr', [])) }}"
|
||||
etcd_cpu_limit: 300m
|
||||
|
||||
@@ -75,12 +75,12 @@ if [ -n "$MASTERS" ]; then
|
||||
# Member key
|
||||
openssl genrsa -out member-${host}-key.pem 2048 > /dev/null 2>&1
|
||||
openssl req -new -key member-${host}-key.pem -out member-${host}.csr -subj "/CN=etcd-member-${cn}" -config ${CONFIG} > /dev/null 2>&1
|
||||
openssl x509 -req -in member-${host}.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out member-${host}.pem -days 3650 -extensions ssl_client -extfile ${CONFIG} > /dev/null 2>&1
|
||||
openssl x509 -req -in member-${host}.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out member-${host}.pem -days 365 -extensions ssl_client -extfile ${CONFIG} > /dev/null 2>&1
|
||||
|
||||
# Admin key
|
||||
openssl genrsa -out admin-${host}-key.pem 2048 > /dev/null 2>&1
|
||||
openssl req -new -key admin-${host}-key.pem -out admin-${host}.csr -subj "/CN=etcd-admin-${cn}" > /dev/null 2>&1
|
||||
openssl x509 -req -in admin-${host}.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out admin-${host}.pem -days 3650 -extensions ssl_client -extfile ${CONFIG} > /dev/null 2>&1
|
||||
openssl x509 -req -in admin-${host}.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out admin-${host}.pem -days 365 -extensions ssl_client -extfile ${CONFIG} > /dev/null 2>&1
|
||||
done
|
||||
fi
|
||||
|
||||
@@ -90,7 +90,7 @@ if [ -n "$HOSTS" ]; then
|
||||
cn="${host%%.*}"
|
||||
openssl genrsa -out node-${host}-key.pem 2048 > /dev/null 2>&1
|
||||
openssl req -new -key node-${host}-key.pem -out node-${host}.csr -subj "/CN=etcd-node-${cn}" > /dev/null 2>&1
|
||||
openssl x509 -req -in node-${host}.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out node-${host}.pem -days 3650 -extensions ssl_client -extfile ${CONFIG} > /dev/null 2>&1
|
||||
openssl x509 -req -in node-${host}.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out node-${host}.pem -days 365 -extensions ssl_client -extfile ${CONFIG} > /dev/null 2>&1
|
||||
done
|
||||
fi
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
- name: Backup etcd data
|
||||
command: /bin/true
|
||||
notify:
|
||||
- Refresh Time Fact
|
||||
- Set etcd Backup Directory Prefix
|
||||
- Set Backup Directory
|
||||
- Create Backup Directory
|
||||
- Backup etcd v2 data
|
||||
- Backup etcd v3 data
|
||||
when: etcd_cluster_is_healthy.rc == 0
|
||||
|
||||
- name: Refresh Time Fact
|
||||
setup: filter=ansible_date_time
|
||||
|
||||
- name: Set etcd Backup Directory Prefix
|
||||
set_fact:
|
||||
etcd_backup_prefix: '/var/backups'
|
||||
|
||||
- name: Set Backup Directory
|
||||
set_fact:
|
||||
etcd_backup_directory: "{{ etcd_backup_prefix }}/etcd-{{ ansible_date_time.date }}_{{ ansible_date_time.time }}"
|
||||
|
||||
- name: Create Backup Directory
|
||||
file:
|
||||
path: "{{ etcd_backup_directory }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0600
|
||||
|
||||
- name: Backup etcd v2 data
|
||||
command: >-
|
||||
{{ bin_dir }}/etcdctl backup
|
||||
--data-dir {{ etcd_data_dir }}
|
||||
--backup-dir {{ etcd_backup_directory }}
|
||||
environment:
|
||||
ETCDCTL_API: 2
|
||||
retries: 3
|
||||
delay: "{{ retry_stagger | random + 3 }}"
|
||||
|
||||
- name: Backup etcd v3 data
|
||||
command: >-
|
||||
{{ bin_dir }}/etcdctl
|
||||
--endpoints={{ etcd_access_addresses }}
|
||||
snapshot save {{ etcd_backup_directory }}/snapshot.db
|
||||
environment:
|
||||
ETCDCTL_API: 3
|
||||
retries: 3
|
||||
delay: "{{ retry_stagger | random + 3 }}"
|
||||
|
||||
@@ -2,13 +2,10 @@
|
||||
- name: restart etcd
|
||||
command: /bin/true
|
||||
notify:
|
||||
- Backup etcd data
|
||||
- etcd | reload systemd
|
||||
- reload etcd
|
||||
- wait for etcd up
|
||||
|
||||
- include: backup.yml
|
||||
|
||||
- name: etcd | reload systemd
|
||||
command: systemctl daemon-reload
|
||||
|
||||
@@ -19,9 +16,7 @@
|
||||
when: is_etcd_master
|
||||
|
||||
- name: wait for etcd up
|
||||
uri:
|
||||
url: "https://{% if is_etcd_master %}{{ etcd_address }}{% else %}127.0.0.1{% endif %}:2379/health"
|
||||
validate_certs: no
|
||||
uri: url="https://{% if is_etcd_master %}{{ etcd_address }}{% else %}127.0.0.1{% endif %}:2379/health" validate_certs=no
|
||||
register: result
|
||||
until: result.status is defined and result.status == 200
|
||||
retries: 10
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user