Compare commits
478 Commits
Author | SHA1 | Date | |
---|---|---|---|
51d9e2f9b1 | |||
941aaf93fd | |||
68b3ee8ac1 | |||
55da185dfe | |||
f33aafefa2 | |||
8f2ad2e2f7 | |||
980ac28d60 | |||
fde234fda7 | |||
de26988e05 | |||
173314d9f1 | |||
e181530333 | |||
366fb084ef | |||
34e883e6e2 | |||
22236bfab7 | |||
24d28de979 | |||
86365d61e3 | |||
370a0635fa | |||
db2ca014cb | |||
f0f8379e1b | |||
815eebf1d7 | |||
95cf18ff00 | |||
696fcaf391 | |||
6ff5ccc938 | |||
f8a18fcaca | |||
961c1be53e | |||
eda1dcb7f6 | |||
5e0140d62c | |||
717fe3cf3a | |||
32d80ca438 | |||
2a9aead50e | |||
9fda84b1c9 | |||
42702dc1a3 | |||
40e35b3fa6 | |||
b15d41a96a | |||
7da2083986 | |||
37df9a10ff | |||
0f845fb350 | |||
23b8998701 | |||
401d441c10 | |||
f7aea8ed89 | |||
a9b67d586b | |||
b1fbead531 | |||
b06826e88a | |||
57fef8f75e | |||
f599a4a859 | |||
e44b0727d5 | |||
18cee65c4b | |||
f779cb93d6 | |||
aec5080a47 | |||
80418a44d5 | |||
257c20f39e | |||
050de3ab7b | |||
f1498d4b53 | |||
18d19d9ed4 | |||
61d7d1459a | |||
6924c6e5a3 | |||
85c851f519 | |||
5cd7d1a3c9 | |||
8b67159239 | |||
4f70da2731 | |||
db5040e6ea | |||
97764921ed | |||
a6853cb79d | |||
8c15db53b2 | |||
0200138a5d | |||
14af98ebdc | |||
8a5434419b | |||
8a406be48a | |||
feac802456 | |||
076f254a67 | |||
bc3a8a0039 | |||
45d151a69d | |||
bd014c409b | |||
08421aad3d | |||
1c25ed669c | |||
a005d19f6f | |||
471589f1f4 | |||
b0ee1f6cc6 | |||
79128dcd6b | |||
dd7e1469e9 | |||
186ec13579 | |||
2c4e6b65d7 | |||
108a6297e9 | |||
94d4ce5a6f | |||
81da231b1e | |||
1a87dcd9b9 | |||
a1fff30bd9 | |||
81d57fe658 | |||
3118437e10 | |||
65e461a7c0 | |||
c672681ce5 | |||
d332a254ee | |||
f3c072f6b6 | |||
3debb8aab5 | |||
aada6e7e40 | |||
ac60786c6f | |||
db33dc6938 | |||
9dfb25cafd | |||
df8d2285b6 | |||
af6456d1ea | |||
6f57f7dd2f | |||
fd2ff675c3 | |||
bec23c8a41 | |||
faaff8bd72 | |||
8031c6c1e7 | |||
9d8fc8caad | |||
d1b1add176 | |||
a51b729817 | |||
19bc79b1a6 | |||
d2fa3c7796 | |||
03cac2109c | |||
932935ecc7 | |||
e01118d36d | |||
dea9304968 | |||
2864e13ff9 | |||
a8c5a0afdc | |||
0ba336b04e | |||
89f1223f64 | |||
8bc0710073 | |||
fb591bf232 | |||
a43e0d3f95 | |||
f16cc1f08d | |||
8712bddcbe | |||
99dbc6d780 | |||
75e4cc2fd9 | |||
81cb302399 | |||
3bcdf46937 | |||
1cf6a99df4 | |||
a5d165dc85 | |||
f18e77f1db | |||
2fc02ed456 | |||
9db61c45ed | |||
8cb54cd74d | |||
a3f1ce25f8 | |||
3c7f682e90 | |||
8984096f35 | |||
1ce7831f6d | |||
46f6c09d21 | |||
6fe2248314 | |||
cb4f797d32 | |||
eb40ac163f | |||
27ec548b88 | |||
637f09f140 | |||
9b0f57a0a6 | |||
5f02068f90 | |||
7f74906d33 | |||
56523812d3 | |||
602b2d198a | |||
4d95bb1421 | |||
184ac6a4e6 | |||
10e0fe86fb | |||
7e1645845f | |||
f255ce3f02 | |||
07ecef86e3 | |||
3bc4b4c174 | |||
da089b5fca | |||
d4f094cc11 | |||
494a6512b8 | |||
3732c3a9b1 | |||
f6a63d88a7 | |||
86cc703c75 | |||
4dba34bd02 | |||
b0437516c1 | |||
da015e0249 | |||
554857da97 | |||
9bf23fa43b | |||
42287066d3 | |||
a1ff1de975 | |||
1bfbc5bbc4 | |||
c5b4d3ceaa | |||
8fc9c5d025 | |||
42bba66c02 | |||
53bc80bb59 | |||
771ce96e6d | |||
fc456ff0cd | |||
b4f70db878 | |||
5707f79b33 | |||
0a2f4edfc6 | |||
56fa46716e | |||
b74abe56fd | |||
62aecd1e4a | |||
973afef96e | |||
a235605d2c | |||
023108a733 | |||
75d1be8272 | |||
a44235d11b | |||
7abf6a6958 | |||
0d0b1fdf82 | |||
b710c72f04 | |||
678c316d01 | |||
bc6de32faf | |||
7cf8ad4dc7 | |||
02ec72fa40 | |||
d22634a597 | |||
4132cee687 | |||
f3df0d5f4a | |||
1d285e654d | |||
dc6ad64ec7 | |||
92bfcf0467 | |||
54b1fe83f3 | |||
5337cff179 | |||
1be788f785 | |||
8afbf339f7 | |||
8c935dfb50 | |||
66c5ed8406 | |||
4087e97505 | |||
da50ed0936 | |||
fbbfff3795 | |||
fb9103acd3 | |||
49d921cf91 | |||
fe29c97ae8 | |||
2abb6c8689 | |||
a3ca441998 | |||
9cf503acb1 | |||
1cbdd7ed5c | |||
428e52e0d1 | |||
70dc222719 | |||
69f796f0c7 | |||
5826f0810c | |||
de9443a694 | |||
99c5f7e013 | |||
d9dedc2cd5 | |||
23ae6027ab | |||
781b5691c9 | |||
fd9bbcb157 | |||
e0410661fa | |||
8ef754678a | |||
161a8f55fa | |||
7481cc31e1 | |||
b15b6e834f | |||
76640cf1a1 | |||
374ea7b81d | |||
46bef931e9 | |||
a36e9ae690 | |||
728155a2a1 | |||
cdf9a9f4fc | |||
29307740dd | |||
a038d62644 | |||
20c7e31ea3 | |||
65065e7fdf | |||
352297cf8d | |||
a67a50f9c0 | |||
324bc41097 | |||
c81b443d93 | |||
dc16ab92f4 | |||
53032a6695 | |||
d90a5f291b | |||
3b7791501e | |||
f2b8a3614d | |||
e89b47c7ee | |||
2aa66eb12d | |||
4c8b93e5b9 | |||
216631bf02 | |||
c7f3123e28 | |||
f599c2a691 | |||
bc7d1f36ea | |||
80fa294a31 | |||
465dfd68bc | |||
73f45fbe94 | |||
d270678bda | |||
de028814e5 | |||
b5406b752d | |||
6025981ceb | |||
4348e78b24 | |||
e2f9adc2ff | |||
f67a24499b | |||
5c704552d8 | |||
d83ea51101 | |||
fa6027e8f0 | |||
2849191e67 | |||
0559eec681 | |||
a3a7fe7c8e | |||
9b2d176617 | |||
7a3547e4d1 | |||
e6fb686156 | |||
5e80603bbb | |||
c8d95a1586 | |||
27a99e0a3f | |||
3cc351dff9 | |||
23c9071c30 | |||
14141ec137 | |||
5bec2edaf7 | |||
f504d0ea99 | |||
3b7797b1a1 | |||
aa63eb6196 | |||
23aa3e4638 | |||
56ae3bfec2 | |||
4d5c4a13cb | |||
69a8f91512 | |||
fa791cc344 | |||
456f743470 | |||
ab6f0012cc | |||
4afbf51d32 | |||
d62684b617 | |||
a8dfcbbfc7 | |||
bbdc6210f5 | |||
c7f6ed1495 | |||
818aa7aeb1 | |||
045acc724b | |||
d540560619 | |||
797bfd85b0 | |||
07cb8ebef7 | |||
54416cabfd | |||
3617ae31f6 | |||
4f05d801c3 | |||
956afcb33f | |||
6347419233 | |||
0c7a50fe1e | |||
7423932510 | |||
b41530ba5d | |||
29e916508c | |||
b45f3f0004 | |||
2a5721b4d4 | |||
e30a703c8e | |||
333f1a4a40 | |||
84b278021a | |||
1e470b0473 | |||
0ef3a7914c | |||
a3fff1e438 | |||
4bc204925a | |||
5d9946184a | |||
5ba169a612 | |||
872b37f751 | |||
8485136f9a | |||
ff1bc739f1 | |||
594a0e7f1b | |||
8e28ba38d2 | |||
73c2ff17dd | |||
13f225e6ae | |||
3f62492a15 | |||
5e3bd2dff1 | |||
787a9c74fa | |||
14749df6f3 | |||
2db2898112 | |||
3776000fc4 | |||
f0572e59e7 | |||
6217184c7f | |||
044dcbaed0 | |||
8a5eae94ea | |||
bf3c6aeed1 | |||
f3fbf995ca | |||
03bded2b6b | |||
d5c0829d61 | |||
00369303de | |||
1f1479c0a7 | |||
e67f848abc | |||
560f50d3cd | |||
3f45122d0d | |||
50bdaa573c | |||
24b6698cc9 | |||
73885d3b9e | |||
f29387316f | |||
d6fd0d2aca | |||
e814da1eec | |||
e029a09345 | |||
dcd9c9509b | |||
15eb7db36d | |||
a5b46bfc8c | |||
fbba259933 | |||
7b77e2d232 | |||
48a182844c | |||
9335cdcebc | |||
38af93b60c | |||
741de6051c | |||
b8f0de3074 | |||
88d919337e | |||
f518b90c6b | |||
d5c33e6d6c | |||
338eb4ce65 | |||
009e208bcd | |||
81e6877b02 | |||
3722acee85 | |||
a4a35f8a4f | |||
82119ca923 | |||
6ca2019002 | |||
53e3463b5a | |||
c9ed5f69d7 | |||
696d481e3b | |||
f5a83ceded | |||
3fe66a1298 | |||
6af1f65d3c | |||
4a10dca7d4 | |||
4d57ed314d | |||
86d0e12695 | |||
4e81bcc147 | |||
691baf5b14 | |||
6243467856 | |||
3c5a4474ac | |||
01da65252b | |||
f3e7615bef | |||
f47a666227 | |||
b708db4cd5 | |||
a3144e7e21 | |||
683efc5698 | |||
38a3075025 | |||
fc072300ea | |||
d25ecfe1c1 | |||
37d98e79ec | |||
a65605b17a | |||
424e59805f | |||
6df8111cd4 | |||
76db060afb | |||
d588532c9b | |||
d6d7458d68 | |||
228b244c84 | |||
d89ecb8308 | |||
50751bb610 | |||
64f48bf84c | |||
f8fdc0cd93 | |||
09fe95bc60 | |||
ada5941a70 | |||
88fe3403ce | |||
04f2682ac6 | |||
873b5608cf | |||
12086744e0 | |||
33ab615072 | |||
f696d7abee | |||
5a1cf19278 | |||
416e65509b | |||
4de6a78e26 | |||
026088deea | |||
f142e671b3 | |||
2f49b6caa8 | |||
50c86919dc | |||
781cc00cc4 | |||
05dc2b3a09 | |||
d0e628911c | |||
656633f784 | |||
530e1c329d | |||
f5aec8add4 | |||
f92309bfd0 | |||
ef10feb26f | |||
c6586829de | |||
b103385678 | |||
848191e97a | |||
04e3fb6a5a | |||
b218e17f44 | |||
bba6d0c613 | |||
49af1f9969 | |||
a6dc50e7cb | |||
f69b5f7f33 | |||
37eac010c8 | |||
d4b9f15c0a | |||
ec3daedf9e | |||
1cf76a10db | |||
d83181a2be | |||
b834a28891 | |||
78f6f6b889 | |||
0b02f6593b | |||
7f1d9ff543 | |||
c5fb734098 | |||
d5d3cfd3fa | |||
cc77a8c395 | |||
d39c273d96 | |||
316508626d | |||
46ba6a4154 | |||
d8cbbc414e | |||
ebae491e3f | |||
6f919e5020 | |||
4ff851b302 | |||
3af90f8772 | |||
cb54d074b5 | |||
9032e271f1 | |||
15597aa493 | |||
3b9d13fda9 | |||
5e0249ae7c | |||
27958e4247 | |||
353afa7cb0 | |||
e865c50574 | |||
a30ad1e5a5 | |||
586ad89d50 | |||
6caa639243 | |||
80f31818df | |||
854cc53fa5 | |||
d2a1ac3b0c | |||
a678d1be9d | |||
097806dfe8 | |||
7cdf1fd388 |
27
.ansible-lint
Normal file
27
.ansible-lint
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
parseable: true
|
||||
skip_list:
|
||||
# see https://docs.ansible.com/ansible-lint/rules/default_rules.html for a list of all default rules
|
||||
# The following rules throw errors.
|
||||
# These either still need to be corrected in the repository and the rules re-enabled or documented why they are skipped on purpose.
|
||||
- '301'
|
||||
- '302'
|
||||
- '303'
|
||||
- '305'
|
||||
- '306'
|
||||
- '404'
|
||||
- '503'
|
||||
|
||||
# These rules are intentionally skipped:
|
||||
#
|
||||
# [E204]: "Lines should be no longer than 160 chars"
|
||||
# This could be re-enabled with a major rewrite in the future.
|
||||
# For now, there's not enough value gain from strictly limiting line length.
|
||||
# (Disabled in May 2019)
|
||||
- '204'
|
||||
|
||||
# [E701]: "meta/main.yml should contain relevant info"
|
||||
# Roles in Kubespray are not intended to be used/imported by Ansible Galaxy.
|
||||
# While it can be useful to have these metadata available, they are also available in the existing documentation.
|
||||
# (Disabled in May 2019)
|
||||
- '701'
|
@ -1,16 +1,11 @@
|
||||
<!-- Thanks for filing an issue! Before hitting the button, please answer these questions.-->
|
||||
|
||||
**Is this a BUG REPORT or FEATURE REQUEST?** (choose one):
|
||||
---
|
||||
name: Bug Report
|
||||
about: Report a bug encountered while operating Kubernetes
|
||||
labels: kind/bug
|
||||
|
||||
---
|
||||
<!--
|
||||
If this is a BUG REPORT, please:
|
||||
- Fill in as much of the template below as you can. If you leave out
|
||||
information, we can't help you as well.
|
||||
|
||||
If this is a FEATURE REQUEST, please:
|
||||
- Describe *in detail* the feature/behavior/change you'd like to see.
|
||||
|
||||
In both cases, be ready for followup questions, and please respond in a timely
|
||||
Please, be ready for followup questions, and please respond in a timely
|
||||
manner. If we can't reproduce a bug or think a feature already exists, we
|
||||
might close your issue. If we're wrong, PLEASE feel free to reopen it and
|
||||
explain why.
|
11
.github/ISSUE_TEMPLATE/enhancement.md
vendored
Normal file
11
.github/ISSUE_TEMPLATE/enhancement.md
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
---
|
||||
name: Enhancement Request
|
||||
about: Suggest an enhancement to the Kubespray project
|
||||
labels: kind/feature
|
||||
|
||||
---
|
||||
<!-- Please only use this template for submitting enhancement requests -->
|
||||
|
||||
**What would you like to be added**:
|
||||
|
||||
**Why is this needed**:
|
20
.github/ISSUE_TEMPLATE/failing-test.md
vendored
Normal file
20
.github/ISSUE_TEMPLATE/failing-test.md
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
name: Failing Test
|
||||
about: Report test failures in Kubespray CI jobs
|
||||
labels: kind/failing-test
|
||||
|
||||
---
|
||||
|
||||
<!-- Please only use this template for submitting reports about failing tests in Kubespray CI jobs -->
|
||||
|
||||
**Which jobs are failing**:
|
||||
|
||||
**Which test(s) are failing**:
|
||||
|
||||
**Since when has it been failing**:
|
||||
|
||||
**Testgrid link**:
|
||||
|
||||
**Reason for failure**:
|
||||
|
||||
**Anything else we need to know**:
|
18
.github/ISSUE_TEMPLATE/support.md
vendored
Normal file
18
.github/ISSUE_TEMPLATE/support.md
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
---
|
||||
name: Support Request
|
||||
about: Support request or question relating to Kubespray
|
||||
labels: triage/support
|
||||
|
||||
---
|
||||
|
||||
<!--
|
||||
STOP -- PLEASE READ!
|
||||
|
||||
GitHub is not the right place for support requests.
|
||||
|
||||
If you're looking for help, check [Stack Overflow](https://stackoverflow.com/questions/tagged/kubespray) and the [troubleshooting guide](https://kubernetes.io/docs/tasks/debug-application-cluster/troubleshooting/).
|
||||
|
||||
You can also post your question on the [Kubernetes Slack](http://slack.k8s.io/) or the [Discuss Kubernetes](https://discuss.kubernetes.io/) forum.
|
||||
|
||||
If the matter is security related, please disclose it privately via https://kubernetes.io/security/.
|
||||
-->
|
44
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
44
.github/PULL_REQUEST_TEMPLATE.md
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
<!-- Thanks for sending a pull request! Here are some tips for you:
|
||||
|
||||
1. If this is your first time, please read our contributor guidelines: https://git.k8s.io/community/contributors/guide#your-first-contribution and developer guide https://git.k8s.io/community/contributors/devel/development.md#development-guide
|
||||
2. Please label this pull request according to what type of issue you are addressing, especially if this is a release targeted pull request. For reference on required PR/issue labels, read here:
|
||||
https://git.k8s.io/community/contributors/devel/release.md#issue-kind-label
|
||||
3. Ensure you have added or ran the appropriate tests for your PR: https://git.k8s.io/community/contributors/devel/testing.md
|
||||
4. If you want *faster* PR reviews, read how: https://git.k8s.io/community/contributors/guide/pull-requests.md#best-practices-for-faster-reviews
|
||||
5. Follow the instructions for writing a release note: https://git.k8s.io/community/contributors/guide/release-notes.md
|
||||
6. If the PR is unfinished, see how to mark it: https://git.k8s.io/community/contributors/guide/pull-requests.md#marking-unfinished-pull-requests
|
||||
-->
|
||||
|
||||
**What type of PR is this?**
|
||||
> Uncomment only one ` /kind <>` line, hit enter to put that in a new line, and remove leading whitespaces from that line:
|
||||
>
|
||||
> /kind api-change
|
||||
> /kind bug
|
||||
> /kind cleanup
|
||||
> /kind design
|
||||
> /kind documentation
|
||||
> /kind failing-test
|
||||
> /kind feature
|
||||
> /kind flake
|
||||
|
||||
**What this PR does / why we need it**:
|
||||
|
||||
**Which issue(s) this PR fixes**:
|
||||
<!--
|
||||
*Automatically closes linked issue when PR is merged.
|
||||
Usage: `Fixes #<issue number>`, or `Fixes (paste link of issue)`.
|
||||
_If PR is about `failing-tests or flakes`, please post the related issues/tests in a comment and do not use `Fixes`_*
|
||||
-->
|
||||
Fixes #
|
||||
|
||||
**Special notes for your reviewer**:
|
||||
|
||||
**Does this PR introduce a user-facing change?**:
|
||||
<!--
|
||||
If no, just write "NONE" in the release-note block below.
|
||||
If yes, a release note is required:
|
||||
Enter your extended release note in the block below. If the PR requires additional action from users switching to the new release, include the string "action required".
|
||||
-->
|
||||
```release-note
|
||||
|
||||
```
|
789
.gitlab-ci.yml
789
.gitlab-ci.yml
@ -1,9 +1,10 @@
|
||||
---
|
||||
stages:
|
||||
- unit-tests
|
||||
- moderator
|
||||
- deploy-part1
|
||||
- moderator
|
||||
- deploy-part2
|
||||
- deploy-gce
|
||||
- deploy-special
|
||||
|
||||
variables:
|
||||
@ -27,785 +28,45 @@ variables:
|
||||
UPGRADE_TEST: "false"
|
||||
LOG_LEVEL: "-vv"
|
||||
|
||||
# asia-east1-a
|
||||
# asia-northeast1-a
|
||||
# europe-west1-b
|
||||
# us-central1-a
|
||||
# us-east1-b
|
||||
# us-west1-a
|
||||
|
||||
before_script:
|
||||
- /usr/bin/python -m pip install -r tests/requirements.txt
|
||||
- ./tests/scripts/rebase.sh
|
||||
- update-alternatives --install /usr/bin/python python /usr/bin/python3 1
|
||||
- python -m pip install -r tests/requirements.txt
|
||||
- mkdir -p /.ssh
|
||||
|
||||
.job: &job
|
||||
tags:
|
||||
- kubernetes
|
||||
- docker
|
||||
image: quay.io/kubespray/kubespray:v2.8
|
||||
|
||||
.docker_service: &docker_service
|
||||
services:
|
||||
- docker:dind
|
||||
|
||||
.create_cluster: &create_cluster
|
||||
<<: *job
|
||||
<<: *docker_service
|
||||
|
||||
.gce_variables: &gce_variables
|
||||
GCE_USER: travis
|
||||
SSH_USER: $GCE_USER
|
||||
CLOUD_MACHINE_TYPE: "g1-small"
|
||||
CI_PLATFORM: "gce"
|
||||
PRIVATE_KEY: $GCE_PRIVATE_KEY
|
||||
|
||||
.do_variables: &do_variables
|
||||
PRIVATE_KEY: $DO_PRIVATE_KEY
|
||||
CI_PLATFORM: "do"
|
||||
SSH_USER: root
|
||||
|
||||
- packet
|
||||
variables:
|
||||
KUBESPRAY_VERSION: v2.11.2
|
||||
image: quay.io/kubespray/kubespray:$KUBESPRAY_VERSION
|
||||
|
||||
.testcases: &testcases
|
||||
<<: *job
|
||||
<<: *docker_service
|
||||
cache:
|
||||
key: "$CI_BUILD_REF_NAME"
|
||||
paths:
|
||||
- downloads/
|
||||
- $HOME/.cache
|
||||
services:
|
||||
- docker:dind
|
||||
before_script:
|
||||
- docker info
|
||||
- /usr/bin/python -m pip install -r requirements.txt
|
||||
- /usr/bin/python -m pip install -r tests/requirements.txt
|
||||
- mkdir -p /.ssh
|
||||
- mkdir -p $HOME/.ssh
|
||||
- ansible-playbook --version
|
||||
- export PYPATH=$([[ ! "$CI_JOB_NAME" =~ "coreos" ]] && echo /usr/bin/python || echo /opt/bin/python)
|
||||
- echo "CI_JOB_NAME is $CI_JOB_NAME"
|
||||
- echo "PYPATH is $PYPATH"
|
||||
- update-alternatives --install /usr/bin/python python /usr/bin/python3 1
|
||||
- ./tests/scripts/rebase.sh
|
||||
- ./tests/scripts/testcases_prepare.sh
|
||||
script:
|
||||
- pwd
|
||||
- ls
|
||||
- echo ${PWD}
|
||||
- echo "${STARTUP_SCRIPT}"
|
||||
- cd tests && make create-${CI_PLATFORM} -s ; cd -
|
||||
|
||||
# Check out latest tag if testing upgrade
|
||||
- test "${UPGRADE_TEST}" != "false" && git fetch --all && git checkout $(git describe --tags $(git rev-list --tags --max-count=1))
|
||||
# Checkout the CI vars file so it is available
|
||||
- test "${UPGRADE_TEST}" != "false" && git checkout "${CI_BUILD_REF}" tests/files/${CI_JOB_NAME}.yml
|
||||
# Workaround https://github.com/kubernetes-sigs/kubespray/issues/2021
|
||||
- 'sh -c "echo ignore_assert_errors: true | tee -a tests/files/${CI_JOB_NAME}.yml"'
|
||||
|
||||
|
||||
# Create cluster
|
||||
- >
|
||||
ansible-playbook
|
||||
-i ${ANSIBLE_INVENTORY}
|
||||
-b --become-user=root
|
||||
--private-key=${HOME}/.ssh/id_rsa
|
||||
-u $SSH_USER
|
||||
${SSH_ARGS}
|
||||
${LOG_LEVEL}
|
||||
-e @${CI_TEST_VARS}
|
||||
-e ansible_ssh_user=${SSH_USER}
|
||||
-e local_release_dir=${PWD}/downloads
|
||||
--limit "all:!fake_hosts"
|
||||
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";
|
||||
git checkout "${CI_BUILD_REF}";
|
||||
ansible-playbook
|
||||
-i ${ANSIBLE_INVENTORY}
|
||||
-b --become-user=root
|
||||
--private-key=${HOME}/.ssh/id_rsa
|
||||
-u $SSH_USER
|
||||
${SSH_ARGS}
|
||||
${LOG_LEVEL}
|
||||
-e @${CI_TEST_VARS}
|
||||
-e ansible_ssh_user=${SSH_USER}
|
||||
-e local_release_dir=${PWD}/downloads
|
||||
--limit "all:!fake_hosts"
|
||||
$PLAYBOOK;
|
||||
fi
|
||||
|
||||
# Tests Cases
|
||||
## Test Master API
|
||||
- ansible-playbook -i ${ANSIBLE_INVENTORY} -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
|
||||
|
||||
## Ping the between 2 pod
|
||||
- ansible-playbook -i ${ANSIBLE_INVENTORY} -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
|
||||
|
||||
## Advanced DNS checks
|
||||
- ansible-playbook -i ${ANSIBLE_INVENTORY} -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
|
||||
|
||||
## Idempotency checks 1/5 (repeat deployment)
|
||||
- >
|
||||
if [ "${IDEMPOT_CHECK}" = "true" ]; then
|
||||
ansible-playbook
|
||||
-i ${ANSIBLE_INVENTORY}
|
||||
-b --become-user=root
|
||||
--private-key=${HOME}/.ssh/id_rsa
|
||||
-u $SSH_USER
|
||||
${SSH_ARGS}
|
||||
${LOG_LEVEL}
|
||||
-e @${CI_TEST_VARS}
|
||||
-e ansible_python_interpreter=${PYPATH}
|
||||
-e local_release_dir=${PWD}/downloads
|
||||
--limit "all:!fake_hosts"
|
||||
cluster.yml;
|
||||
fi
|
||||
|
||||
## Idempotency checks 2/5 (Advanced DNS checks)
|
||||
- >
|
||||
if [ "${IDEMPOT_CHECK}" = "true" ]; then
|
||||
ansible-playbook
|
||||
-i ${ANSIBLE_INVENTORY}
|
||||
-b --become-user=root
|
||||
--private-key=${HOME}/.ssh/id_rsa
|
||||
-u $SSH_USER
|
||||
${SSH_ARGS}
|
||||
${LOG_LEVEL}
|
||||
-e @${CI_TEST_VARS}
|
||||
--limit "all:!fake_hosts"
|
||||
tests/testcases/040_check-network-adv.yml $LOG_LEVEL;
|
||||
fi
|
||||
|
||||
## Idempotency checks 3/5 (reset deployment)
|
||||
- >
|
||||
if [ "${IDEMPOT_CHECK}" = "true" -a "${RESET_CHECK}" = "true" ]; then
|
||||
ansible-playbook
|
||||
-i ${ANSIBLE_INVENTORY}
|
||||
-b --become-user=root
|
||||
--private-key=${HOME}/.ssh/id_rsa
|
||||
-u $SSH_USER
|
||||
${SSH_ARGS}
|
||||
${LOG_LEVEL}
|
||||
-e @${CI_TEST_VARS}
|
||||
-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" -a "${RESET_CHECK}" = "true" ]; then
|
||||
ansible-playbook
|
||||
-i ${ANSIBLE_INVENTORY}
|
||||
-b --become-user=root
|
||||
--private-key=${HOME}/.ssh/id_rsa
|
||||
-u $SSH_USER
|
||||
${SSH_ARGS}
|
||||
${LOG_LEVEL}
|
||||
-e @${CI_TEST_VARS}
|
||||
-e ansible_python_interpreter=${PYPATH}
|
||||
-e local_release_dir=${PWD}/downloads
|
||||
--limit "all:!fake_hosts"
|
||||
cluster.yml;
|
||||
fi
|
||||
|
||||
## Idempotency checks 5/5 (Advanced DNS checks)
|
||||
- >
|
||||
if [ "${IDEMPOT_CHECK}" = "true" -a "${RESET_CHECK}" = "true" ]; then
|
||||
ansible-playbook -i ${ANSIBLE_INVENTORY} -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
|
||||
|
||||
- ./tests/scripts/testcases_run.sh
|
||||
after_script:
|
||||
- cd tests && make delete-${CI_PLATFORM} -s ; cd -
|
||||
|
||||
.gce: &gce
|
||||
<<: *testcases
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
|
||||
.do: &do
|
||||
variables:
|
||||
<<: *do_variables
|
||||
<<: *testcases
|
||||
|
||||
# Test matrix. Leave the comments for markup scripts.
|
||||
.coreos_calico_aio_variables: &coreos_calico_aio_variables
|
||||
# stage: deploy-part1
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.ubuntu18_flannel_aio_variables: &ubuntu18_flannel_aio_variables
|
||||
# stage: deploy-part1
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.centos_weave_kubeadm_variables: ¢os_weave_kubeadm_variables
|
||||
# stage: deploy-part1
|
||||
UPGRADE_TEST: "graceful"
|
||||
|
||||
.ubuntu_canal_kubeadm_variables: &ubuntu_canal_kubeadm_variables
|
||||
# stage: deploy-part1
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.ubuntu_canal_ha_variables: &ubuntu_canal_ha_variables
|
||||
# stage: deploy-special
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.ubuntu_contiv_sep_variables: &ubuntu_contiv_sep_variables
|
||||
# stage: deploy-special
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.coreos_cilium_variables: &coreos_cilium_variables
|
||||
# stage: deploy-special
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.ubuntu_cilium_sep_variables: &ubuntu_cilium_sep_variables
|
||||
# stage: deploy-special
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.rhel7_weave_variables: &rhel7_weave_variables
|
||||
# stage: deploy-part1
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.centos7_flannel_addons_variables: ¢os7_flannel_addons_variables
|
||||
# stage: deploy-part2
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.debian9_calico_variables: &debian9_calico_variables
|
||||
# stage: deploy-part2
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.coreos_canal_variables: &coreos_canal_variables
|
||||
# stage: deploy-part2
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.rhel7_canal_sep_variables: &rhel7_canal_sep_variables
|
||||
# stage: deploy-special
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.ubuntu_weave_sep_variables: &ubuntu_weave_sep_variables
|
||||
# stage: deploy-special
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.centos7_calico_ha_variables: ¢os7_calico_ha_variables
|
||||
# stage: deploy-special
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.centos7_kube_router_variables: ¢os7_kube_router_variables
|
||||
# stage: deploy-special
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.centos7_multus_calico_variables: ¢os7_multus_calico_variables
|
||||
# stage: deploy-part2
|
||||
UPGRADE_TEST: "graceful"
|
||||
|
||||
.coreos_alpha_weave_ha_variables: &coreos_alpha_weave_ha_variables
|
||||
# stage: deploy-special
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.coreos_kube_router_variables: &coreos_kube_router_variables
|
||||
# stage: deploy-special
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.ubuntu_rkt_sep_variables: &ubuntu_rkt_sep_variables
|
||||
# stage: deploy-part1
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.ubuntu_flannel_variables: &ubuntu_flannel_variables
|
||||
# stage: deploy-part2
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.ubuntu_kube_router_variables: &ubuntu_kube_router_variables
|
||||
# stage: deploy-special
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
.opensuse_canal_variables: &opensuse_canal_variables
|
||||
# stage: deploy-part2
|
||||
MOVED_TO_GROUP_VARS: "true"
|
||||
|
||||
|
||||
# Builds for PRs only (premoderated by unit-tests step) and triggers (auto)
|
||||
### PR JOBS PART1
|
||||
|
||||
gce_ubuntu18-flannel-aio:
|
||||
stage: deploy-part1
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *ubuntu18_flannel_aio_variables
|
||||
<<: *gce_variables
|
||||
when: on_success
|
||||
except: ['triggers']
|
||||
only: [/^pr-.*$/]
|
||||
|
||||
### PR JOBS PART2
|
||||
|
||||
gce_coreos-calico-aio:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *coreos_calico_aio_variables
|
||||
<<: *gce_variables
|
||||
when: on_success
|
||||
except: ['triggers']
|
||||
only: [/^pr-.*$/]
|
||||
|
||||
gce_centos7-flannel-addons:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *centos7_flannel_addons_variables
|
||||
when: on_success
|
||||
except: ['triggers']
|
||||
only: [/^pr-.*$/]
|
||||
|
||||
### MANUAL JOBS
|
||||
|
||||
gce_centos-weave-kubeadm-sep:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *centos_weave_kubeadm_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
gce_ubuntu-weave-sep:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_weave_sep_variables
|
||||
when: manual
|
||||
only: ['triggers']
|
||||
|
||||
gce_coreos-calico-sep-triggers:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *coreos_calico_aio_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
gce_ubuntu-canal-ha-triggers:
|
||||
stage: deploy-special
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_canal_ha_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
gce_centos7-flannel-addons-triggers:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *centos7_flannel_addons_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
gce_ubuntu-weave-sep-triggers:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_weave_sep_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
# More builds for PRs/merges (manual) and triggers (auto)
|
||||
do_ubuntu-canal-ha:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *do
|
||||
variables:
|
||||
<<: *do_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_ubuntu-canal-ha:
|
||||
stage: deploy-special
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_canal_ha_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_ubuntu-canal-kubeadm:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_canal_kubeadm_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_ubuntu-canal-kubeadm-triggers:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_canal_kubeadm_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
gce_ubuntu-flannel-ha:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_flannel_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
|
||||
gce_centos-weave-kubeadm-triggers:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *centos_weave_kubeadm_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
gce_ubuntu-contiv-sep:
|
||||
stage: deploy-special
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_contiv_sep_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_coreos-cilium:
|
||||
stage: deploy-special
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *coreos_cilium_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_ubuntu-cilium-sep:
|
||||
stage: deploy-special
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_cilium_sep_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_rhel7-weave:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *rhel7_weave_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_rhel7-weave-triggers:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *rhel7_weave_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
gce_debian9-calico-upgrade:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *debian9_calico_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_debian9-calico-triggers:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *debian9_calico_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
gce_coreos-canal:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *coreos_canal_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_coreos-canal-triggers:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *coreos_canal_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
gce_rhel7-canal-sep:
|
||||
stage: deploy-special
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *rhel7_canal_sep_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_rhel7-canal-sep-triggers:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *rhel7_canal_sep_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
gce_centos7-calico-ha:
|
||||
stage: deploy-special
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *centos7_calico_ha_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_centos7-calico-ha-triggers:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *centos7_calico_ha_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
|
||||
gce_centos7-kube-router:
|
||||
stage: deploy-special
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *centos7_kube_router_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_centos7-multus-calico:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *centos7_multus_calico_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_opensuse-canal:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *opensuse_canal_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
# no triggers yet https://github.com/kubernetes-incubator/kargo/issues/613
|
||||
gce_coreos-alpha-weave-ha:
|
||||
stage: deploy-special
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *coreos_alpha_weave_ha_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_coreos-kube-router:
|
||||
stage: deploy-special
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *coreos_kube_router_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_ubuntu-rkt-sep:
|
||||
stage: deploy-part2
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_rkt_sep_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_ubuntu-kube-router-sep:
|
||||
stage: deploy-special
|
||||
<<: *job
|
||||
<<: *gce
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
<<: *ubuntu_kube_router_variables
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
- ./tests/scripts/testcases_cleanup.sh
|
||||
|
||||
# For failfast, at least 1 job must be defined in .gitlab-ci.yml
|
||||
# Premoderated with manual actions
|
||||
ci-authorized:
|
||||
<<: *job
|
||||
extends: .job
|
||||
stage: moderator
|
||||
before_script:
|
||||
- apt-get -y install jq
|
||||
script:
|
||||
- /bin/sh scripts/premoderator.sh
|
||||
except: ['triggers', 'master']
|
||||
# Disable ci moderator
|
||||
only: []
|
||||
|
||||
syntax-check:
|
||||
<<: *job
|
||||
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
|
||||
- ansible-playbook -i inventory/local-tests.cfg -u root -e ansible_ssh_user=root -b --become-user=root extra_playbooks/upgrade-only-k8s.yml -vvv --syntax-check
|
||||
except: ['triggers', 'master']
|
||||
|
||||
yamllint:
|
||||
<<: *job
|
||||
stage: unit-tests
|
||||
script:
|
||||
- yamllint .
|
||||
except: ['triggers', 'master']
|
||||
|
||||
tox-inventory-builder:
|
||||
stage: unit-tests
|
||||
<<: *job
|
||||
script:
|
||||
- pip install tox
|
||||
- cd contrib/inventory_builder && tox
|
||||
when: manual
|
||||
except: ['triggers', 'master']
|
||||
|
||||
|
||||
# Tests for contrib/terraform/
|
||||
.terraform_install: &terraform_install
|
||||
<<: *job
|
||||
before_script:
|
||||
# Set Ansible config
|
||||
- cp ansible.cfg ~/.ansible.cfg
|
||||
# Install Terraform
|
||||
- apt-get install -y unzip
|
||||
- curl https://releases.hashicorp.com/terraform/${TF_VERSION}/terraform_${TF_VERSION}_linux_amd64.zip > /tmp/terraform.zip
|
||||
- unzip /tmp/terraform.zip && mv ./terraform /usr/local/bin/ && terraform --version
|
||||
# Prepare inventory
|
||||
- cp -LRp contrib/terraform/$PROVIDER/sample-inventory inventory/$CLUSTER
|
||||
- cd inventory/$CLUSTER
|
||||
- ln -s ../../contrib/terraform/$PROVIDER/hosts
|
||||
- terraform init ../../contrib/terraform/$PROVIDER
|
||||
# Copy SSH keypair
|
||||
- mkdir -p ~/.ssh
|
||||
- echo "$PACKET_PRIVATE_KEY" | base64 -d > ~/.ssh/id_rsa
|
||||
- chmod 400 ~/.ssh/id_rsa
|
||||
- echo "$PACKET_PUBLIC_KEY" | base64 -d > ~/.ssh/id_rsa.pub
|
||||
- export TF_VAR_public_key_path=""
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
.terraform_validate: &terraform_validate
|
||||
<<: *terraform_install
|
||||
stage: unit-tests
|
||||
script:
|
||||
- terraform validate -var-file=cluster.tf ../../contrib/terraform/$PROVIDER
|
||||
- terraform fmt -check -diff ../../contrib/terraform/$PROVIDER
|
||||
|
||||
.terraform_apply: &terraform_apply
|
||||
<<: *terraform_install
|
||||
stage: deploy-part2
|
||||
when: manual
|
||||
script:
|
||||
- terraform apply -auto-approve ../../contrib/terraform/$PROVIDER
|
||||
- ansible-playbook -i hosts ../../cluster.yml
|
||||
after_script:
|
||||
# Cleanup regardless of exit code
|
||||
- cd inventory/$CLUSTER
|
||||
- terraform destroy -auto-approve ../../contrib/terraform/$PROVIDER
|
||||
|
||||
tf-validate-openstack:
|
||||
<<: *terraform_validate
|
||||
variables:
|
||||
TF_VERSION: 0.11.11
|
||||
PROVIDER: openstack
|
||||
CLUSTER: $CI_COMMIT_REF_NAME
|
||||
|
||||
tf-validate-packet:
|
||||
<<: *terraform_validate
|
||||
variables:
|
||||
TF_VERSION: 0.11.11
|
||||
PROVIDER: packet
|
||||
CLUSTER: $CI_COMMIT_REF_NAME
|
||||
|
||||
tf-apply-packet:
|
||||
<<: *terraform_apply
|
||||
variables:
|
||||
TF_VERSION: 0.11.11
|
||||
PROVIDER: packet
|
||||
CLUSTER: $CI_COMMIT_REF_NAME
|
||||
TF_VAR_cluster_name: $CI_COMMIT_REF_NAME
|
||||
TF_VAR_number_of_k8s_masters: "1"
|
||||
TF_VAR_number_of_k8s_nodes: "1"
|
||||
TF_VAR_plan_k8s_masters: t1.small.x86
|
||||
TF_VAR_plan_k8s_nodes: t1.small.x86
|
||||
TF_VAR_facility: "ewr1"
|
||||
include:
|
||||
- .gitlab-ci/lint.yml
|
||||
- .gitlab-ci/shellcheck.yml
|
||||
- .gitlab-ci/terraform.yml
|
||||
- .gitlab-ci/packet.yml
|
||||
|
247
.gitlab-ci/gce.yml
Normal file
247
.gitlab-ci/gce.yml
Normal file
@ -0,0 +1,247 @@
|
||||
---
|
||||
.gce_variables: &gce_variables
|
||||
GCE_USER: travis
|
||||
SSH_USER: $GCE_USER
|
||||
CLOUD_MACHINE_TYPE: "g1-small"
|
||||
CI_PLATFORM: "gce"
|
||||
PRIVATE_KEY: $GCE_PRIVATE_KEY
|
||||
|
||||
.cache: &cache
|
||||
cache:
|
||||
key: "$CI_BUILD_REF_NAME"
|
||||
paths:
|
||||
- downloads/
|
||||
- $HOME/.cache
|
||||
|
||||
.gce: &gce
|
||||
extends: .testcases
|
||||
<<: *cache
|
||||
variables:
|
||||
<<: *gce_variables
|
||||
tags:
|
||||
- gce
|
||||
except: ['triggers']
|
||||
only: [/^pr-.*$/]
|
||||
|
||||
.centos_weave_kubeadm_variables: ¢os_weave_kubeadm_variables
|
||||
# stage: deploy-part1
|
||||
UPGRADE_TEST: "graceful"
|
||||
|
||||
.centos7_multus_calico_variables: ¢os7_multus_calico_variables
|
||||
# stage: deploy-gce
|
||||
UPGRADE_TEST: "graceful"
|
||||
|
||||
# Builds for PRs only (premoderated by unit-tests step) and triggers (auto)
|
||||
### PR JOBS PART1
|
||||
|
||||
gce_ubuntu18-flannel-aio:
|
||||
stage: deploy-part1
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
### PR JOBS PART2
|
||||
|
||||
gce_coreos-calico-aio:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: on_success
|
||||
|
||||
gce_centos7-flannel-addons:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
### MANUAL JOBS
|
||||
|
||||
gce_centos-weave-kubeadm-sep:
|
||||
stage: deploy-gce
|
||||
extends: .gce
|
||||
variables:
|
||||
<<: *centos_weave_kubeadm_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
gce_ubuntu-weave-sep:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: manual
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
gce_coreos-calico-sep-triggers:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
gce_ubuntu-canal-ha-triggers:
|
||||
stage: deploy-special
|
||||
<<: *gce
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
gce_centos7-flannel-addons-triggers:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
gce_ubuntu-weave-sep-triggers:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
# More builds for PRs/merges (manual) and triggers (auto)
|
||||
|
||||
|
||||
gce_ubuntu-canal-ha:
|
||||
stage: deploy-special
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_ubuntu-canal-kubeadm:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_ubuntu-canal-kubeadm-triggers:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
gce_ubuntu-flannel-ha:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_centos-weave-kubeadm-triggers:
|
||||
stage: deploy-gce
|
||||
extends: .gce
|
||||
variables:
|
||||
<<: *centos_weave_kubeadm_variables
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
gce_ubuntu-contiv-sep:
|
||||
stage: deploy-special
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_coreos-cilium:
|
||||
stage: deploy-special
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_ubuntu18-cilium-sep:
|
||||
stage: deploy-special
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_rhel7-weave:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_rhel7-weave-triggers:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
gce_debian9-calico-upgrade:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_debian9-calico-triggers:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
gce_coreos-canal:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_coreos-canal-triggers:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
gce_rhel7-canal-sep:
|
||||
stage: deploy-special
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_rhel7-canal-sep-triggers:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
gce_centos7-calico-ha:
|
||||
stage: deploy-special
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_centos7-calico-ha-triggers:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: on_success
|
||||
only: ['triggers']
|
||||
except: []
|
||||
|
||||
gce_centos7-kube-router:
|
||||
stage: deploy-special
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_centos7-multus-calico:
|
||||
stage: deploy-gce
|
||||
extends: .gce
|
||||
variables:
|
||||
<<: *centos7_multus_calico_variables
|
||||
when: manual
|
||||
|
||||
gce_oracle-canal:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: manual
|
||||
except: ['triggers']
|
||||
only: ['master', /^pr-.*$/]
|
||||
|
||||
gce_opensuse-canal:
|
||||
stage: deploy-gce
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
# no triggers yet https://github.com/kubernetes-incubator/kargo/issues/613
|
||||
gce_coreos-alpha-weave-ha:
|
||||
stage: deploy-special
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_coreos-kube-router:
|
||||
stage: deploy-special
|
||||
<<: *gce
|
||||
when: manual
|
||||
|
||||
gce_ubuntu-kube-router-sep:
|
||||
stage: deploy-special
|
||||
<<: *gce
|
||||
when: manual
|
63
.gitlab-ci/lint.yml
Normal file
63
.gitlab-ci/lint.yml
Normal file
@ -0,0 +1,63 @@
|
||||
---
|
||||
yamllint:
|
||||
extends: .job
|
||||
stage: unit-tests
|
||||
variables:
|
||||
LANG: C.UTF-8
|
||||
script:
|
||||
- yamllint --strict .
|
||||
except: ['triggers', 'master']
|
||||
|
||||
vagrant-validate:
|
||||
extends: .job
|
||||
stage: unit-tests
|
||||
script:
|
||||
- curl -sL https://releases.hashicorp.com/vagrant/2.2.4/vagrant_2.2.4_x86_64.deb -o /tmp/vagrant_2.2.4_x86_64.deb
|
||||
- dpkg -i /tmp/vagrant_2.2.4_x86_64.deb
|
||||
- vagrant validate --ignore-provider
|
||||
except: ['triggers', 'master']
|
||||
|
||||
ansible-lint:
|
||||
extends: .job
|
||||
stage: unit-tests
|
||||
# lint every yml/yaml file that looks like it contains Ansible plays
|
||||
script: |-
|
||||
grep -Rl '^- hosts: \|^ hosts: ' --include \*.yml --include \*.yaml . | xargs -P 4 -n 25 ansible-lint -v
|
||||
except: ['triggers', 'master']
|
||||
|
||||
syntax-check:
|
||||
extends: .job
|
||||
stage: unit-tests
|
||||
variables:
|
||||
ANSIBLE_INVENTORY: inventory/local-tests.cfg
|
||||
ANSIBLE_REMOTE_USER: root
|
||||
ANSIBLE_BECOME: "true"
|
||||
ANSIBLE_BECOME_USER: root
|
||||
ANSIBLE_VERBOSITY: "3"
|
||||
script:
|
||||
- ansible-playbook --syntax-check cluster.yml
|
||||
- ansible-playbook --syntax-check upgrade-cluster.yml
|
||||
- ansible-playbook --syntax-check reset.yml
|
||||
- ansible-playbook --syntax-check extra_playbooks/upgrade-only-k8s.yml
|
||||
except: ['triggers', 'master']
|
||||
|
||||
tox-inventory-builder:
|
||||
stage: unit-tests
|
||||
extends: .job
|
||||
before_script:
|
||||
- ./tests/scripts/rebase.sh
|
||||
- apt-get update && apt-get install -y python3-pip
|
||||
- update-alternatives --install /usr/bin/python python /usr/bin/python3 10
|
||||
- python -m pip install -r tests/requirements.txt
|
||||
script:
|
||||
- pip3 install tox
|
||||
- cd contrib/inventory_builder && tox
|
||||
except: ['triggers', 'master']
|
||||
|
||||
markdownlint:
|
||||
stage: unit-tests
|
||||
image: node
|
||||
before_script:
|
||||
- npm install -g markdownlint-cli
|
||||
script:
|
||||
- markdownlint README.md docs --ignore docs/_sidebar.md
|
126
.gitlab-ci/packet.yml
Normal file
126
.gitlab-ci/packet.yml
Normal file
@ -0,0 +1,126 @@
|
||||
---
|
||||
.packet: &packet
|
||||
extends: .testcases
|
||||
variables:
|
||||
CI_PLATFORM: "packet"
|
||||
SSH_USER: "kubespray"
|
||||
tags:
|
||||
- packet
|
||||
only: [/^pr-.*$/]
|
||||
except: ['triggers']
|
||||
|
||||
packet_ubuntu18-calico-aio:
|
||||
stage: deploy-part1
|
||||
extends: .packet
|
||||
when: on_success
|
||||
|
||||
# ### PR JOBS PART2
|
||||
|
||||
packet_centos7-flannel-addons:
|
||||
extends: .packet
|
||||
stage: deploy-part2
|
||||
when: on_success
|
||||
|
||||
# ### MANUAL JOBS
|
||||
|
||||
packet_centos-weave-kubeadm-sep:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: on_success
|
||||
variables:
|
||||
UPGRADE_TEST: basic
|
||||
|
||||
packet_ubuntu-weave-sep:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: manual
|
||||
|
||||
# # More builds for PRs/merges (manual) and triggers (auto)
|
||||
|
||||
packet_ubuntu-canal-ha:
|
||||
stage: deploy-special
|
||||
extends: .packet
|
||||
when: manual
|
||||
|
||||
packet_ubuntu-canal-kubeadm:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: on_success
|
||||
|
||||
packet_ubuntu-flannel-ha:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: manual
|
||||
|
||||
# Contiv does not work in k8s v1.16
|
||||
# packet_ubuntu-contiv-sep:
|
||||
# stage: deploy-part2
|
||||
# extends: .packet
|
||||
# when: on_success
|
||||
|
||||
packet_ubuntu18-cilium-sep:
|
||||
stage: deploy-special
|
||||
extends: .packet
|
||||
when: manual
|
||||
|
||||
packet_ubuntu18-flannel-containerd:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: manual
|
||||
|
||||
packet_debian9-macvlan-sep:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: manual
|
||||
|
||||
packet_debian9-calico-upgrade:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: on_success
|
||||
variables:
|
||||
UPGRADE_TEST: graceful
|
||||
|
||||
packet_debian10-containerd:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: on_success
|
||||
|
||||
packet_centos7-calico-ha:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: manual
|
||||
|
||||
packet_centos7-kube-ovn:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: on_success
|
||||
|
||||
packet_centos7-kube-router:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: manual
|
||||
|
||||
packet_centos7-multus-calico:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: manual
|
||||
|
||||
packet_opensuse-canal:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: manual
|
||||
|
||||
packet_oracle-7-canal:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: manual
|
||||
|
||||
packet_ubuntu-kube-router-sep:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: manual
|
||||
|
||||
packet_amazon-linux-2-aio:
|
||||
stage: deploy-part2
|
||||
extends: .packet
|
||||
when: manual
|
15
.gitlab-ci/shellcheck.yml
Normal file
15
.gitlab-ci/shellcheck.yml
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
shellcheck:
|
||||
extends: .job
|
||||
stage: unit-tests
|
||||
variables:
|
||||
SHELLCHECK_VERSION: v0.6.0
|
||||
before_script:
|
||||
- ./tests/scripts/rebase.sh
|
||||
- curl --silent "https://storage.googleapis.com/shellcheck/shellcheck-"${SHELLCHECK_VERSION}".linux.x86_64.tar.xz" | tar -xJv
|
||||
- cp shellcheck-"${SHELLCHECK_VERSION}"/shellcheck /usr/bin/
|
||||
- shellcheck --version
|
||||
script:
|
||||
# Run shellcheck for all *.sh except contrib/
|
||||
- find . -name '*.sh' -not -path './contrib/*' | xargs shellcheck --severity error
|
||||
except: ['triggers', 'master']
|
161
.gitlab-ci/terraform.yml
Normal file
161
.gitlab-ci/terraform.yml
Normal file
@ -0,0 +1,161 @@
|
||||
---
|
||||
# Tests for contrib/terraform/
|
||||
.terraform_install:
|
||||
extends: .job
|
||||
before_script:
|
||||
- update-alternatives --install /usr/bin/python python /usr/bin/python3 1
|
||||
- ./tests/scripts/rebase.sh
|
||||
- ./tests/scripts/testcases_prepare.sh
|
||||
- ./tests/scripts/terraform_install.sh
|
||||
# Set Ansible config
|
||||
- cp ansible.cfg ~/.ansible.cfg
|
||||
# Prepare inventory
|
||||
- cp contrib/terraform/$PROVIDER/sample-inventory/cluster.tfvars .
|
||||
- ln -s contrib/terraform/$PROVIDER/hosts
|
||||
- terraform init contrib/terraform/$PROVIDER
|
||||
# Copy SSH keypair
|
||||
- mkdir -p ~/.ssh
|
||||
- echo "$PACKET_PRIVATE_KEY" | base64 -d > ~/.ssh/id_rsa
|
||||
- chmod 400 ~/.ssh/id_rsa
|
||||
- echo "$PACKET_PUBLIC_KEY" | base64 -d > ~/.ssh/id_rsa.pub
|
||||
|
||||
.terraform_validate:
|
||||
extends: .terraform_install
|
||||
stage: unit-tests
|
||||
only: ['master', /^pr-.*$/]
|
||||
script:
|
||||
- terraform validate -var-file=cluster.tfvars contrib/terraform/$PROVIDER
|
||||
- terraform fmt -check -diff contrib/terraform/$PROVIDER
|
||||
|
||||
.terraform_apply:
|
||||
extends: .terraform_install
|
||||
stage: deploy-part2
|
||||
when: manual
|
||||
only: [/^pr-.*$/]
|
||||
variables:
|
||||
ANSIBLE_INVENTORY_UNPARSED_FAILED: "true"
|
||||
ANSIBLE_INVENTORY: hosts
|
||||
CI_PLATFORM: tf
|
||||
TF_VAR_ssh_user: $SSH_USER
|
||||
TF_VAR_cluster_name: $CI_JOB_ID
|
||||
script:
|
||||
- tests/scripts/testcases_run.sh
|
||||
after_script:
|
||||
# Cleanup regardless of exit code
|
||||
- ./tests/scripts/testcases_cleanup.sh
|
||||
|
||||
tf-validate-openstack:
|
||||
extends: .terraform_validate
|
||||
variables:
|
||||
TF_VERSION: 0.12.12
|
||||
PROVIDER: openstack
|
||||
CLUSTER: $CI_COMMIT_REF_NAME
|
||||
|
||||
tf-validate-packet:
|
||||
extends: .terraform_validate
|
||||
variables:
|
||||
TF_VERSION: 0.12.12
|
||||
PROVIDER: packet
|
||||
CLUSTER: $CI_COMMIT_REF_NAME
|
||||
|
||||
tf-validate-aws:
|
||||
extends: .terraform_validate
|
||||
variables:
|
||||
TF_VERSION: 0.12.12
|
||||
PROVIDER: aws
|
||||
CLUSTER: $CI_COMMIT_REF_NAME
|
||||
|
||||
# tf-packet-ubuntu16-default:
|
||||
# extends: .terraform_apply
|
||||
# variables:
|
||||
# TF_VERSION: 0.12.12
|
||||
# PROVIDER: packet
|
||||
# CLUSTER: $CI_COMMIT_REF_NAME
|
||||
# TF_VAR_number_of_k8s_masters: "1"
|
||||
# TF_VAR_number_of_k8s_nodes: "1"
|
||||
# TF_VAR_plan_k8s_masters: t1.small.x86
|
||||
# TF_VAR_plan_k8s_nodes: t1.small.x86
|
||||
# TF_VAR_facility: ewr1
|
||||
# TF_VAR_public_key_path: ""
|
||||
# TF_VAR_operating_system: ubuntu_16_04
|
||||
#
|
||||
# tf-packet-ubuntu18-default:
|
||||
# extends: .terraform_apply
|
||||
# variables:
|
||||
# TF_VERSION: 0.12.12
|
||||
# PROVIDER: packet
|
||||
# CLUSTER: $CI_COMMIT_REF_NAME
|
||||
# TF_VAR_number_of_k8s_masters: "1"
|
||||
# TF_VAR_number_of_k8s_nodes: "1"
|
||||
# TF_VAR_plan_k8s_masters: t1.small.x86
|
||||
# TF_VAR_plan_k8s_nodes: t1.small.x86
|
||||
# TF_VAR_facility: ams1
|
||||
# TF_VAR_public_key_path: ""
|
||||
# TF_VAR_operating_system: ubuntu_18_04
|
||||
|
||||
.ovh_variables: &ovh_variables
|
||||
OS_AUTH_URL: https://auth.cloud.ovh.net/v3
|
||||
OS_PROJECT_ID: 8d3cd5d737d74227ace462dee0b903fe
|
||||
OS_PROJECT_NAME: "9361447987648822"
|
||||
OS_USER_DOMAIN_NAME: Default
|
||||
OS_PROJECT_DOMAIN_ID: default
|
||||
OS_USERNAME: 8XuhBMfkKVrk
|
||||
OS_REGION_NAME: UK1
|
||||
OS_INTERFACE: public
|
||||
OS_IDENTITY_API_VERSION: "3"
|
||||
|
||||
tf-ovh_ubuntu18-calico:
|
||||
extends: .terraform_apply
|
||||
when: on_success
|
||||
variables:
|
||||
<<: *ovh_variables
|
||||
TF_VERSION: 0.12.12
|
||||
PROVIDER: openstack
|
||||
CLUSTER: $CI_COMMIT_REF_NAME
|
||||
ANSIBLE_TIMEOUT: "60"
|
||||
SSH_USER: ubuntu
|
||||
TF_VAR_number_of_k8s_masters: "0"
|
||||
TF_VAR_number_of_k8s_masters_no_floating_ip: "1"
|
||||
TF_VAR_number_of_k8s_masters_no_floating_ip_no_etcd: "0"
|
||||
TF_VAR_number_of_etcd: "0"
|
||||
TF_VAR_number_of_k8s_nodes: "0"
|
||||
TF_VAR_number_of_k8s_nodes_no_floating_ip: "1"
|
||||
TF_VAR_number_of_gfs_nodes_no_floating_ip: "0"
|
||||
TF_VAR_number_of_bastions: "0"
|
||||
TF_VAR_number_of_k8s_masters_no_etcd: "0"
|
||||
TF_VAR_use_neutron: "0"
|
||||
TF_VAR_floatingip_pool: "Ext-Net"
|
||||
TF_VAR_external_net: "6011fbc9-4cbf-46a4-8452-6890a340b60b"
|
||||
TF_VAR_network_name: "Ext-Net"
|
||||
TF_VAR_flavor_k8s_master: "defa64c3-bd46-43b4-858a-d93bbae0a229" # s1-8
|
||||
TF_VAR_flavor_k8s_node: "defa64c3-bd46-43b4-858a-d93bbae0a229" # s1-8
|
||||
TF_VAR_image: "Ubuntu 18.04"
|
||||
TF_VAR_k8s_allowed_remote_ips: '["0.0.0.0/0"]'
|
||||
|
||||
tf-ovh_coreos-calico:
|
||||
extends: .terraform_apply
|
||||
when: on_success
|
||||
variables:
|
||||
<<: *ovh_variables
|
||||
TF_VERSION: 0.12.12
|
||||
PROVIDER: openstack
|
||||
CLUSTER: $CI_COMMIT_REF_NAME
|
||||
ANSIBLE_TIMEOUT: "60"
|
||||
SSH_USER: core
|
||||
TF_VAR_number_of_k8s_masters: "0"
|
||||
TF_VAR_number_of_k8s_masters_no_floating_ip: "1"
|
||||
TF_VAR_number_of_k8s_masters_no_floating_ip_no_etcd: "0"
|
||||
TF_VAR_number_of_etcd: "0"
|
||||
TF_VAR_number_of_k8s_nodes: "0"
|
||||
TF_VAR_number_of_k8s_nodes_no_floating_ip: "1"
|
||||
TF_VAR_number_of_gfs_nodes_no_floating_ip: "0"
|
||||
TF_VAR_number_of_bastions: "0"
|
||||
TF_VAR_number_of_k8s_masters_no_etcd: "0"
|
||||
TF_VAR_use_neutron: "0"
|
||||
TF_VAR_floatingip_pool: "Ext-Net"
|
||||
TF_VAR_external_net: "6011fbc9-4cbf-46a4-8452-6890a340b60b"
|
||||
TF_VAR_network_name: "Ext-Net"
|
||||
TF_VAR_flavor_k8s_master: "4d4fd037-9493-4f2b-9afe-b542b5248eac" # b2-7
|
||||
TF_VAR_flavor_k8s_node: "4d4fd037-9493-4f2b-9afe-b542b5248eac" # b2-7
|
||||
TF_VAR_image: "CoreOS Stable"
|
||||
TF_VAR_k8s_allowed_remote_ips: '["0.0.0.0/0"]'
|
2
.markdownlint.yaml
Normal file
2
.markdownlint.yaml
Normal file
@ -0,0 +1,2 @@
|
||||
---
|
||||
MD013: false
|
11
Dockerfile
11
Dockerfile
@ -1,11 +1,11 @@
|
||||
FROM ubuntu:16.04
|
||||
FROM ubuntu:18.04
|
||||
|
||||
RUN mkdir /kubespray
|
||||
WORKDIR /kubespray
|
||||
RUN apt update -y && \
|
||||
apt install -y \
|
||||
libssl-dev python-dev sshpass apt-transport-https jq \
|
||||
ca-certificates curl gnupg2 software-properties-common python-pip
|
||||
libssl-dev python3-dev sshpass apt-transport-https jq moreutils \
|
||||
ca-certificates curl gnupg2 software-properties-common python3-pip rsync
|
||||
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - && \
|
||||
add-apt-repository \
|
||||
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
|
||||
@ -13,7 +13,6 @@ RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - &&
|
||||
stable" \
|
||||
&& apt update -y && apt-get install docker-ce -y
|
||||
COPY . .
|
||||
RUN /usr/bin/python -m pip install pip -U && /usr/bin/python -m pip install -r tests/requirements.txt && python -m pip install -r requirements.txt
|
||||
RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.11.3/bin/linux/amd64/kubectl \
|
||||
RUN /usr/bin/python3 -m pip install pip -U && /usr/bin/python3 -m pip install -r tests/requirements.txt && python3 -m pip install -r requirements.txt && update-alternatives --install /usr/bin/python python /usr/bin/python3 1
|
||||
RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.14.4/bin/linux/amd64/kubectl \
|
||||
&& chmod a+x kubectl && cp kubectl /usr/local/bin/kubectl
|
||||
|
||||
|
@ -4,17 +4,12 @@ aliases:
|
||||
- mattymo
|
||||
- atoms
|
||||
- chadswen
|
||||
- rsmitty
|
||||
- bogdando
|
||||
- bradbeam
|
||||
- woopstar
|
||||
- mirwan
|
||||
- miouge1
|
||||
- riverzhang
|
||||
- holser
|
||||
- smana
|
||||
- verwilst
|
||||
- woopstar
|
||||
kubespray-reviewers:
|
||||
- jjungnickel
|
||||
- archifleks
|
||||
- chapsuk
|
||||
- mirwan
|
||||
- miouge1
|
||||
- holmsten
|
||||
|
262
README.md
262
README.md
@ -1,19 +1,17 @@
|
||||

|
||||
# Deploy a Production Ready Kubernetes Cluster
|
||||
|
||||
Deploy a Production Ready Kubernetes Cluster
|
||||
============================================
|
||||

|
||||
|
||||
If you have questions, check the [documentation](https://kubespray.io) and join us on the [kubernetes slack](https://kubernetes.slack.com), channel **\#kubespray**.
|
||||
You can get your invite [here](http://slack.k8s.io/)
|
||||
|
||||
- Can be deployed on **AWS, GCE, Azure, OpenStack, vSphere, Packet (bare metal), Oracle Cloud Infrastructure (Experimental), or Baremetal**
|
||||
- **Highly available** cluster
|
||||
- **Composable** (Choice of the network plugin for instance)
|
||||
- Supports most popular **Linux distributions**
|
||||
- **Continuous integration tests**
|
||||
- Can be deployed on **AWS, GCE, Azure, OpenStack, vSphere, Packet (bare metal), Oracle Cloud Infrastructure (Experimental), or Baremetal**
|
||||
- **Highly available** cluster
|
||||
- **Composable** (Choice of the network plugin for instance)
|
||||
- Supports most popular **Linux distributions**
|
||||
- **Continuous integration tests**
|
||||
|
||||
Quick Start
|
||||
-----------
|
||||
## Quick Start
|
||||
|
||||
To deploy the cluster you can use :
|
||||
|
||||
@ -21,31 +19,35 @@ To deploy the cluster you can use :
|
||||
|
||||
#### Usage
|
||||
|
||||
# Install dependencies from ``requirements.txt``
|
||||
sudo pip install -r requirements.txt
|
||||
```ShellSession
|
||||
# Install dependencies from ``requirements.txt``
|
||||
sudo pip install -r requirements.txt
|
||||
|
||||
# Copy ``inventory/sample`` as ``inventory/mycluster``
|
||||
cp -rfp inventory/sample inventory/mycluster
|
||||
# Copy ``inventory/sample`` as ``inventory/mycluster``
|
||||
cp -rfp inventory/sample inventory/mycluster
|
||||
|
||||
# Update Ansible inventory file with inventory builder
|
||||
declare -a IPS=(10.10.1.3 10.10.1.4 10.10.1.5)
|
||||
CONFIG_FILE=inventory/mycluster/hosts.ini python3 contrib/inventory_builder/inventory.py ${IPS[@]}
|
||||
# Update Ansible inventory file with inventory builder
|
||||
declare -a IPS=(10.10.1.3 10.10.1.4 10.10.1.5)
|
||||
CONFIG_FILE=inventory/mycluster/inventory.ini python3 contrib/inventory_builder/inventory.py ${IPS[@]}
|
||||
|
||||
# Review and change parameters under ``inventory/mycluster/group_vars``
|
||||
cat inventory/mycluster/group_vars/all/all.yml
|
||||
cat inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml
|
||||
# Review and change parameters under ``inventory/mycluster/group_vars``
|
||||
cat inventory/mycluster/group_vars/all/all.yml
|
||||
cat inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml
|
||||
|
||||
# Deploy Kubespray with Ansible Playbook - run the playbook as root
|
||||
# The option `-b` is required, as for example writing SSL keys in /etc/,
|
||||
# installing packages and interacting with various systemd daemons.
|
||||
# Without -b the playbook will fail to run!
|
||||
ansible-playbook -i inventory/mycluster/hosts.ini --become --become-user=root cluster.yml
|
||||
# Deploy Kubespray with Ansible Playbook - run the playbook as root
|
||||
# The option `--become` is required, as for example writing SSL keys in /etc/,
|
||||
# installing packages and interacting with various systemd daemons.
|
||||
# Without --become the playbook will fail to run!
|
||||
ansible-playbook -i inventory/mycluster/inventory.ini --become --become-user=root cluster.yml
|
||||
```
|
||||
|
||||
Note: When Ansible is already installed via system packages on the control machine, other python packages installed via `sudo pip install -r requirements.txt` will go to a different directory tree (e.g. `/usr/local/lib/python2.7/dist-packages` on Ubuntu) from Ansible's (e.g. `/usr/lib/python2.7/dist-packages/ansible` still on Ubuntu).
|
||||
As a consequence, `ansible-playbook` command will fail with:
|
||||
```
|
||||
|
||||
```raw
|
||||
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
|
||||
```
|
||||
|
||||
probably pointing on a task depending on a module present in requirements.txt (i.e. "unseal vault").
|
||||
|
||||
One way of solving this would be to uninstall the Ansible package and then, to install it via pip but it is not always possible.
|
||||
@ -56,156 +58,154 @@ A workaround consists of setting `ANSIBLE_LIBRARY` and `ANSIBLE_MODULE_UTILS` en
|
||||
For Vagrant we need to install python dependencies for provisioning tasks.
|
||||
Check if Python and pip are installed:
|
||||
|
||||
python -V && pip -V
|
||||
```ShellSession
|
||||
python -V && pip -V
|
||||
```
|
||||
|
||||
If this returns the version of the software, you're good to go. If not, download and install Python from here <https://www.python.org/downloads/source/>
|
||||
Install the necessary requirements
|
||||
|
||||
sudo pip install -r requirements.txt
|
||||
vagrant up
|
||||
```ShellSession
|
||||
sudo pip install -r requirements.txt
|
||||
vagrant up
|
||||
```
|
||||
|
||||
Documents
|
||||
---------
|
||||
## Documents
|
||||
|
||||
- [Requirements](#requirements)
|
||||
- [Kubespray vs ...](docs/comparisons.md)
|
||||
- [Getting started](docs/getting-started.md)
|
||||
- [Ansible inventory and tags](docs/ansible.md)
|
||||
- [Integration with existing ansible repo](docs/integration.md)
|
||||
- [Deployment data variables](docs/vars.md)
|
||||
- [DNS stack](docs/dns-stack.md)
|
||||
- [HA mode](docs/ha-mode.md)
|
||||
- [Network plugins](#network-plugins)
|
||||
- [Vagrant install](docs/vagrant.md)
|
||||
- [CoreOS bootstrap](docs/coreos.md)
|
||||
- [Debian Jessie setup](docs/debian.md)
|
||||
- [openSUSE setup](docs/opensuse.md)
|
||||
- [Downloaded artifacts](docs/downloads.md)
|
||||
- [Cloud providers](docs/cloud.md)
|
||||
- [OpenStack](docs/openstack.md)
|
||||
- [AWS](docs/aws.md)
|
||||
- [Azure](docs/azure.md)
|
||||
- [vSphere](docs/vsphere.md)
|
||||
- [Packet Host](docs/packet.md)
|
||||
- [Large deployments](docs/large-deployments.md)
|
||||
- [Upgrades basics](docs/upgrades.md)
|
||||
- [Roadmap](docs/roadmap.md)
|
||||
- [Requirements](#requirements)
|
||||
- [Kubespray vs ...](docs/comparisons.md)
|
||||
- [Getting started](docs/getting-started.md)
|
||||
- [Ansible inventory and tags](docs/ansible.md)
|
||||
- [Integration with existing ansible repo](docs/integration.md)
|
||||
- [Deployment data variables](docs/vars.md)
|
||||
- [DNS stack](docs/dns-stack.md)
|
||||
- [HA mode](docs/ha-mode.md)
|
||||
- [Network plugins](#network-plugins)
|
||||
- [Vagrant install](docs/vagrant.md)
|
||||
- [CoreOS bootstrap](docs/coreos.md)
|
||||
- [Debian Jessie setup](docs/debian.md)
|
||||
- [openSUSE setup](docs/opensuse.md)
|
||||
- [Downloaded artifacts](docs/downloads.md)
|
||||
- [Cloud providers](docs/cloud.md)
|
||||
- [OpenStack](docs/openstack.md)
|
||||
- [AWS](docs/aws.md)
|
||||
- [Azure](docs/azure.md)
|
||||
- [vSphere](docs/vsphere.md)
|
||||
- [Packet Host](docs/packet.md)
|
||||
- [Large deployments](docs/large-deployments.md)
|
||||
- [Upgrades basics](docs/upgrades.md)
|
||||
- [Roadmap](docs/roadmap.md)
|
||||
|
||||
Supported Linux Distributions
|
||||
-----------------------------
|
||||
## Supported Linux Distributions
|
||||
|
||||
- **Container Linux by CoreOS**
|
||||
- **Debian** Buster, Jessie, Stretch, Wheezy
|
||||
- **Ubuntu** 16.04, 18.04
|
||||
- **CentOS/RHEL** 7
|
||||
- **Fedora** 28
|
||||
- **Fedora/CentOS** Atomic
|
||||
- **openSUSE** Leap 42.3/Tumbleweed
|
||||
- **Container Linux by CoreOS**
|
||||
- **Debian** Buster, Jessie, Stretch, Wheezy
|
||||
- **Ubuntu** 16.04, 18.04
|
||||
- **CentOS/RHEL** 7
|
||||
- **Fedora** 28
|
||||
- **Fedora/CentOS** Atomic
|
||||
- **openSUSE** Leap 42.3/Tumbleweed
|
||||
- **Oracle Linux** 7
|
||||
|
||||
Note: Upstart/SysV init based OS types are not supported.
|
||||
|
||||
Supported Components
|
||||
--------------------
|
||||
## Supported Components
|
||||
|
||||
- Core
|
||||
- [kubernetes](https://github.com/kubernetes/kubernetes) v1.13.5
|
||||
- [etcd](https://github.com/coreos/etcd) v3.2.26
|
||||
- [docker](https://www.docker.com/) v18.06 (see note)
|
||||
- [rkt](https://github.com/rkt/rkt) v1.21.0 (see Note 2)
|
||||
- [cri-o](http://cri-o.io/) v1.11.5 (experimental: see [CRI-O Note](docs/cri-o.md). Only on centos based OS)
|
||||
- Network Plugin
|
||||
- [calico](https://github.com/projectcalico/calico) v3.4.0
|
||||
- [canal](https://github.com/projectcalico/canal) (given calico/flannel versions)
|
||||
- [cilium](https://github.com/cilium/cilium) v1.3.0
|
||||
- [contiv](https://github.com/contiv/install) v1.2.1
|
||||
- [flanneld](https://github.com/coreos/flannel) v0.11.0
|
||||
- [kube-router](https://github.com/cloudnativelabs/kube-router) v0.2.5
|
||||
- [multus](https://github.com/intel/multus-cni) v3.1.autoconf
|
||||
- [weave](https://github.com/weaveworks/weave) v2.5.1
|
||||
- Application
|
||||
- [cephfs-provisioner](https://github.com/kubernetes-incubator/external-storage) v2.1.0-k8s1.11
|
||||
- [cert-manager](https://github.com/jetstack/cert-manager) v0.5.2
|
||||
- [coredns](https://github.com/coredns/coredns) v1.4.0
|
||||
- [ingress-nginx](https://github.com/kubernetes/ingress-nginx) v0.21.0
|
||||
- Core
|
||||
- [kubernetes](https://github.com/kubernetes/kubernetes) v1.16.8
|
||||
- [etcd](https://github.com/coreos/etcd) v3.3.12
|
||||
- [docker](https://www.docker.com/) v18.06 (see note)
|
||||
- [containerd](https://containerd.io/) v1.2.13
|
||||
- [cri-o](http://cri-o.io/) v1.14.0 (experimental: see [CRI-O Note](docs/cri-o.md). Only on centos based OS)
|
||||
- Network Plugin
|
||||
- [cni-plugins](https://github.com/containernetworking/plugins) v0.8.1
|
||||
- [calico](https://github.com/projectcalico/calico) v3.7.3
|
||||
- [canal](https://github.com/projectcalico/canal) (given calico/flannel versions)
|
||||
- [cilium](https://github.com/cilium/cilium) v1.5.5
|
||||
- [contiv](https://github.com/contiv/install) v1.2.1
|
||||
- [flanneld](https://github.com/coreos/flannel) v0.11.0
|
||||
- [kube-router](https://github.com/cloudnativelabs/kube-router) v0.2.5
|
||||
- [multus](https://github.com/intel/multus-cni) v3.2.1
|
||||
- [weave](https://github.com/weaveworks/weave) v2.5.2
|
||||
- Application
|
||||
- [cephfs-provisioner](https://github.com/kubernetes-incubator/external-storage) v2.1.0-k8s1.11
|
||||
- [rbd-provisioner](https://github.com/kubernetes-incubator/external-storage) v2.1.1-k8s1.11
|
||||
- [cert-manager](https://github.com/jetstack/cert-manager) v0.11.0
|
||||
- [coredns](https://github.com/coredns/coredns) v1.6.0
|
||||
- [ingress-nginx](https://github.com/kubernetes/ingress-nginx) v0.26.1
|
||||
|
||||
Note: The list of validated [docker versions](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.13.md) was updated to 1.11.1, 1.12.1, 1.13.1, 17.03, 17.06, 17.09, 18.06. kubeadm now properly recognizes Docker 18.09.0 and newer, but still treats 18.06 as the default supported version. The kubelet might break on docker's non-standard version numbering (it no longer uses semantic versioning). To ensure auto-updates don't break your cluster look into e.g. yum versionlock plugin or apt pin).
|
||||
Note: The list of validated [docker versions](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.16.md) was updated to 1.13.1, 17.03, 17.06, 17.09, 18.06, 18.09. kubeadm now properly recognizes Docker 18.09.0 and newer, but still treats 18.06 as the default supported version. The kubelet might break on docker's non-standard version numbering (it no longer uses semantic versioning). To ensure auto-updates don't break your cluster look into e.g. yum versionlock plugin or apt pin).
|
||||
|
||||
Note 2: rkt support as docker alternative is limited to control plane (etcd and
|
||||
kubelet). Docker is still used for Kubernetes cluster workloads and network
|
||||
plugins' related OS services. Also note, only one of the supported network
|
||||
plugins can be deployed for a given single cluster.
|
||||
## Requirements
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
- **Ansible v2.7.6 (or newer) and python-netaddr is installed on the machine
|
||||
that will run Ansible commands**
|
||||
- **Jinja 2.9 (or newer) is required to run the Ansible Playbooks**
|
||||
- The target servers must have **access to the Internet** in order to pull docker images. Otherwise, additional configuration is required (See [Offline Environment](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/downloads.md#offline-environment))
|
||||
- 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.
|
||||
- **Minimum required version of Kubernetes is v1.15**
|
||||
- **Ansible v2.7.16 and python-netaddr is installed on the machine that will run Ansible commands**
|
||||
- **Jinja 2.9 (or newer) is required to run the Ansible Playbooks**
|
||||
- The target servers must have **access to the Internet** in order to pull docker images. Otherwise, additional configuration is required (See [Offline Environment](https://github.com/kubernetes-sigs/kubespray/blob/master/docs/downloads.md#offline-environment))
|
||||
- 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.
|
||||
- If kubespray is ran from non-root user account, correct privilege escalation method
|
||||
- If kubespray is ran from non-root user account, correct privilege escalation method
|
||||
should be configured in the target servers. Then the `ansible_become` flag
|
||||
or command parameters `--become or -b` should be specified.
|
||||
|
||||
Hardware:
|
||||
Hardware:
|
||||
These limits are safe guarded by Kubespray. Actual requirements for your workload can differ. For a sizing guide go to the [Building Large Clusters](https://kubernetes.io/docs/setup/cluster-large/#size-of-master-and-master-components) guide.
|
||||
|
||||
- Master
|
||||
- Memory: 1500 MB
|
||||
- Node
|
||||
- Memory: 1024 MB
|
||||
- Master
|
||||
- Memory: 1500 MB
|
||||
- Node
|
||||
- Memory: 1024 MB
|
||||
|
||||
Network Plugins
|
||||
---------------
|
||||
## Network Plugins
|
||||
|
||||
You can choose between 6 network plugins. (default: `calico`, except Vagrant uses `flannel`)
|
||||
You can choose between 10 network plugins. (default: `calico`, except Vagrant uses `flannel`)
|
||||
|
||||
- [flannel](docs/flannel.md): gre/vxlan (layer 2) networking.
|
||||
- [flannel](docs/flannel.md): gre/vxlan (layer 2) networking.
|
||||
|
||||
- [calico](docs/calico.md): bgp (layer 3) networking.
|
||||
- [calico](docs/calico.md): bgp (layer 3) networking.
|
||||
|
||||
- [canal](https://github.com/projectcalico/canal): a composition of calico and flannel plugins.
|
||||
- [canal](https://github.com/projectcalico/canal): a composition of calico and flannel plugins.
|
||||
|
||||
- [cilium](http://docs.cilium.io/en/latest/): layer 3/4 networking (as well as layer 7 to protect and secure application protocols), supports dynamic insertion of BPF bytecode into the Linux kernel to implement security services, networking and visibility logic.
|
||||
- [cilium](http://docs.cilium.io/en/latest/): layer 3/4 networking (as well as layer 7 to protect and secure application protocols), supports dynamic insertion of BPF bytecode into the Linux kernel to implement security services, networking and visibility logic.
|
||||
|
||||
- [contiv](docs/contiv.md): supports vlan, vxlan, bgp and Cisco SDN networking. This plugin is able to
|
||||
- [contiv](docs/contiv.md): supports vlan, vxlan, bgp and Cisco SDN networking. This plugin is able to
|
||||
apply firewall policies, segregate containers in multiple network and bridging pods onto physical networks.
|
||||
|
||||
- [weave](docs/weave.md): Weave is a lightweight container overlay network that doesn't require an external K/V database cluster.
|
||||
(Please refer to `weave` [troubleshooting documentation](http://docs.weave.works/weave/latest_release/troubleshooting.html)).
|
||||
- [weave](docs/weave.md): Weave is a lightweight container overlay network that doesn't require an external K/V database cluster.
|
||||
(Please refer to `weave` [troubleshooting documentation](https://www.weave.works/docs/net/latest/troubleshooting/)).
|
||||
|
||||
- [kube-router](docs/kube-router.md): Kube-router is a L3 CNI for Kubernetes networking aiming to provide operational
|
||||
- [kube-ovn](docs/kube-ovn.md): Kube-OVN integrates the OVN-based Network Virtualization with Kubernetes. It offers an advanced Container Network Fabric for Enterprises.
|
||||
|
||||
- [kube-router](docs/kube-router.md): Kube-router is a L3 CNI for Kubernetes networking aiming to provide operational
|
||||
simplicity and high performance: it uses IPVS to provide Kube Services Proxy (if setup to replace kube-proxy),
|
||||
iptables for network policies, and BGP for ods L3 networking (with optionally BGP peering with out-of-cluster BGP peers).
|
||||
It can also optionally advertise routes to Kubernetes cluster Pods CIDRs, ClusterIPs, ExternalIPs and LoadBalancerIPs.
|
||||
|
||||
- [multus](docs/multus.md): Multus is a meta CNI plugin that provides multiple network interface support to pods. For each interface Multus delegates CNI calls to secondary CNI plugins such as Calico, macvlan, etc.
|
||||
- [macvlan](docs/macvlan.md): Macvlan is a Linux network driver. Pods have their own unique Mac and Ip address, connected directly the physical (layer 2) network.
|
||||
|
||||
- [multus](docs/multus.md): Multus is a meta CNI plugin that provides multiple network interface support to pods. For each interface Multus delegates CNI calls to secondary CNI plugins such as Calico, macvlan, etc.
|
||||
|
||||
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
|
||||
----------------------------
|
||||
## Community docs and resources
|
||||
|
||||
- [kubernetes.io/docs/getting-started-guides/kubespray/](https://kubernetes.io/docs/getting-started-guides/kubespray/)
|
||||
- [kubespray, 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 Kubernetes Cluster with Kubespray (video)](https://www.youtube.com/watch?v=N9q51JgbWu8)
|
||||
- [kubernetes.io/docs/setup/production-environment/tools/kubespray/](https://kubernetes.io/docs/setup/production-environment/tools/kubespray/)
|
||||
- [kubespray, 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 Kubernetes Cluster with Kubespray (video)](https://www.youtube.com/watch?v=N9q51JgbWu8)
|
||||
|
||||
Tools and projects on top of Kubespray
|
||||
--------------------------------------
|
||||
## Tools and projects on top of Kubespray
|
||||
|
||||
- [Digital Rebar Provision](https://github.com/digitalrebar/provision/blob/master/doc/integrations/ansible.rst)
|
||||
- [Terraform Contrib](https://github.com/kubernetes-sigs/kubespray/tree/master/contrib/terraform)
|
||||
- [Digital Rebar Provision](https://github.com/digitalrebar/provision/blob/v4/doc/integrations/ansible.rst)
|
||||
- [Terraform Contrib](https://github.com/kubernetes-sigs/kubespray/tree/master/contrib/terraform)
|
||||
|
||||
CI Tests
|
||||
--------
|
||||
## CI Tests
|
||||
|
||||
[](https://gitlab.com/kubespray-ci/kubernetes-incubator__kubespray/pipelines)
|
||||
[](https://gitlab.com/kargo-ci/kubernetes-sigs-kubespray/pipelines)
|
||||
|
||||
CI/end-to-end tests sponsored by Google (GCE)
|
||||
See the [test matrix](docs/test_cases.md) for details.
|
||||
|
17
RELEASE.md
17
RELEASE.md
@ -3,16 +3,19 @@
|
||||
The Kubespray Project is released on an as-needed basis. The process is as follows:
|
||||
|
||||
1. An issue is proposing a new release with a changelog since the last release
|
||||
2. At least one of the [OWNERS](OWNERS) must LGTM this release
|
||||
3. An OWNER runs `git tag -s $VERSION` and inserts the changelog and pushes the tag with `git push $VERSION`
|
||||
4. The release issue is closed
|
||||
5. An announcement email is sent to `kubernetes-dev@googlegroups.com` with the subject `[ANNOUNCE] Kubespray $VERSION is released`
|
||||
2. At least one of the [approvers](OWNERS_ALIASES) must approve this release
|
||||
3. An approver creates [new release in GitHub](https://github.com/kubernetes-sigs/kubespray/releases/new) using a version and tag name like `vX.Y.Z` and attaching the release notes
|
||||
4. An approver creates a release branch in the form `release-vX.Y`
|
||||
5. The corresponding version of [quay.io/kubespray/kubespray:vX.Y.Z](https://quay.io/repository/kubespray/kubespray) docker image is built and tagged
|
||||
6. The `KUBESPRAY_VERSION` variable is updated in `.gitlab-ci.yml`
|
||||
7. The release issue is closed
|
||||
8. An announcement email is sent to `kubernetes-dev@googlegroups.com` with the subject `[ANNOUNCE] Kubespray $VERSION is released`
|
||||
|
||||
## Major/minor releases, merge freezes and milestones
|
||||
|
||||
* Kubespray does not maintain stable branches for releases. Releases are tags, not
|
||||
branches, and there are no backports. Therefore, there is no need for merge
|
||||
freezes as well.
|
||||
* Kubespray maintains one branch for major releases (vX.Y). Minor releases are available only as tags.
|
||||
|
||||
* Security patches and bugs might be backported.
|
||||
|
||||
* Fixes for major releases (vX.x.0) and minor releases (vX.Y.x) are delivered
|
||||
via maintenance releases (vX.Y.Z) and assigned to the corresponding open
|
||||
|
20
Vagrantfile
vendored
20
Vagrantfile
vendored
@ -21,10 +21,11 @@ SUPPORTED_OS = {
|
||||
"ubuntu1604" => {box: "generic/ubuntu1604", user: "vagrant"},
|
||||
"ubuntu1804" => {box: "generic/ubuntu1804", user: "vagrant"},
|
||||
"centos" => {box: "centos/7", user: "vagrant"},
|
||||
"centos-bento" => {box: "bento/centos-7.5", user: "vagrant"},
|
||||
"centos-bento" => {box: "bento/centos-7.6", user: "vagrant"},
|
||||
"fedora" => {box: "fedora/28-cloud-base", user: "vagrant"},
|
||||
"opensuse" => {box: "opensuse/openSUSE-15.0-x86_64", user: "vagrant"},
|
||||
"opensuse-tumbleweed" => {box: "opensuse/openSUSE-Tumbleweed-x86_64", user: "vagrant"},
|
||||
"oraclelinux" => {box: "generic/oracle7", user: "vagrant"},
|
||||
}
|
||||
|
||||
# Defaults for config options defined in CONFIG
|
||||
@ -180,11 +181,20 @@ Vagrant.configure("2") do |config|
|
||||
"flannel_interface": "eth1",
|
||||
"kube_network_plugin": $network_plugin,
|
||||
"kube_network_plugin_multus": $multi_networking,
|
||||
"docker_keepcache": "1",
|
||||
"download_run_once": "False",
|
||||
"download_run_once": "True",
|
||||
"download_localhost": "False",
|
||||
"download_cache_dir": ENV['HOME'] + "/kubespray_cache",
|
||||
# Make kubespray cache even when download_run_once is false
|
||||
"download_force_cache": "True",
|
||||
# Keeping the cache on the nodes can improve provisioning speed while debugging kubespray
|
||||
"download_keep_remote_cache": "False",
|
||||
"docker_keepcache": "1",
|
||||
# These two settings will put kubectl and admin.config in $inventory/artifacts
|
||||
"kubeconfig_localhost": "True",
|
||||
"kubectl_localhost": "True",
|
||||
"local_path_provisioner_enabled": "#{$local_path_provisioner_enabled}",
|
||||
"local_path_provisioner_claim_root": "#{$local_path_provisioner_claim_root}"
|
||||
"local_path_provisioner_claim_root": "#{$local_path_provisioner_claim_root}",
|
||||
"ansible_ssh_user": SUPPORTED_OS[$os][:user]
|
||||
}
|
||||
|
||||
# Only execute the Ansible provisioner once, when all the machines are up and ready.
|
||||
@ -196,7 +206,7 @@ Vagrant.configure("2") do |config|
|
||||
ansible.inventory_path = $ansible_inventory_path
|
||||
end
|
||||
ansible.become = true
|
||||
ansible.limit = "all"
|
||||
ansible.limit = "all,localhost"
|
||||
ansible.host_key_checking = false
|
||||
ansible.raw_arguments = ["--forks=#{$num_instances}", "--flush-cache", "-e ansible_become_pass=vagrant"]
|
||||
ansible.host_vars = host_vars
|
||||
|
@ -4,6 +4,8 @@ ssh_args = -o ControlMaster=auto -o ControlPersist=30m -o ConnectionAttempts=100
|
||||
#control_path = ~/.ssh/ansible-%%r@%%h:%%p
|
||||
[defaults]
|
||||
strategy_plugins = plugins/mitogen/ansible_mitogen/plugins/strategy
|
||||
# https://github.com/ansible/ansible/issues/56930 (to ignore group names with - and .)
|
||||
force_valid_group_names = ignore
|
||||
|
||||
host_key_checking=False
|
||||
gathering = smart
|
||||
@ -14,6 +16,6 @@ library = ./library
|
||||
callback_whitelist = profile_tasks
|
||||
roles_path = roles:$VIRTUAL_ENV/usr/local/share/kubespray/roles:$VIRTUAL_ENV/usr/local/share/ansible/roles:/usr/share/kubespray/roles
|
||||
deprecation_warnings=False
|
||||
inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo, .creds
|
||||
inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo, .creds, .gpg
|
||||
[inventory]
|
||||
ignore_patterns = artifacts, credentials
|
||||
|
67
cluster.yml
67
cluster.yml
@ -3,11 +3,11 @@
|
||||
gather_facts: false
|
||||
become: no
|
||||
tasks:
|
||||
- name: "Check ansible version >=2.7.6"
|
||||
- name: "Check ansible version >=2.7.8"
|
||||
assert:
|
||||
msg: "Ansible must be v2.7.6 or higher"
|
||||
msg: "Ansible must be v2.7.8 or higher"
|
||||
that:
|
||||
- ansible_version.string is version("2.7.6", ">=")
|
||||
- ansible_version.string is version("2.7.8", ">=")
|
||||
tags:
|
||||
- check
|
||||
vars:
|
||||
@ -19,57 +19,50 @@
|
||||
- { role: kubespray-defaults}
|
||||
- { role: bastion-ssh-config, tags: ["localhost", "bastion"]}
|
||||
|
||||
- hosts: k8s-cluster:etcd:calico-rr
|
||||
- hosts: k8s-cluster:etcd
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(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: kubespray-defaults}
|
||||
- { role: bootstrap-os, tags: bootstrap-os}
|
||||
|
||||
- hosts: k8s-cluster:etcd:calico-rr
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
vars:
|
||||
ansible_ssh_pipelining: true
|
||||
gather_facts: false
|
||||
pre_tasks:
|
||||
- name: gather facts from all instances
|
||||
setup:
|
||||
delegate_to: "{{item}}"
|
||||
delegate_facts: true
|
||||
with_items: "{{ groups['k8s-cluster'] + groups['etcd'] + groups['calico-rr']|default([]) }}"
|
||||
run_once: true
|
||||
|
||||
- hosts: k8s-cluster:etcd:calico-rr
|
||||
- hosts: k8s-cluster:etcd
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults}
|
||||
- { role: kubernetes/preinstall, tags: preinstall }
|
||||
- { role: "container-engine", tags: "container-engine", when: deploy_container_engine|default(true) }
|
||||
- { role: download, tags: download, when: "not skip_downloads" }
|
||||
environment: "{{proxy_env}}"
|
||||
environment: "{{ proxy_env }}"
|
||||
|
||||
- hosts: etcd
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults}
|
||||
- { role: etcd, tags: etcd, etcd_cluster_setup: true, etcd_events_cluster_setup: "{{ etcd_events_cluster_enabled }}" }
|
||||
- role: etcd
|
||||
tags: etcd
|
||||
vars:
|
||||
etcd_cluster_setup: true
|
||||
etcd_events_cluster_setup: "{{ etcd_events_cluster_enabled }}"
|
||||
when: not etcd_kubeadm_enabled| default(false)
|
||||
|
||||
- hosts: k8s-cluster:calico-rr
|
||||
- hosts: k8s-cluster
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults}
|
||||
- { role: etcd, tags: etcd, etcd_cluster_setup: false, etcd_events_cluster_setup: false }
|
||||
- role: etcd
|
||||
tags: etcd
|
||||
vars:
|
||||
etcd_cluster_setup: false
|
||||
etcd_events_cluster_setup: false
|
||||
when: not etcd_kubeadm_enabled| default(false)
|
||||
|
||||
- hosts: k8s-cluster
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults}
|
||||
- { role: kubernetes/node, tags: node }
|
||||
environment: "{{proxy_env}}"
|
||||
environment: "{{ proxy_env }}"
|
||||
|
||||
- hosts: kube-master
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
@ -85,6 +78,13 @@
|
||||
- { role: kubespray-defaults}
|
||||
- { role: kubernetes/kubeadm, tags: kubeadm}
|
||||
- { role: network_plugin, tags: network }
|
||||
- { role: kubernetes/node-label }
|
||||
|
||||
- hosts: calico-rr
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults}
|
||||
- { role: network_plugin/calico/rr, tags: ['network', 'calico_rr']}
|
||||
|
||||
- hosts: kube-master[0]
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
@ -102,16 +102,15 @@
|
||||
- { role: kubernetes-apps/ingress_controller, tags: ingress-controller }
|
||||
- { role: kubernetes-apps/external_provisioner, tags: external-provisioner }
|
||||
|
||||
- hosts: calico-rr
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults}
|
||||
- { role: network_plugin/calico/rr, tags: network }
|
||||
|
||||
- hosts: kube-master
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults}
|
||||
- { role: kubernetes-apps, tags: apps }
|
||||
environment: "{{ proxy_env }}"
|
||||
|
||||
- hosts: k8s-cluster
|
||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||
roles:
|
||||
- { role: kubespray-defaults}
|
||||
- { role: kubernetes/preinstall, when: "dns_mode != 'none' and resolvconf_mode == 'host_resolvconf'", tags: resolvconf, dns_late: true }
|
||||
environment: "{{proxy_env}}"
|
||||
|
@ -42,8 +42,11 @@ class SearchEC2Tags(object):
|
||||
region = os.environ['REGION']
|
||||
|
||||
ec2 = boto3.resource('ec2', region)
|
||||
|
||||
instances = ec2.instances.filter(Filters=[{'Name': 'tag:'+tag_key, 'Values': tag_value}, {'Name': 'instance-state-name', 'Values': ['running']}])
|
||||
filters = [{'Name': 'tag:'+tag_key, 'Values': tag_value}, {'Name': 'instance-state-name', 'Values': ['running']}]
|
||||
cluster_name = os.getenv('CLUSTER_NAME')
|
||||
if cluster_name:
|
||||
filters.append({'Name': 'tag-key', 'Values': ['kubernetes.io/cluster/'+cluster_name]})
|
||||
instances = ec2.instances.filter(Filters=filters)
|
||||
for instance in instances:
|
||||
|
||||
##Suppose default vpc_visibility is private
|
||||
|
@ -7,7 +7,7 @@ cluster_name: example
|
||||
# node that can be used to access the masters and minions
|
||||
use_bastion: false
|
||||
|
||||
# Set this to a prefered name that will be used as the first part of the dns name for your bastotion host. For example: k8s-bastion.<azureregion>.cloudapp.azure.com.
|
||||
# Set this to a preferred name that will be used as the first part of the dns name for your bastotion host. For example: k8s-bastion.<azureregion>.cloudapp.azure.com.
|
||||
# This is convenient when exceptions have to be configured on a firewall to allow ssh to the given bastion host.
|
||||
# bastion_domain_prefix: k8s-bastion
|
||||
|
||||
|
@ -4,8 +4,11 @@
|
||||
command: azure vm list-ip-address --json {{ azure_resource_group }}
|
||||
register: vm_list_cmd
|
||||
|
||||
- set_fact:
|
||||
- name: Set vm_list
|
||||
set_fact:
|
||||
vm_list: "{{ vm_list_cmd.stdout }}"
|
||||
|
||||
- name: Generate inventory
|
||||
template: src=inventory.j2 dest="{{playbook_dir}}/inventory"
|
||||
template:
|
||||
src: inventory.j2
|
||||
dest: "{{ playbook_dir }}/inventory"
|
||||
|
@ -8,9 +8,22 @@
|
||||
command: az vm list -o json --resource-group {{ azure_resource_group }}
|
||||
register: vm_list_cmd
|
||||
|
||||
- set_fact:
|
||||
- name: Query Azure Load Balancer Public IP
|
||||
command: az network public-ip show -o json -g {{ azure_resource_group }} -n kubernetes-api-pubip
|
||||
register: lb_pubip_cmd
|
||||
|
||||
- name: Set VM IP, roles lists and load balancer public IP
|
||||
set_fact:
|
||||
vm_ip_list: "{{ vm_ip_list_cmd.stdout }}"
|
||||
vm_roles_list: "{{ vm_list_cmd.stdout }}"
|
||||
lb_pubip: "{{ lb_pubip_cmd.stdout }}"
|
||||
|
||||
- name: Generate inventory
|
||||
template: src=inventory.j2 dest="{{playbook_dir}}/inventory"
|
||||
template:
|
||||
src: inventory.j2
|
||||
dest: "{{ playbook_dir }}/inventory"
|
||||
|
||||
- name: Generate Load Balancer variables
|
||||
template:
|
||||
src: loadbalancer_vars.j2
|
||||
dest: "{{ playbook_dir }}/loadbalancer_vars.yml"
|
||||
|
@ -0,0 +1,8 @@
|
||||
## External LB example config
|
||||
apiserver_loadbalancer_domain_name: {{ lb_pubip.dnsSettings.fqdn }}
|
||||
loadbalancer_apiserver:
|
||||
address: {{ lb_pubip.ipAddress }}
|
||||
port: 6443
|
||||
|
||||
## Internal loadbalancers for apiservers
|
||||
loadbalancer_apiserver_localhost: false
|
@ -29,7 +29,7 @@ sshKeyPath: "/home/{{admin_username}}/.ssh/authorized_keys"
|
||||
imageReference:
|
||||
publisher: "OpenLogic"
|
||||
offer: "CentOS"
|
||||
sku: "7.2"
|
||||
sku: "7.5"
|
||||
version: "latest"
|
||||
imageReferenceJson: "{{imageReference|to_json}}"
|
||||
|
||||
|
@ -1,10 +1,18 @@
|
||||
---
|
||||
- set_fact:
|
||||
base_dir: "{{playbook_dir}}/.generated/"
|
||||
- name: Set base_dir
|
||||
set_fact:
|
||||
base_dir: "{{ playbook_dir }}/.generated/"
|
||||
|
||||
- file: path={{base_dir}} state=directory recurse=true
|
||||
- name: Create base_dir
|
||||
file:
|
||||
path: "{{ base_dir }}"
|
||||
state: directory
|
||||
recurse: true
|
||||
|
||||
- template: src={{item}} dest="{{base_dir}}/{{item}}"
|
||||
- name: Store json files in base_dir
|
||||
template:
|
||||
src: "{{ item }}"
|
||||
dest: "{{ base_dir }}/{{ item }}"
|
||||
with_items:
|
||||
- network.json
|
||||
- storage.json
|
||||
|
@ -12,7 +12,7 @@
|
||||
- name: Null-ify some linux tools to ease DIND
|
||||
file:
|
||||
src: "/bin/true"
|
||||
dest: "{{item}}"
|
||||
dest: "{{ item }}"
|
||||
state: link
|
||||
force: yes
|
||||
with_items:
|
||||
@ -52,7 +52,7 @@
|
||||
- rsyslog
|
||||
- "{{ distro_ssh_service }}"
|
||||
|
||||
- name: Create distro user "{{distro_user}}"
|
||||
- name: Create distro user "{{ distro_user }}"
|
||||
user:
|
||||
name: "{{ distro_user }}"
|
||||
uid: 1000
|
||||
|
@ -28,7 +28,7 @@
|
||||
- /lib/modules:/lib/modules
|
||||
- "{{ item }}:/dind/docker"
|
||||
register: containers
|
||||
with_items: "{{groups.containers}}"
|
||||
with_items: "{{ groups.containers }}"
|
||||
tags:
|
||||
- addresses
|
||||
|
||||
@ -79,6 +79,7 @@
|
||||
with_items: "{{ containers.results }}"
|
||||
|
||||
- name: Early hack image install to adapt for DIND
|
||||
# noqa 302 - this task uses the raw module intentionally
|
||||
raw: |
|
||||
rm -fv /usr/bin/udevadm /usr/sbin/udevadm
|
||||
delegate_to: "{{ item._ansible_item_label|default(item.item) }}"
|
||||
|
@ -20,6 +20,8 @@
|
||||
# Add range of hosts: inventory.py 10.10.1.3-10.10.1.5
|
||||
# Add hosts with different ip and access ip:
|
||||
# inventory.py 10.0.0.1,192.168.10.1 10.0.0.2,192.168.10.2 10.0.0.3,192.168.1.3
|
||||
# Add hosts with a specific hostname, ip, and optional access ip:
|
||||
# inventory.py first,10.0.0.1,192.168.10.1 second,10.0.0.2 last,10.0.0.3
|
||||
# Delete a host: inventory.py -10.10.1.3
|
||||
# Delete a host by id: inventory.py -node1
|
||||
#
|
||||
@ -44,7 +46,8 @@ import sys
|
||||
ROLES = ['all', 'kube-master', 'kube-node', 'etcd', 'k8s-cluster',
|
||||
'calico-rr']
|
||||
PROTECTED_NAMES = ROLES
|
||||
AVAILABLE_COMMANDS = ['help', 'print_cfg', 'print_ips', 'load']
|
||||
AVAILABLE_COMMANDS = ['help', 'print_cfg', 'print_ips', 'print_hostnames',
|
||||
'load']
|
||||
_boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
|
||||
'0': False, 'no': False, 'false': False, 'off': False}
|
||||
yaml = YAML()
|
||||
@ -59,6 +62,7 @@ def get_var_as_bool(name, default):
|
||||
|
||||
|
||||
CONFIG_FILE = os.environ.get("CONFIG_FILE", "./inventory/sample/hosts.yaml")
|
||||
KUBE_MASTERS = int(os.environ.get("KUBE_MASTERS_MASTERS", 2))
|
||||
# Reconfigures cluster distribution at scale
|
||||
SCALE_THRESHOLD = int(os.environ.get("SCALE_THRESHOLD", 50))
|
||||
MASSIVE_SCALE_THRESHOLD = int(os.environ.get("SCALE_THRESHOLD", 200))
|
||||
@ -78,7 +82,7 @@ class KubesprayInventory(object):
|
||||
try:
|
||||
self.hosts_file = open(config_file, 'r')
|
||||
self.yaml_config = yaml.load(self.hosts_file)
|
||||
except FileNotFoundError:
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
if changed_hosts and changed_hosts[0] in AVAILABLE_COMMANDS:
|
||||
@ -93,14 +97,16 @@ class KubesprayInventory(object):
|
||||
self.purge_invalid_hosts(self.hosts.keys(), PROTECTED_NAMES)
|
||||
self.set_all(self.hosts)
|
||||
self.set_k8s_cluster()
|
||||
self.set_etcd(list(self.hosts.keys())[:3])
|
||||
etcd_hosts_count = 3 if len(self.hosts.keys()) >= 3 else 1
|
||||
self.set_etcd(list(self.hosts.keys())[:etcd_hosts_count])
|
||||
if len(self.hosts) >= SCALE_THRESHOLD:
|
||||
self.set_kube_master(list(self.hosts.keys())[3:5])
|
||||
self.set_kube_master(list(self.hosts.keys())[
|
||||
etcd_hosts_count:(etcd_hosts_count + KUBE_MASTERS)])
|
||||
else:
|
||||
self.set_kube_master(list(self.hosts.keys())[:2])
|
||||
self.set_kube_master(list(self.hosts.keys())[:KUBE_MASTERS])
|
||||
self.set_kube_node(self.hosts.keys())
|
||||
if len(self.hosts) >= SCALE_THRESHOLD:
|
||||
self.set_calico_rr(list(self.hosts.keys())[:3])
|
||||
self.set_calico_rr(list(self.hosts.keys())[:etcd_hosts_count])
|
||||
else: # Show help if no options
|
||||
self.show_help()
|
||||
sys.exit(0)
|
||||
@ -191,8 +197,21 @@ class KubesprayInventory(object):
|
||||
'ip': ip,
|
||||
'access_ip': access_ip}
|
||||
elif host[0].isalpha():
|
||||
raise Exception("Adding hosts by hostname is not supported.")
|
||||
|
||||
if ',' in host:
|
||||
try:
|
||||
hostname, ip, access_ip = host.split(',')
|
||||
except Exception:
|
||||
hostname, ip = host.split(',')
|
||||
access_ip = ip
|
||||
if self.exists_hostname(all_hosts, host):
|
||||
self.debug("Skipping existing host {0}.".format(host))
|
||||
continue
|
||||
elif self.exists_ip(all_hosts, ip):
|
||||
self.debug("Skipping existing host {0}.".format(ip))
|
||||
continue
|
||||
all_hosts[hostname] = {'ansible_host': access_ip,
|
||||
'ip': ip,
|
||||
'access_ip': access_ip}
|
||||
return all_hosts
|
||||
|
||||
def range2ips(self, hosts):
|
||||
@ -202,11 +221,11 @@ class KubesprayInventory(object):
|
||||
try:
|
||||
# Python 3.x
|
||||
start = int(ip_address(start_address))
|
||||
end = int(ip_address(end_address))
|
||||
except:
|
||||
end = int(ip_address(end_address))
|
||||
except Exception:
|
||||
# Python 2.7
|
||||
start = int(ip_address(unicode(start_address)))
|
||||
end = int(ip_address(unicode(end_address)))
|
||||
start = int(ip_address(str(start_address)))
|
||||
end = int(ip_address(str(end_address)))
|
||||
return [ip_address(ip).exploded for ip in range(start, end + 1)]
|
||||
|
||||
for host in hosts:
|
||||
@ -345,6 +364,8 @@ class KubesprayInventory(object):
|
||||
self.print_config()
|
||||
elif command == 'print_ips':
|
||||
self.print_ips()
|
||||
elif command == 'print_hostnames':
|
||||
self.print_hostnames()
|
||||
elif command == 'load':
|
||||
self.load_file(args)
|
||||
else:
|
||||
@ -358,11 +379,13 @@ Available commands:
|
||||
help - Display this message
|
||||
print_cfg - Write inventory file to stdout
|
||||
print_ips - Write a space-delimited list of IPs from "all" group
|
||||
print_hostnames - Write a space-delimited list of Hostnames from "all" group
|
||||
|
||||
Advanced usage:
|
||||
Add another host after initial creation: inventory.py 10.10.1.5
|
||||
Add range of hosts: inventory.py 10.10.1.3-10.10.1.5
|
||||
Add hosts with different ip and access ip: inventory.py 10.0.0.1,192.168.10.1 10.0.0.2,192.168.10.2 10.0.0.3,192.168.10.3
|
||||
Add hosts with a specific hostname, ip, and optional access ip: first,10.0.0.1,192.168.10.1 second,10.0.0.2 last,10.0.0.3
|
||||
Delete a host: inventory.py -10.10.1.3
|
||||
Delete a host by id: inventory.py -node1
|
||||
|
||||
@ -378,6 +401,9 @@ MASSIVE_SCALE_THRESHOLD Separate K8s master and ETCD if # of nodes >= 200
|
||||
def print_config(self):
|
||||
yaml.dump(self.yaml_config, sys.stdout)
|
||||
|
||||
def print_hostnames(self):
|
||||
print(' '.join(self.yaml_config['all']['hosts'].keys()))
|
||||
|
||||
def print_ips(self):
|
||||
ips = []
|
||||
for host, opts in self.yaml_config['all']['hosts'].items():
|
||||
|
@ -12,6 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import inventory
|
||||
import mock
|
||||
import unittest
|
||||
|
||||
@ -22,7 +23,7 @@ path = "./contrib/inventory_builder/"
|
||||
if path not in sys.path:
|
||||
sys.path.append(path)
|
||||
|
||||
import inventory
|
||||
import inventory # noqa
|
||||
|
||||
|
||||
class TestInventory(unittest.TestCase):
|
||||
@ -43,8 +44,8 @@ class TestInventory(unittest.TestCase):
|
||||
|
||||
def test_get_ip_from_opts_invalid(self):
|
||||
optstring = "notanaddr=value something random!chars:D"
|
||||
self.assertRaisesRegexp(ValueError, "IP parameter not found",
|
||||
self.inv.get_ip_from_opts, optstring)
|
||||
self.assertRaisesRegex(ValueError, "IP parameter not found",
|
||||
self.inv.get_ip_from_opts, optstring)
|
||||
|
||||
def test_ensure_required_groups(self):
|
||||
groups = ['group1', 'group2']
|
||||
@ -63,8 +64,8 @@ class TestInventory(unittest.TestCase):
|
||||
def test_get_host_id_invalid(self):
|
||||
bad_hostnames = ['node', 'no99de', '01node', 'node.111111']
|
||||
for hostname in bad_hostnames:
|
||||
self.assertRaisesRegexp(ValueError, "Host name must end in an",
|
||||
self.inv.get_host_id, hostname)
|
||||
self.assertRaisesRegex(ValueError, "Host name must end in an",
|
||||
self.inv.get_host_id, hostname)
|
||||
|
||||
def test_build_hostnames_add_one(self):
|
||||
changed_hosts = ['10.90.0.2']
|
||||
@ -192,8 +193,8 @@ class TestInventory(unittest.TestCase):
|
||||
('node2', {'ansible_host': '10.90.0.3',
|
||||
'ip': '10.90.0.3',
|
||||
'access_ip': '10.90.0.3'})])
|
||||
self.assertRaisesRegexp(ValueError, "Unable to find host",
|
||||
self.inv.delete_host_by_ip, existing_hosts, ip)
|
||||
self.assertRaisesRegex(ValueError, "Unable to find host",
|
||||
self.inv.delete_host_by_ip, existing_hosts, ip)
|
||||
|
||||
def test_purge_invalid_hosts(self):
|
||||
proper_hostnames = ['node1', 'node2']
|
||||
@ -309,8 +310,8 @@ class TestInventory(unittest.TestCase):
|
||||
|
||||
def test_range2ips_incorrect_range(self):
|
||||
host_range = ['10.90.0.4-a.9b.c.e']
|
||||
self.assertRaisesRegexp(Exception, "Range of ip_addresses isn't valid",
|
||||
self.inv.range2ips, host_range)
|
||||
self.assertRaisesRegex(Exception, "Range of ip_addresses isn't valid",
|
||||
self.inv.range2ips, host_range)
|
||||
|
||||
def test_build_hostnames_different_ips_add_one(self):
|
||||
changed_hosts = ['10.90.0.2,192.168.0.2']
|
||||
|
@ -1,7 +1,7 @@
|
||||
[tox]
|
||||
minversion = 1.6
|
||||
skipsdist = True
|
||||
envlist = pep8, py27
|
||||
envlist = pep8, py33
|
||||
|
||||
[testenv]
|
||||
whitelist_externals = py.test
|
||||
|
@ -1,15 +1,9 @@
|
||||
---
|
||||
|
||||
- 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
|
||||
state: present
|
||||
with_items:
|
||||
- bind-utils
|
||||
- ntp
|
||||
@ -21,23 +15,13 @@
|
||||
update_cache: yes
|
||||
cache_valid_time: 3600
|
||||
name: "{{ item }}"
|
||||
state: latest
|
||||
state: present
|
||||
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
|
||||
|
@ -2,9 +2,11 @@
|
||||
```
|
||||
MetalLB hooks into your Kubernetes cluster, and provides a network load-balancer implementation. In short, it allows you to create Kubernetes services of type “LoadBalancer” in clusters that don’t run on a cloud provider, and thus cannot simply hook into paid products to provide load-balancers.
|
||||
```
|
||||
This playbook aims to automate [this](https://metallb.universe.tf/tutorial/layer2/tutorial). It deploys MetalLB into kubernetes and sets up a layer 2 loadbalancer.
|
||||
This playbook aims to automate [this](https://metallb.universe.tf/concepts/layer2/). It deploys MetalLB into kubernetes and sets up a layer 2 loadbalancer.
|
||||
|
||||
## Install
|
||||
```
|
||||
Defaults can be found in contrib/metallb/roles/provision/defaults/main.yml. You can override the defaults by copying the contents of this file to somewhere in inventory/mycluster/group_vars such as inventory/mycluster/groups_vars/k8s-cluster/addons.yml and making any adjustments as required.
|
||||
|
||||
ansible-playbook --ask-become -i inventory/sample/hosts.ini contrib/metallb/metallb.yml
|
||||
```
|
||||
|
@ -1,6 +1,12 @@
|
||||
---
|
||||
metallb:
|
||||
ip_range: "10.5.0.50-10.5.0.99"
|
||||
protocol: "layer2"
|
||||
# additional_address_pools:
|
||||
# kube_service_pool:
|
||||
# ip_range: "10.5.1.50-10.5.1.99"
|
||||
# protocol: "layer2"
|
||||
# auto_assign: false
|
||||
limits:
|
||||
cpu: "100m"
|
||||
memory: "100Mi"
|
||||
|
@ -1,4 +1,9 @@
|
||||
---
|
||||
- name: "Kubernetes Apps | Check cluster settings for MetalLB"
|
||||
fail:
|
||||
msg: "MetalLB require kube_proxy_strict_arp = true, see https://github.com/danderson/metallb/issues/153#issuecomment-518651132"
|
||||
when:
|
||||
- "kube_proxy_mode == 'ipvs' and not kube_proxy_strict_arp"
|
||||
- name: "Kubernetes Apps | Lay Down MetalLB"
|
||||
become: true
|
||||
template: { src: "{{ item }}.j2", dest: "{{ kube_config_dir }}/{{ item }}" }
|
||||
@ -9,7 +14,7 @@
|
||||
- name: "Kubernetes Apps | Install and configure MetalLB"
|
||||
kube:
|
||||
name: "MetalLB"
|
||||
kubectl: "{{bin_dir}}/kubectl"
|
||||
kubectl: "{{ bin_dir }}/kubectl"
|
||||
filename: "{{ kube_config_dir }}/{{ item.item }}"
|
||||
state: "{{ item.changed | ternary('latest','present') }}"
|
||||
become: true
|
||||
|
@ -8,6 +8,14 @@ data:
|
||||
config: |
|
||||
address-pools:
|
||||
- name: loadbalanced
|
||||
protocol: layer2
|
||||
protocol: {{ metallb.protocol }}
|
||||
addresses:
|
||||
- {{ metallb.ip_range }}
|
||||
{% if metallb.additional_address_pools is defined %}{% for pool in metallb.additional_address_pools %}
|
||||
- name: {{ pool }}
|
||||
protocol: {{ metallb.additional_address_pools[pool].protocol }}
|
||||
addresses:
|
||||
- {{ metallb.additional_address_pools[pool].ip_range }}
|
||||
auto-assign: {{ metallb.additional_address_pools[pool].auto_assign }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
@ -115,7 +115,7 @@ roleRef:
|
||||
kind: Role
|
||||
name: config-watcher
|
||||
---
|
||||
apiVersion: apps/v1beta2
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
namespace: metallb-system
|
||||
@ -169,7 +169,7 @@ spec:
|
||||
- net_raw
|
||||
|
||||
---
|
||||
apiVersion: apps/v1beta2
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
namespace: metallb-system
|
||||
|
15
contrib/misc/clusteradmin-rbac.yml
Normal file
15
contrib/misc/clusteradmin-rbac.yml
Normal file
@ -0,0 +1,15 @@
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1beta1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: kubernetes-dashboard
|
||||
labels:
|
||||
k8s-app: kubernetes-dashboard
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: cluster-admin
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: kubernetes-dashboard
|
||||
namespace: kube-system
|
@ -21,7 +21,7 @@ You can specify a `default_release` for apt on Debian/Ubuntu by overriding this
|
||||
glusterfs_ppa_use: yes
|
||||
glusterfs_ppa_version: "3.5"
|
||||
|
||||
For Ubuntu, specify whether to use the official Gluster PPA, and which version of the PPA to use. See Gluster's [Getting Started Guide](http://www.gluster.org/community/documentation/index.php/Getting_started_install) for more info.
|
||||
For Ubuntu, specify whether to use the official Gluster PPA, and which version of the PPA to use. See Gluster's [Getting Started Guide](https://docs.gluster.org/en/latest/Quick-Start-Guide/Quickstart/) for more info.
|
||||
|
||||
## Dependencies
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
- name: Include OS-specific variables.
|
||||
include_vars: "{{ ansible_os_family }}.yml"
|
||||
|
||||
# Instal xfs package
|
||||
# Install xfs package
|
||||
- name: install xfs Debian
|
||||
apt: name=xfsprogs state=present
|
||||
when: ansible_os_family == "Debian"
|
||||
@ -36,7 +36,7 @@
|
||||
- "{{ gluster_brick_dir }}"
|
||||
- "{{ gluster_mount_dir }}"
|
||||
|
||||
- name: Configure Gluster volume.
|
||||
- name: Configure Gluster volume with replicas
|
||||
gluster_volume:
|
||||
state: present
|
||||
name: "{{ gluster_brick_name }}"
|
||||
@ -46,6 +46,18 @@
|
||||
host: "{{ inventory_hostname }}"
|
||||
force: yes
|
||||
run_once: true
|
||||
when: groups['gfs-cluster']|length > 1
|
||||
|
||||
- name: Configure Gluster volume without replicas
|
||||
gluster_volume:
|
||||
state: present
|
||||
name: "{{ gluster_brick_name }}"
|
||||
brick: "{{ gluster_brick_dir }}"
|
||||
cluster: "{% for item in groups['gfs-cluster'] -%}{{ hostvars[item]['ip']|default(hostvars[item].ansible_default_ipv4['address']) }}{% if not loop.last %},{% endif %}{%- endfor %}"
|
||||
host: "{{ inventory_hostname }}"
|
||||
force: yes
|
||||
run_once: true
|
||||
when: groups['gfs-cluster']|length <= 1
|
||||
|
||||
- name: Mount glusterfs to retrieve disk size
|
||||
mount:
|
||||
|
@ -1,6 +1,8 @@
|
||||
---
|
||||
- name: Kubernetes Apps | Lay Down k8s GlusterFS Endpoint and PV
|
||||
template: src={{item.file}} dest={{kube_config_dir}}/{{item.dest}}
|
||||
template:
|
||||
src: "{{ item.file }}"
|
||||
dest: "{{ kube_config_dir }}/{{ item.dest }}"
|
||||
with_items:
|
||||
- { file: glusterfs-kubernetes-endpoint.json.j2, type: ep, dest: glusterfs-kubernetes-endpoint.json}
|
||||
- { file: glusterfs-kubernetes-pv.yml.j2, type: pv, dest: glusterfs-kubernetes-pv.yml}
|
||||
@ -12,9 +14,9 @@
|
||||
kube:
|
||||
name: glusterfs
|
||||
namespace: default
|
||||
kubectl: "{{bin_dir}}/kubectl"
|
||||
resource: "{{item.item.type}}"
|
||||
filename: "{{kube_config_dir}}/{{item.item.dest}}"
|
||||
state: "{{item.changed | ternary('latest','present') }}"
|
||||
kubectl: "{{ bin_dir }}/kubectl"
|
||||
resource: "{{ item.item.type }}"
|
||||
filename: "{{ kube_config_dir }}/{{ item.item.dest }}"
|
||||
state: "{{ item.changed | ternary('latest','present') }}"
|
||||
with_items: "{{ gluster_pv.results }}"
|
||||
when: inventory_hostname == groups['kube-master'][0] and groups['gfs-cluster'] is defined
|
||||
|
@ -14,3 +14,5 @@ ansible-playbook --ask-become -i inventory/sample/k8s_heketi_inventory.yml contr
|
||||
```
|
||||
ansible-playbook --ask-become -i inventory/sample/k8s_heketi_inventory.yml contrib/network-storage/heketi/heketi-tear-down.yml
|
||||
```
|
||||
|
||||
Add `--extra-vars "heketi_remove_lvm=true"` to the command above to remove LVM packages from the system
|
||||
|
@ -4,6 +4,7 @@
|
||||
register: "initial_heketi_state"
|
||||
changed_when: false
|
||||
command: "{{ bin_dir }}/kubectl get services,deployments,pods --selector=deploy-heketi --output=json"
|
||||
|
||||
- name: "Bootstrap heketi."
|
||||
when:
|
||||
- "(initial_heketi_state.stdout|from_json|json_query(\"items[?kind=='Service']\"))|length == 0"
|
||||
@ -16,15 +17,20 @@
|
||||
register: "initial_heketi_pod"
|
||||
command: "{{ bin_dir }}/kubectl get pods --selector=deploy-heketi=pod,glusterfs=heketi-pod,name=deploy-heketi --output=json"
|
||||
changed_when: false
|
||||
|
||||
- name: "Ensure heketi bootstrap pod is up."
|
||||
assert:
|
||||
that: "(initial_heketi_pod.stdout|from_json|json_query('items[*]'))|length == 1"
|
||||
- set_fact:
|
||||
|
||||
- name: Store the initial heketi pod name
|
||||
set_fact:
|
||||
initial_heketi_pod_name: "{{ initial_heketi_pod.stdout|from_json|json_query(\"items[*].metadata.name|[0]\") }}"
|
||||
|
||||
- name: "Test heketi topology."
|
||||
changed_when: false
|
||||
register: "heketi_topology"
|
||||
command: "{{ bin_dir }}/kubectl exec {{ initial_heketi_pod_name }} -- heketi-cli --user admin --secret {{ heketi_admin_key }} topology info --json"
|
||||
|
||||
- name: "Load heketi topology."
|
||||
when: "heketi_topology.stdout|from_json|json_query(\"clusters[*].nodes[*]\")|flatten|length == 0"
|
||||
include_tasks: "bootstrap/topology.yml"
|
||||
@ -42,6 +48,7 @@
|
||||
command: "{{ bin_dir }}/kubectl get secrets,endpoints,services,jobs --output=json"
|
||||
changed_when: false
|
||||
register: "heketi_storage_state"
|
||||
|
||||
# ensure endpoints actually exist before trying to move database data to it
|
||||
- name: "Create heketi storage."
|
||||
include_tasks: "bootstrap/storage.yml"
|
||||
|
@ -6,7 +6,7 @@
|
||||
- name: "Kubernetes Apps | Install and configure Heketi Bootstrap"
|
||||
kube:
|
||||
name: "GlusterFS"
|
||||
kubectl: "{{bin_dir}}/kubectl"
|
||||
kubectl: "{{ bin_dir }}/kubectl"
|
||||
filename: "{{ kube_config_dir }}/heketi-bootstrap.json"
|
||||
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
||||
- name: "Wait for heketi bootstrap to complete."
|
||||
|
@ -6,7 +6,7 @@
|
||||
- name: "Create heketi storage."
|
||||
kube:
|
||||
name: "GlusterFS"
|
||||
kubectl: "{{bin_dir}}/kubectl"
|
||||
kubectl: "{{ bin_dir }}/kubectl"
|
||||
filename: "{{ kube_config_dir }}/heketi-storage-bootstrap.json"
|
||||
state: "present"
|
||||
vars:
|
||||
|
@ -6,7 +6,7 @@
|
||||
- name: "Kubernetes Apps | Install and configure GlusterFS daemonset"
|
||||
kube:
|
||||
name: "GlusterFS"
|
||||
kubectl: "{{bin_dir}}/kubectl"
|
||||
kubectl: "{{ bin_dir }}/kubectl"
|
||||
filename: "{{ kube_config_dir }}/glusterfs-daemonset.json"
|
||||
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
||||
- name: "Kubernetes Apps | Label GlusterFS nodes"
|
||||
@ -33,6 +33,6 @@
|
||||
- name: "Kubernetes Apps | Install and configure Heketi Service Account"
|
||||
kube:
|
||||
name: "GlusterFS"
|
||||
kubectl: "{{bin_dir}}/kubectl"
|
||||
kubectl: "{{ bin_dir }}/kubectl"
|
||||
filename: "{{ kube_config_dir }}/heketi-service-account.json"
|
||||
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
||||
|
@ -1,11 +1,19 @@
|
||||
---
|
||||
- register: "label_present"
|
||||
- name: Get storage nodes
|
||||
register: "label_present"
|
||||
command: "{{ bin_dir }}/kubectl get node --selector=storagenode=glusterfs,kubernetes.io/hostname={{ node }} --ignore-not-found=true"
|
||||
changed_when: false
|
||||
|
||||
- name: "Assign storage label"
|
||||
when: "label_present.stdout_lines|length == 0"
|
||||
command: "{{ bin_dir }}/kubectl label node {{ node }} storagenode=glusterfs"
|
||||
- register: "label_present"
|
||||
|
||||
- name: Get storage nodes again
|
||||
register: "label_present"
|
||||
command: "{{ bin_dir }}/kubectl get node --selector=storagenode=glusterfs,kubernetes.io/hostname={{ node }} --ignore-not-found=true"
|
||||
changed_when: false
|
||||
- assert: { that: "label_present|length > 0", msg: "Node {{ node }} has not been assigned with label storagenode=glusterfs." }
|
||||
|
||||
- name: Ensure the label has been set
|
||||
assert:
|
||||
that: "label_present|length > 0"
|
||||
msg: "Node {{ node }} has not been assigned with label storagenode=glusterfs."
|
||||
|
@ -1,19 +1,24 @@
|
||||
---
|
||||
- name: "Kubernetes Apps | Lay Down Heketi"
|
||||
become: true
|
||||
template: { src: "heketi-deployment.json.j2", dest: "{{ kube_config_dir }}/heketi-deployment.json" }
|
||||
template:
|
||||
src: "heketi-deployment.json.j2"
|
||||
dest: "{{ kube_config_dir }}/heketi-deployment.json"
|
||||
register: "rendering"
|
||||
|
||||
- name: "Kubernetes Apps | Install and configure Heketi"
|
||||
kube:
|
||||
name: "GlusterFS"
|
||||
kubectl: "{{bin_dir}}/kubectl"
|
||||
kubectl: "{{ bin_dir }}/kubectl"
|
||||
filename: "{{ kube_config_dir }}/heketi-deployment.json"
|
||||
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
||||
|
||||
- name: "Ensure heketi is up and running."
|
||||
changed_when: false
|
||||
register: "heketi_state"
|
||||
vars:
|
||||
heketi_state: { stdout: "{}" }
|
||||
heketi_state:
|
||||
stdout: "{}"
|
||||
pods_query: "items[?kind=='Pod'].status.conditions|[0][?type=='Ready'].status|[0]"
|
||||
deployments_query: "items[?kind=='Deployment'].status.conditions|[0][?type=='Available'].status|[0]"
|
||||
command: "{{ bin_dir }}/kubectl get deployments,pods --selector=glusterfs --output=json"
|
||||
@ -22,5 +27,7 @@
|
||||
- "heketi_state.stdout|from_json|json_query(deployments_query) == 'True'"
|
||||
retries: 60
|
||||
delay: 5
|
||||
- set_fact:
|
||||
|
||||
- name: Set the Heketi pod name
|
||||
set_fact:
|
||||
heketi_pod_name: "{{ heketi_state.stdout|from_json|json_query(\"items[?kind=='Pod'].metadata.name|[0]\") }}"
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
- name: "Kubernetes Apps | Test Heketi"
|
||||
register: "heketi_service_state"
|
||||
command: "{{bin_dir}}/kubectl get service heketi-storage-endpoints -o=name --ignore-not-found=true"
|
||||
command: "{{ bin_dir }}/kubectl get service heketi-storage-endpoints -o=name --ignore-not-found=true"
|
||||
changed_when: false
|
||||
|
||||
- name: "Kubernetes Apps | Bootstrap Heketi"
|
||||
|
@ -1,31 +1,44 @@
|
||||
---
|
||||
- register: "clusterrolebinding_state"
|
||||
command: "{{bin_dir}}/kubectl get clusterrolebinding heketi-gluster-admin -o=name --ignore-not-found=true"
|
||||
- name: Get clusterrolebindings
|
||||
register: "clusterrolebinding_state"
|
||||
command: "{{ bin_dir }}/kubectl get clusterrolebinding heketi-gluster-admin -o=name --ignore-not-found=true"
|
||||
changed_when: false
|
||||
|
||||
- name: "Kubernetes Apps | Deploy cluster role binding."
|
||||
when: "clusterrolebinding_state.stdout == \"\""
|
||||
command: "{{bin_dir}}/kubectl create clusterrolebinding heketi-gluster-admin --clusterrole=edit --serviceaccount=default:heketi-service-account"
|
||||
- register: "clusterrolebinding_state"
|
||||
command: "{{bin_dir}}/kubectl get clusterrolebinding heketi-gluster-admin -o=name --ignore-not-found=true"
|
||||
command: "{{ bin_dir }}/kubectl create clusterrolebinding heketi-gluster-admin --clusterrole=edit --serviceaccount=default:heketi-service-account"
|
||||
|
||||
- name: Get clusterrolebindings again
|
||||
register: "clusterrolebinding_state"
|
||||
command: "{{ bin_dir }}/kubectl get clusterrolebinding heketi-gluster-admin -o=name --ignore-not-found=true"
|
||||
changed_when: false
|
||||
- assert:
|
||||
|
||||
- name: Make sure that clusterrolebindings are present now
|
||||
assert:
|
||||
that: "clusterrolebinding_state.stdout != \"\""
|
||||
msg: "Cluster role binding is not present."
|
||||
|
||||
- register: "secret_state"
|
||||
command: "{{bin_dir}}/kubectl get secret heketi-config-secret -o=name --ignore-not-found=true"
|
||||
- name: Get the heketi-config-secret secret
|
||||
register: "secret_state"
|
||||
command: "{{ bin_dir }}/kubectl get secret heketi-config-secret -o=name --ignore-not-found=true"
|
||||
changed_when: false
|
||||
|
||||
- name: "Render Heketi secret configuration."
|
||||
become: true
|
||||
template:
|
||||
src: "heketi.json.j2"
|
||||
dest: "{{ kube_config_dir }}/heketi.json"
|
||||
|
||||
- name: "Deploy Heketi config secret"
|
||||
when: "secret_state.stdout == \"\""
|
||||
command: "{{bin_dir}}/kubectl create secret generic heketi-config-secret --from-file={{ kube_config_dir }}/heketi.json"
|
||||
- register: "secret_state"
|
||||
command: "{{bin_dir}}/kubectl get secret heketi-config-secret -o=name --ignore-not-found=true"
|
||||
command: "{{ bin_dir }}/kubectl create secret generic heketi-config-secret --from-file={{ kube_config_dir }}/heketi.json"
|
||||
|
||||
- name: Get the heketi-config-secret secret again
|
||||
register: "secret_state"
|
||||
command: "{{ bin_dir }}/kubectl get secret heketi-config-secret -o=name --ignore-not-found=true"
|
||||
changed_when: false
|
||||
- assert:
|
||||
|
||||
- name: Make sure the heketi-config-secret secret exists now
|
||||
assert:
|
||||
that: "secret_state.stdout != \"\""
|
||||
msg: "Heketi config secret is not present."
|
||||
|
@ -7,6 +7,6 @@
|
||||
- name: "Kubernetes Apps | Install and configure Heketi Storage"
|
||||
kube:
|
||||
name: "GlusterFS"
|
||||
kubectl: "{{bin_dir}}/kubectl"
|
||||
kubectl: "{{ bin_dir }}/kubectl"
|
||||
filename: "{{ kube_config_dir }}/heketi-storage.json"
|
||||
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
||||
|
@ -20,6 +20,6 @@
|
||||
- name: "Kubernetes Apps | Install and configure Storace Class"
|
||||
kube:
|
||||
name: "GlusterFS"
|
||||
kubectl: "{{bin_dir}}/kubectl"
|
||||
kubectl: "{{ bin_dir }}/kubectl"
|
||||
filename: "{{ kube_config_dir }}/storageclass.yml"
|
||||
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"kind": "DaemonSet",
|
||||
"apiVersion": "extensions/v1beta1",
|
||||
"apiVersion": "apps/v1",
|
||||
"metadata": {
|
||||
"name": "glusterfs",
|
||||
"labels": {
|
||||
@ -69,7 +69,7 @@
|
||||
},
|
||||
"readinessProbe": {
|
||||
"timeoutSeconds": 3,
|
||||
"initialDelaySeconds": 60,
|
||||
"initialDelaySeconds": 3,
|
||||
"exec": {
|
||||
"command": [
|
||||
"/bin/bash",
|
||||
@ -80,7 +80,7 @@
|
||||
},
|
||||
"livenessProbe": {
|
||||
"timeoutSeconds": 3,
|
||||
"initialDelaySeconds": 60,
|
||||
"initialDelaySeconds": 10,
|
||||
"exec": {
|
||||
"command": [
|
||||
"/bin/bash",
|
||||
|
@ -30,7 +30,7 @@
|
||||
},
|
||||
{
|
||||
"kind": "Deployment",
|
||||
"apiVersion": "extensions/v1beta1",
|
||||
"apiVersion": "apps/v1",
|
||||
"metadata": {
|
||||
"name": "deploy-heketi",
|
||||
"labels": {
|
||||
@ -56,7 +56,7 @@
|
||||
"serviceAccountName": "heketi-service-account",
|
||||
"containers": [
|
||||
{
|
||||
"image": "heketi/heketi:7",
|
||||
"image": "heketi/heketi:9",
|
||||
"imagePullPolicy": "Always",
|
||||
"name": "deploy-heketi",
|
||||
"env": [
|
||||
@ -106,7 +106,7 @@
|
||||
},
|
||||
"livenessProbe": {
|
||||
"timeoutSeconds": 3,
|
||||
"initialDelaySeconds": 30,
|
||||
"initialDelaySeconds": 10,
|
||||
"httpGet": {
|
||||
"path": "/hello",
|
||||
"port": 8080
|
||||
|
@ -44,7 +44,7 @@
|
||||
},
|
||||
{
|
||||
"kind": "Deployment",
|
||||
"apiVersion": "extensions/v1beta1",
|
||||
"apiVersion": "apps/v1",
|
||||
"metadata": {
|
||||
"name": "heketi",
|
||||
"labels": {
|
||||
@ -68,7 +68,7 @@
|
||||
"serviceAccountName": "heketi-service-account",
|
||||
"containers": [
|
||||
{
|
||||
"image": "heketi/heketi:7",
|
||||
"image": "heketi/heketi:9",
|
||||
"imagePullPolicy": "Always",
|
||||
"name": "heketi",
|
||||
"env": [
|
||||
@ -122,7 +122,7 @@
|
||||
},
|
||||
"livenessProbe": {
|
||||
"timeoutSeconds": 3,
|
||||
"initialDelaySeconds": 30,
|
||||
"initialDelaySeconds": 10,
|
||||
"httpGet": {
|
||||
"path": "/hello",
|
||||
"port": 8080
|
||||
|
@ -16,7 +16,7 @@
|
||||
{
|
||||
"addresses": [
|
||||
{
|
||||
"ip": "{{ hostvars[node]['ansible_facts']['default_ipv4']['address'] }}"
|
||||
"ip": "{{ hostvars[node].ip }}"
|
||||
}
|
||||
],
|
||||
"ports": [
|
||||
|
@ -12,7 +12,7 @@
|
||||
"{{ node }}"
|
||||
],
|
||||
"storage": [
|
||||
"{{ hostvars[node]['ansible_facts']['default_ipv4']['address'] }}"
|
||||
"{{ hostvars[node].ip }}"
|
||||
]
|
||||
},
|
||||
"zone": 1
|
||||
|
@ -0,0 +1,2 @@
|
||||
---
|
||||
heketi_remove_lvm: false
|
@ -14,6 +14,8 @@
|
||||
when: "ansible_os_family == 'Debian'"
|
||||
|
||||
- name: "Get volume group information."
|
||||
environment:
|
||||
PATH: "{{ ansible_env.PATH }}:/sbin" # Make sure we can workaround RH / CentOS conservative path management
|
||||
become: true
|
||||
shell: "pvs {{ disk_volume_device_1 }} --option vg_name | tail -n+2"
|
||||
register: "volume_groups"
|
||||
@ -21,12 +23,16 @@
|
||||
changed_when: false
|
||||
|
||||
- name: "Remove volume groups."
|
||||
environment:
|
||||
PATH: "{{ ansible_env.PATH }}:/sbin" # Make sure we can workaround RH / CentOS conservative path management
|
||||
become: true
|
||||
command: "vgremove {{ volume_group }} --yes"
|
||||
with_items: "{{ volume_groups.stdout_lines }}"
|
||||
loop_control: { loop_var: "volume_group" }
|
||||
|
||||
- name: "Remove physical volume from cluster disks."
|
||||
environment:
|
||||
PATH: "{{ ansible_env.PATH }}:/sbin" # Make sure we can workaround RH / CentOS conservative path management
|
||||
become: true
|
||||
command: "pvremove {{ disk_volume_device_1 }} --yes"
|
||||
ignore_errors: true
|
||||
@ -36,11 +42,11 @@
|
||||
yum:
|
||||
name: "lvm2"
|
||||
state: "absent"
|
||||
when: "ansible_os_family == 'RedHat'"
|
||||
when: "ansible_os_family == 'RedHat' and heketi_remove_lvm"
|
||||
|
||||
- name: "Remove lvm utils (Debian)"
|
||||
become: true
|
||||
apt:
|
||||
name: "lvm2"
|
||||
state: "absent"
|
||||
when: "ansible_os_family == 'Debian'"
|
||||
when: "ansible_os_family == 'Debian' and heketi_remove_lvm"
|
||||
|
@ -10,7 +10,7 @@ This project will create:
|
||||
* AWS ELB in the Public Subnet for accessing the Kubernetes API from the internet
|
||||
|
||||
**Requirements**
|
||||
- Terraform 0.8.7 or newer
|
||||
- Terraform 0.12.0 or newer
|
||||
|
||||
**How to Use:**
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
terraform {
|
||||
required_version = ">= 0.8.7"
|
||||
required_version = ">= 0.12.0"
|
||||
}
|
||||
|
||||
provider "aws" {
|
||||
@ -16,22 +16,22 @@ data "aws_availability_zones" "available" {}
|
||||
*/
|
||||
|
||||
module "aws-vpc" {
|
||||
source = "modules/vpc"
|
||||
source = "./modules/vpc"
|
||||
|
||||
aws_cluster_name = "${var.aws_cluster_name}"
|
||||
aws_vpc_cidr_block = "${var.aws_vpc_cidr_block}"
|
||||
aws_avail_zones = "${slice(data.aws_availability_zones.available.names,0,2)}"
|
||||
aws_avail_zones = "${slice(data.aws_availability_zones.available.names, 0, 2)}"
|
||||
aws_cidr_subnets_private = "${var.aws_cidr_subnets_private}"
|
||||
aws_cidr_subnets_public = "${var.aws_cidr_subnets_public}"
|
||||
default_tags = "${var.default_tags}"
|
||||
}
|
||||
|
||||
module "aws-elb" {
|
||||
source = "modules/elb"
|
||||
source = "./modules/elb"
|
||||
|
||||
aws_cluster_name = "${var.aws_cluster_name}"
|
||||
aws_vpc_id = "${module.aws-vpc.aws_vpc_id}"
|
||||
aws_avail_zones = "${slice(data.aws_availability_zones.available.names,0,2)}"
|
||||
aws_avail_zones = "${slice(data.aws_availability_zones.available.names, 0, 2)}"
|
||||
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}"
|
||||
@ -39,7 +39,7 @@ module "aws-elb" {
|
||||
}
|
||||
|
||||
module "aws-iam" {
|
||||
source = "modules/iam"
|
||||
source = "./modules/iam"
|
||||
|
||||
aws_cluster_name = "${var.aws_cluster_name}"
|
||||
}
|
||||
@ -54,18 +54,18 @@ resource "aws_instance" "bastion-server" {
|
||||
instance_type = "${var.aws_bastion_size}"
|
||||
count = "${length(var.aws_cidr_subnets_public)}"
|
||||
associate_public_ip_address = true
|
||||
availability_zone = "${element(slice(data.aws_availability_zones.available.names,0,2),count.index)}"
|
||||
subnet_id = "${element(module.aws-vpc.aws_subnet_ids_public,count.index)}"
|
||||
availability_zone = "${element(slice(data.aws_availability_zones.available.names, 0, 2), count.index)}"
|
||||
subnet_id = "${element(module.aws-vpc.aws_subnet_ids_public, count.index)}"
|
||||
|
||||
vpc_security_group_ids = ["${module.aws-vpc.aws_security_group}"]
|
||||
vpc_security_group_ids = "${module.aws-vpc.aws_security_group}"
|
||||
|
||||
key_name = "${var.AWS_SSH_KEY_NAME}"
|
||||
|
||||
tags = "${merge(var.default_tags, map(
|
||||
"Name", "kubernetes-${var.aws_cluster_name}-bastion-${count.index}",
|
||||
"Cluster", "${var.aws_cluster_name}",
|
||||
"Role", "bastion-${var.aws_cluster_name}-${count.index}"
|
||||
))}"
|
||||
"Name", "kubernetes-${var.aws_cluster_name}-bastion-${count.index}",
|
||||
"Cluster", "${var.aws_cluster_name}",
|
||||
"Role", "bastion-${var.aws_cluster_name}-${count.index}"
|
||||
))}"
|
||||
}
|
||||
|
||||
/*
|
||||
@ -79,25 +79,25 @@ resource "aws_instance" "k8s-master" {
|
||||
|
||||
count = "${var.aws_kube_master_num}"
|
||||
|
||||
availability_zone = "${element(slice(data.aws_availability_zones.available.names,0,2),count.index)}"
|
||||
subnet_id = "${element(module.aws-vpc.aws_subnet_ids_private,count.index)}"
|
||||
availability_zone = "${element(slice(data.aws_availability_zones.available.names, 0, 2), count.index)}"
|
||||
subnet_id = "${element(module.aws-vpc.aws_subnet_ids_private, count.index)}"
|
||||
|
||||
vpc_security_group_ids = ["${module.aws-vpc.aws_security_group}"]
|
||||
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 = "${merge(var.default_tags, map(
|
||||
"Name", "kubernetes-${var.aws_cluster_name}-master${count.index}",
|
||||
"kubernetes.io/cluster/${var.aws_cluster_name}", "member",
|
||||
"Role", "master"
|
||||
))}"
|
||||
"Name", "kubernetes-${var.aws_cluster_name}-master${count.index}",
|
||||
"kubernetes.io/cluster/${var.aws_cluster_name}", "member",
|
||||
"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)}"
|
||||
instance = "${element(aws_instance.k8s-master.*.id, count.index)}"
|
||||
}
|
||||
|
||||
resource "aws_instance" "k8s-etcd" {
|
||||
@ -106,18 +106,18 @@ resource "aws_instance" "k8s-etcd" {
|
||||
|
||||
count = "${var.aws_etcd_num}"
|
||||
|
||||
availability_zone = "${element(slice(data.aws_availability_zones.available.names,0,2),count.index)}"
|
||||
subnet_id = "${element(module.aws-vpc.aws_subnet_ids_private,count.index)}"
|
||||
availability_zone = "${element(slice(data.aws_availability_zones.available.names, 0, 2), count.index)}"
|
||||
subnet_id = "${element(module.aws-vpc.aws_subnet_ids_private, count.index)}"
|
||||
|
||||
vpc_security_group_ids = ["${module.aws-vpc.aws_security_group}"]
|
||||
vpc_security_group_ids = "${module.aws-vpc.aws_security_group}"
|
||||
|
||||
key_name = "${var.AWS_SSH_KEY_NAME}"
|
||||
|
||||
tags = "${merge(var.default_tags, map(
|
||||
"Name", "kubernetes-${var.aws_cluster_name}-etcd${count.index}",
|
||||
"kubernetes.io/cluster/${var.aws_cluster_name}", "member",
|
||||
"Role", "etcd"
|
||||
))}"
|
||||
"Name", "kubernetes-${var.aws_cluster_name}-etcd${count.index}",
|
||||
"kubernetes.io/cluster/${var.aws_cluster_name}", "member",
|
||||
"Role", "etcd"
|
||||
))}"
|
||||
}
|
||||
|
||||
resource "aws_instance" "k8s-worker" {
|
||||
@ -126,19 +126,19 @@ resource "aws_instance" "k8s-worker" {
|
||||
|
||||
count = "${var.aws_kube_worker_num}"
|
||||
|
||||
availability_zone = "${element(slice(data.aws_availability_zones.available.names,0,2),count.index)}"
|
||||
subnet_id = "${element(module.aws-vpc.aws_subnet_ids_private,count.index)}"
|
||||
availability_zone = "${element(slice(data.aws_availability_zones.available.names, 0, 2), count.index)}"
|
||||
subnet_id = "${element(module.aws-vpc.aws_subnet_ids_private, count.index)}"
|
||||
|
||||
vpc_security_group_ids = ["${module.aws-vpc.aws_security_group}"]
|
||||
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 = "${merge(var.default_tags, map(
|
||||
"Name", "kubernetes-${var.aws_cluster_name}-worker${count.index}",
|
||||
"kubernetes.io/cluster/${var.aws_cluster_name}", "member",
|
||||
"Role", "worker"
|
||||
))}"
|
||||
"Name", "kubernetes-${var.aws_cluster_name}-worker${count.index}",
|
||||
"kubernetes.io/cluster/${var.aws_cluster_name}", "member",
|
||||
"Role", "worker"
|
||||
))}"
|
||||
}
|
||||
|
||||
/*
|
||||
@ -148,14 +148,14 @@ resource "aws_instance" "k8s-worker" {
|
||||
data "template_file" "inventory" {
|
||||
template = "${file("${path.module}/templates/inventory.tpl")}"
|
||||
|
||||
vars {
|
||||
public_ip_address_bastion = "${join("\n",formatlist("bastion ansible_host=%s" , aws_instance.bastion-server.*.public_ip))}"
|
||||
connection_strings_master = "${join("\n",formatlist("%s ansible_host=%s",aws_instance.k8s-master.*.tags.Name, aws_instance.k8s-master.*.private_ip))}"
|
||||
vars = {
|
||||
public_ip_address_bastion = "${join("\n", formatlist("bastion ansible_host=%s", aws_instance.bastion-server.*.public_ip))}"
|
||||
connection_strings_master = "${join("\n", formatlist("%s ansible_host=%s", aws_instance.k8s-master.*.tags.Name, aws_instance.k8s-master.*.private_ip))}"
|
||||
connection_strings_node = "${join("\n", formatlist("%s ansible_host=%s", aws_instance.k8s-worker.*.tags.Name, aws_instance.k8s-worker.*.private_ip))}"
|
||||
connection_strings_etcd = "${join("\n",formatlist("%s ansible_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)}"
|
||||
connection_strings_etcd = "${join("\n", formatlist("%s ansible_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}\""
|
||||
}
|
||||
}
|
||||
@ -165,7 +165,7 @@ resource "null_resource" "inventories" {
|
||||
command = "echo '${data.template_file.inventory.rendered}' > ${var.inventory_file}"
|
||||
}
|
||||
|
||||
triggers {
|
||||
triggers = {
|
||||
template = "${data.template_file.inventory.rendered}"
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ resource "aws_security_group_rule" "aws-allow-api-egress" {
|
||||
# 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}"]
|
||||
subnets = var.aws_subnet_ids_public
|
||||
security_groups = ["${aws_security_group.aws-elb.id}"]
|
||||
|
||||
listener {
|
||||
|
@ -3,15 +3,15 @@ output "aws_vpc_id" {
|
||||
}
|
||||
|
||||
output "aws_subnet_ids_private" {
|
||||
value = ["${aws_subnet.cluster-vpc-subnets-private.*.id}"]
|
||||
value = aws_subnet.cluster-vpc-subnets-private.*.id
|
||||
}
|
||||
|
||||
output "aws_subnet_ids_public" {
|
||||
value = ["${aws_subnet.cluster-vpc-subnets-public.*.id}"]
|
||||
value = aws_subnet.cluster-vpc-subnets-public.*.id
|
||||
}
|
||||
|
||||
output "aws_security_group" {
|
||||
value = ["${aws_security_group.kubernetes.*.id}"]
|
||||
value = aws_security_group.kubernetes.*.id
|
||||
}
|
||||
|
||||
output "default_tags" {
|
||||
|
53
contrib/terraform/aws/sample-inventory/cluster.tfvars
Normal file
53
contrib/terraform/aws/sample-inventory/cluster.tfvars
Normal file
@ -0,0 +1,53 @@
|
||||
#Global Vars
|
||||
aws_cluster_name = "devtest"
|
||||
|
||||
#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"]
|
||||
|
||||
#Bastion Host
|
||||
aws_bastion_size = "t2.medium"
|
||||
|
||||
#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"
|
||||
|
||||
#Settings AWS ELB
|
||||
|
||||
aws_elb_api_port = 6443
|
||||
|
||||
k8s_secure_api_port = 6443
|
||||
|
||||
kube_insecure_apiserver_address = "0.0.0.0"
|
||||
|
||||
default_tags = {
|
||||
# Env = "devtest" # Product = "kubernetes"
|
||||
}
|
||||
|
||||
inventory_file = "../../../inventory/hosts"
|
||||
|
||||
## Credentials
|
||||
#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"
|
1
contrib/terraform/aws/sample-inventory/group_vars
Symbolic link
1
contrib/terraform/aws/sample-inventory/group_vars
Symbolic link
@ -0,0 +1 @@
|
||||
../../../../inventory/sample/group_vars
|
@ -2,9 +2,9 @@
|
||||
aws_cluster_name = "devtest"
|
||||
|
||||
#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_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"]
|
||||
|
||||
#Bastion Host
|
||||
aws_bastion_size = "t2.medium"
|
||||
@ -12,24 +12,24 @@ aws_bastion_size = "t2.medium"
|
||||
|
||||
#Kubernetes Cluster
|
||||
|
||||
aws_kube_master_num = 3
|
||||
aws_kube_master_num = 3
|
||||
aws_kube_master_size = "t2.medium"
|
||||
|
||||
aws_etcd_num = 3
|
||||
aws_etcd_num = 3
|
||||
aws_etcd_size = "t2.medium"
|
||||
|
||||
aws_kube_worker_num = 4
|
||||
aws_kube_worker_num = 4
|
||||
aws_kube_worker_size = "t2.medium"
|
||||
|
||||
#Settings AWS ELB
|
||||
|
||||
aws_elb_api_port = 6443
|
||||
k8s_secure_api_port = 6443
|
||||
aws_elb_api_port = 6443
|
||||
k8s_secure_api_port = 6443
|
||||
kube_insecure_apiserver_address = "0.0.0.0"
|
||||
|
||||
default_tags = {
|
||||
# Env = "devtest"
|
||||
# Product = "kubernetes"
|
||||
# Env = "devtest"
|
||||
# Product = "kubernetes"
|
||||
}
|
||||
|
||||
inventory_file = "../../../inventory/hosts"
|
||||
|
1
contrib/terraform/openstack/.gitignore
vendored
1
contrib/terraform/openstack/.gitignore
vendored
@ -1,4 +1,5 @@
|
||||
.terraform
|
||||
*.tfvars
|
||||
!sample-inventory\/cluster.tfvars
|
||||
*.tfstate
|
||||
*.tfstate.backup
|
||||
|
@ -16,14 +16,13 @@ most modern installs of OpenStack that support the basic services.
|
||||
- [ELASTX](https://elastx.se/)
|
||||
- [EnterCloudSuite](https://www.entercloudsuite.com/)
|
||||
- [FugaCloud](https://fuga.cloud/)
|
||||
- [Open Telekom Cloud](https://cloud.telekom.de/) : requires to set the variable `wait_for_floatingip = "true"` in your cluster.tfvars
|
||||
- [OVH](https://www.ovh.com/)
|
||||
- [Rackspace](https://www.rackspace.com/)
|
||||
- [Ultimum](https://ultimum.io/)
|
||||
- [VexxHost](https://vexxhost.com/)
|
||||
- [Zetta](https://www.zetta.io/)
|
||||
|
||||
### Known incompatible public clouds
|
||||
- T-Systems / Open Telekom Cloud: requires `wait_until_associated`
|
||||
|
||||
## Approach
|
||||
The terraform configuration inspects variables found in
|
||||
@ -70,7 +69,7 @@ binaries available on hyperkube v1.4.3_coreos.0 or higher.
|
||||
|
||||
## Requirements
|
||||
|
||||
- [Install Terraform](https://www.terraform.io/intro/getting-started/install.html)
|
||||
- [Install Terraform](https://www.terraform.io/intro/getting-started/install.html) 0.12 or later
|
||||
- [Install Ansible](http://docs.ansible.com/ansible/latest/intro_installation.html)
|
||||
- you already have a suitable OS image in Glance
|
||||
- you already have a floating IP pool created
|
||||
@ -220,12 +219,14 @@ set OS_PROJECT_DOMAIN_NAME=Default
|
||||
The construction of the cluster is driven by values found in
|
||||
[variables.tf](variables.tf).
|
||||
|
||||
For your cluster, edit `inventory/$CLUSTER/cluster.tf`.
|
||||
For your cluster, edit `inventory/$CLUSTER/cluster.tfvars`.
|
||||
|
||||
|Variable | Description |
|
||||
|---------|-------------|
|
||||
|`cluster_name` | All OpenStack resources will use the Terraform variable`cluster_name` (default`example`) in their name to make it easier to track. For example the first compute resource will be named`example-kubernetes-1`. |
|
||||
|`az_list` | List of Availability Zones available in your OpenStack cluster. |
|
||||
|`network_name` | The name to be given to the internal network that will be generated |
|
||||
|`network_dns_domain` | (Optional) The dns_domain for the internal network that will be generated |
|
||||
|`dns_nameservers`| An array of DNS name server names to be used by hosts in the internal subnet. |
|
||||
|`floatingip_pool` | Name of the pool from which floating IPs will be allocated |
|
||||
|`external_net` | UUID of the external network that will be routed to |
|
||||
@ -243,7 +244,16 @@ For your cluster, edit `inventory/$CLUSTER/cluster.tf`.
|
||||
|`supplementary_master_groups` | To add ansible groups to the masters, such as `kube-node` for tainting them as nodes, empty by default. |
|
||||
|`supplementary_node_groups` | To add ansible groups to the nodes, such as `kube-ingress` for running ingress controller pods, empty by default. |
|
||||
|`bastion_allowed_remote_ips` | List of CIDR allowed to initiate a SSH connection, `["0.0.0.0/0"]` by default |
|
||||
|`master_allowed_remote_ips` | List of CIDR blocks allowed to initiate an API connection, `["0.0.0.0/0"]` by default |
|
||||
|`k8s_allowed_remote_ips` | List of CIDR allowed to initiate a SSH connection, empty by default |
|
||||
|`worker_allowed_ports` | List of ports to open on worker nodes, `[{ "protocol" = "tcp", "port_range_min" = 30000, "port_range_max" = 32767, "remote_ip_prefix" = "0.0.0.0/0"}]` by default |
|
||||
|`wait_for_floatingip` | Let Terraform poll the instance until the floating IP has been associated, `false` by default. |
|
||||
|`node_root_volume_size_in_gb` | Size of the root volume for nodes, 0 to use ephemeral storage |
|
||||
|`master_root_volume_size_in_gb` | Size of the root volume for masters, 0 to use ephemeral storage |
|
||||
|`gfs_root_volume_size_in_gb` | Size of the root volume for gluster, 0 to use ephemeral storage |
|
||||
|`etcd_root_volume_size_in_gb` | Size of the root volume for etcd nodes, 0 to use ephemeral storage |
|
||||
|`bastion_root_volume_size_in_gb` | Size of the root volume for bastions, 0 to use ephemeral storage |
|
||||
|`use_server_group` | Create and use openstack nova servergroups, default: false |
|
||||
|
||||
#### Terraform state files
|
||||
|
||||
@ -274,7 +284,7 @@ This should finish fairly quickly telling you Terraform has successfully initial
|
||||
You can apply the Terraform configuration to your cluster with the following command
|
||||
issued from your cluster's inventory directory (`inventory/$CLUSTER`):
|
||||
```ShellSession
|
||||
$ terraform apply -var-file=cluster.tf ../../contrib/terraform/openstack
|
||||
$ terraform apply -var-file=cluster.tfvars ../../contrib/terraform/openstack
|
||||
```
|
||||
|
||||
if you chose to create a bastion host, this script will create
|
||||
@ -288,7 +298,7 @@ pick it up automatically.
|
||||
You can destroy your new cluster with the following command issued from the cluster's inventory directory:
|
||||
|
||||
```ShellSession
|
||||
$ terraform destroy -var-file=cluster.tf ../../contrib/terraform/openstack
|
||||
$ terraform destroy -var-file=cluster.tfvars ../../contrib/terraform/openstack
|
||||
```
|
||||
|
||||
If you've started the Ansible run, it may also be a good idea to do some manual cleanup:
|
||||
@ -323,6 +333,30 @@ $ ssh-add ~/.ssh/id_rsa
|
||||
|
||||
If you have deployed and destroyed a previous iteration of your cluster, you will need to clear out any stale keys from your SSH "known hosts" file ( `~/.ssh/known_hosts`).
|
||||
|
||||
#### Metadata variables
|
||||
|
||||
The [python script](../terraform.py) that reads the
|
||||
generated`.tfstate` file to generate a dynamic inventory recognizes
|
||||
some variables within a "metadata" block, defined in a "resource"
|
||||
block (example):
|
||||
|
||||
```
|
||||
resource "openstack_compute_instance_v2" "example" {
|
||||
...
|
||||
metadata {
|
||||
ssh_user = "ubuntu"
|
||||
prefer_ipv6 = true
|
||||
python_bin = "/usr/bin/python3"
|
||||
}
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
As the example shows, these let you define the SSH username for
|
||||
Ansible, a Python binary which is needed by Ansible if
|
||||
`/usr/bin/python` doesn't exist, and whether the IPv6 address of the
|
||||
instance should be preferred over IPv4.
|
||||
|
||||
#### Bastion host
|
||||
|
||||
Bastion access will be determined by:
|
||||
@ -389,6 +423,14 @@ kube_network_plugin: flannel
|
||||
# For Container Linux by CoreOS:
|
||||
resolvconf_mode: host_resolvconf
|
||||
```
|
||||
- Set max amount of attached cinder volume per host (default 256)
|
||||
```
|
||||
node_volume_attach_limit: 26
|
||||
```
|
||||
- Disable access_ip, this will make all innternal cluster traffic to be sent over local network when a floating IP is attached (default this value is set to 1)
|
||||
```
|
||||
use_access_ip: 0
|
||||
```
|
||||
|
||||
### Deploy Kubernetes
|
||||
|
||||
|
@ -1,16 +1,21 @@
|
||||
module "network" {
|
||||
source = "modules/network"
|
||||
provider "openstack" {
|
||||
version = "~> 1.17"
|
||||
}
|
||||
|
||||
external_net = "${var.external_net}"
|
||||
network_name = "${var.network_name}"
|
||||
subnet_cidr = "${var.subnet_cidr}"
|
||||
cluster_name = "${var.cluster_name}"
|
||||
dns_nameservers = "${var.dns_nameservers}"
|
||||
use_neutron = "${var.use_neutron}"
|
||||
module "network" {
|
||||
source = "./modules/network"
|
||||
|
||||
external_net = "${var.external_net}"
|
||||
network_name = "${var.network_name}"
|
||||
subnet_cidr = "${var.subnet_cidr}"
|
||||
cluster_name = "${var.cluster_name}"
|
||||
dns_nameservers = "${var.dns_nameservers}"
|
||||
network_dns_domain = "${var.network_dns_domain}"
|
||||
use_neutron = "${var.use_neutron}"
|
||||
}
|
||||
|
||||
module "ips" {
|
||||
source = "modules/ips"
|
||||
source = "./modules/ips"
|
||||
|
||||
number_of_k8s_masters = "${var.number_of_k8s_masters}"
|
||||
number_of_k8s_masters_no_etcd = "${var.number_of_k8s_masters_no_etcd}"
|
||||
@ -23,7 +28,7 @@ module "ips" {
|
||||
}
|
||||
|
||||
module "compute" {
|
||||
source = "modules/compute"
|
||||
source = "./modules/compute"
|
||||
|
||||
cluster_name = "${var.cluster_name}"
|
||||
az_list = "${var.az_list}"
|
||||
@ -36,6 +41,11 @@ module "compute" {
|
||||
number_of_bastions = "${var.number_of_bastions}"
|
||||
number_of_k8s_nodes_no_floating_ip = "${var.number_of_k8s_nodes_no_floating_ip}"
|
||||
number_of_gfs_nodes_no_floating_ip = "${var.number_of_gfs_nodes_no_floating_ip}"
|
||||
bastion_root_volume_size_in_gb = "${var.bastion_root_volume_size_in_gb}"
|
||||
etcd_root_volume_size_in_gb = "${var.etcd_root_volume_size_in_gb}"
|
||||
master_root_volume_size_in_gb = "${var.master_root_volume_size_in_gb}"
|
||||
node_root_volume_size_in_gb = "${var.node_root_volume_size_in_gb}"
|
||||
gfs_root_volume_size_in_gb = "${var.gfs_root_volume_size_in_gb}"
|
||||
gfs_volume_size_in_gb = "${var.gfs_volume_size_in_gb}"
|
||||
public_key_path = "${var.public_key_path}"
|
||||
image = "${var.image}"
|
||||
@ -49,12 +59,19 @@ module "compute" {
|
||||
network_name = "${var.network_name}"
|
||||
flavor_bastion = "${var.flavor_bastion}"
|
||||
k8s_master_fips = "${module.ips.k8s_master_fips}"
|
||||
k8s_master_no_etcd_fips = "${module.ips.k8s_master_no_etcd_fips}"
|
||||
k8s_node_fips = "${module.ips.k8s_node_fips}"
|
||||
bastion_fips = "${module.ips.bastion_fips}"
|
||||
bastion_allowed_remote_ips = "${var.bastion_allowed_remote_ips}"
|
||||
master_allowed_remote_ips = "${var.master_allowed_remote_ips}"
|
||||
k8s_allowed_remote_ips = "${var.k8s_allowed_remote_ips}"
|
||||
k8s_allowed_egress_ips = "${var.k8s_allowed_egress_ips}"
|
||||
supplementary_master_groups = "${var.supplementary_master_groups}"
|
||||
supplementary_node_groups = "${var.supplementary_node_groups}"
|
||||
worker_allowed_ports = "${var.worker_allowed_ports}"
|
||||
wait_for_floatingip = "${var.wait_for_floatingip}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
use_server_groups = "${var.use_server_groups}"
|
||||
|
||||
network_id = "${module.network.router_id}"
|
||||
}
|
||||
@ -72,7 +89,7 @@ output "router_id" {
|
||||
}
|
||||
|
||||
output "k8s_master_fips" {
|
||||
value = "${module.ips.k8s_master_fips}"
|
||||
value = "${concat(module.ips.k8s_master_fips, module.ips.k8s_master_no_etcd_fips)}"
|
||||
}
|
||||
|
||||
output "k8s_node_fips" {
|
||||
|
@ -1,43 +1,55 @@
|
||||
data "openstack_images_image_v2" "vm_image" {
|
||||
name = "${var.image}"
|
||||
}
|
||||
|
||||
data "openstack_images_image_v2" "gfs_image" {
|
||||
name = "${var.image_gfs == "" ? var.image : var.image_gfs}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_keypair_v2" "k8s" {
|
||||
name = "kubernetes-${var.cluster_name}"
|
||||
public_key = "${chomp(file(var.public_key_path))}"
|
||||
}
|
||||
|
||||
resource "openstack_networking_secgroup_v2" "k8s_master" {
|
||||
name = "${var.cluster_name}-k8s-master"
|
||||
description = "${var.cluster_name} - Kubernetes Master"
|
||||
name = "${var.cluster_name}-k8s-master"
|
||||
description = "${var.cluster_name} - Kubernetes Master"
|
||||
delete_default_rules = true
|
||||
}
|
||||
|
||||
resource "openstack_networking_secgroup_rule_v2" "k8s_master" {
|
||||
count = "${length(var.master_allowed_remote_ips)}"
|
||||
direction = "ingress"
|
||||
ethertype = "IPv4"
|
||||
protocol = "tcp"
|
||||
port_range_min = "6443"
|
||||
port_range_max = "6443"
|
||||
remote_ip_prefix = "0.0.0.0/0"
|
||||
remote_ip_prefix = "${var.master_allowed_remote_ips[count.index]}"
|
||||
security_group_id = "${openstack_networking_secgroup_v2.k8s_master.id}"
|
||||
}
|
||||
|
||||
resource "openstack_networking_secgroup_v2" "bastion" {
|
||||
name = "${var.cluster_name}-bastion"
|
||||
count = "${var.number_of_bastions ? 1 : 0}"
|
||||
description = "${var.cluster_name} - Bastion Server"
|
||||
name = "${var.cluster_name}-bastion"
|
||||
count = "${var.number_of_bastions != "" ? 1 : 0}"
|
||||
description = "${var.cluster_name} - Bastion Server"
|
||||
delete_default_rules = true
|
||||
}
|
||||
|
||||
resource "openstack_networking_secgroup_rule_v2" "bastion" {
|
||||
count = "${var.number_of_bastions ? length(var.bastion_allowed_remote_ips) : 0}"
|
||||
count = "${var.number_of_bastions != "" ? length(var.bastion_allowed_remote_ips) : 0}"
|
||||
direction = "ingress"
|
||||
ethertype = "IPv4"
|
||||
protocol = "tcp"
|
||||
port_range_min = "22"
|
||||
port_range_max = "22"
|
||||
remote_ip_prefix = "${var.bastion_allowed_remote_ips[count.index]}"
|
||||
security_group_id = "${openstack_networking_secgroup_v2.bastion.id}"
|
||||
security_group_id = "${openstack_networking_secgroup_v2.bastion[count.index].id}"
|
||||
}
|
||||
|
||||
resource "openstack_networking_secgroup_v2" "k8s" {
|
||||
name = "${var.cluster_name}-k8s"
|
||||
description = "${var.cluster_name} - Kubernetes"
|
||||
name = "${var.cluster_name}-k8s"
|
||||
description = "${var.cluster_name} - Kubernetes"
|
||||
delete_default_rules = true
|
||||
}
|
||||
|
||||
resource "openstack_networking_secgroup_rule_v2" "k8s" {
|
||||
@ -47,9 +59,29 @@ resource "openstack_networking_secgroup_rule_v2" "k8s" {
|
||||
security_group_id = "${openstack_networking_secgroup_v2.k8s.id}"
|
||||
}
|
||||
|
||||
resource "openstack_networking_secgroup_rule_v2" "k8s_allowed_remote_ips" {
|
||||
count = "${length(var.k8s_allowed_remote_ips)}"
|
||||
direction = "ingress"
|
||||
ethertype = "IPv4"
|
||||
protocol = "tcp"
|
||||
port_range_min = "22"
|
||||
port_range_max = "22"
|
||||
remote_ip_prefix = "${var.k8s_allowed_remote_ips[count.index]}"
|
||||
security_group_id = "${openstack_networking_secgroup_v2.k8s.id}"
|
||||
}
|
||||
|
||||
resource "openstack_networking_secgroup_rule_v2" "egress" {
|
||||
count = "${length(var.k8s_allowed_egress_ips)}"
|
||||
direction = "egress"
|
||||
ethertype = "IPv4"
|
||||
remote_ip_prefix = "${var.k8s_allowed_egress_ips[count.index]}"
|
||||
security_group_id = "${openstack_networking_secgroup_v2.k8s.id}"
|
||||
}
|
||||
|
||||
resource "openstack_networking_secgroup_v2" "worker" {
|
||||
name = "${var.cluster_name}-k8s-worker"
|
||||
description = "${var.cluster_name} - Kubernetes worker nodes"
|
||||
name = "${var.cluster_name}-k8s-worker"
|
||||
description = "${var.cluster_name} - Kubernetes worker nodes"
|
||||
delete_default_rules = true
|
||||
}
|
||||
|
||||
resource "openstack_networking_secgroup_rule_v2" "worker" {
|
||||
@ -63,9 +95,27 @@ resource "openstack_networking_secgroup_rule_v2" "worker" {
|
||||
security_group_id = "${openstack_networking_secgroup_v2.worker.id}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_servergroup_v2" "k8s_master" {
|
||||
count = "%{ if var.use_server_groups }1%{else}0%{endif}"
|
||||
name = "k8s-master-srvgrp"
|
||||
policies = ["anti-affinity"]
|
||||
}
|
||||
|
||||
resource "openstack_compute_servergroup_v2" "k8s_node" {
|
||||
count = "%{ if var.use_server_groups }1%{else}0%{endif}"
|
||||
name = "k8s-node-srvgrp"
|
||||
policies = ["anti-affinity"]
|
||||
}
|
||||
|
||||
resource "openstack_compute_servergroup_v2" "k8s_etcd" {
|
||||
count = "%{ if var.use_server_groups }1%{else}0%{endif}"
|
||||
name = "k8s-etcd-srvgrp"
|
||||
policies = ["anti-affinity"]
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "bastion" {
|
||||
name = "${var.cluster_name}-bastion-${count.index+1}"
|
||||
count = "${var.number_of_bastions}"
|
||||
count = "${var.bastion_root_volume_size_in_gb == 0 ? var.number_of_bastions : 0}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_bastion}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
@ -75,24 +125,60 @@ resource "openstack_compute_instance_v2" "bastion" {
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}",
|
||||
"${openstack_networking_secgroup_v2.bastion.name}",
|
||||
"default",
|
||||
"${element(openstack_networking_secgroup_v2.bastion.*.name, count.index)}",
|
||||
]
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "bastion"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${var.bastion_fips[0]}/ > contrib/terraform/group_vars/no-floating.yml"
|
||||
command = "sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${var.bastion_fips[0]}/ > group_vars/no-floating.yml"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "bastion_custom_volume_size" {
|
||||
name = "${var.cluster_name}-bastion-${count.index+1}"
|
||||
count = "${var.bastion_root_volume_size_in_gb > 0 ? var.number_of_bastions : 0}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_bastion}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
block_device {
|
||||
uuid = "${data.openstack_images_image_v2.vm_image.id}"
|
||||
source_type = "image"
|
||||
volume_size = "${var.bastion_root_volume_size_in_gb}"
|
||||
boot_index = 0
|
||||
destination_type = "volume"
|
||||
delete_on_termination = true
|
||||
}
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}",
|
||||
"${element(openstack_networking_secgroup_v2.bastion.*.name, count.index)}",
|
||||
]
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "bastion"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${var.bastion_fips[0]}/ > group_vars/no-floating.yml"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_master" {
|
||||
name = "${var.cluster_name}-k8s-master-${count.index+1}"
|
||||
count = "${var.number_of_k8s_masters}"
|
||||
count = "${var.master_root_volume_size_in_gb == 0 ? var.number_of_k8s_masters : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
@ -102,28 +188,76 @@ resource "openstack_compute_instance_v2" "k8s_master" {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
# The join() hack is described here: https://github.com/hashicorp/terraform/issues/11566
|
||||
# As a workaround for creating "dynamic" lists (when, for example, no bastion host is created)
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_networking_secgroup_v2.k8s.name}",
|
||||
]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_master[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
security_groups = ["${compact(list(
|
||||
openstack_networking_secgroup_v2.k8s_master.name,
|
||||
join(" ", openstack_networking_secgroup_v2.bastion.*.id),
|
||||
openstack_networking_secgroup_v2.k8s.name,
|
||||
"default",
|
||||
))}"]
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,kube-master,${var.supplementary_master_groups},k8s-cluster,vault"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element( concat(var.bastion_fips, var.k8s_master_fips), 0)}/ > contrib/terraform/group_vars/no-floating.yml"
|
||||
command = "sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element( concat(var.bastion_fips, var.k8s_master_fips), 0)}/ > group_vars/no-floating.yml"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_master_custom_volume_size" {
|
||||
name = "${var.cluster_name}-k8s-master-${count.index+1}"
|
||||
count = "${var.master_root_volume_size_in_gb > 0 ? var.number_of_k8s_masters : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
block_device {
|
||||
uuid = "${data.openstack_images_image_v2.vm_image.id}"
|
||||
source_type = "image"
|
||||
volume_size = "${var.master_root_volume_size_in_gb}"
|
||||
boot_index = 0
|
||||
destination_type = "volume"
|
||||
delete_on_termination = true
|
||||
}
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_networking_secgroup_v2.k8s.name}",
|
||||
]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_master[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,kube-master,${var.supplementary_master_groups},k8s-cluster,vault"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element( concat(var.bastion_fips, var.k8s_master_fips), 0)}/ > group_vars/no-floating.yml"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_master_no_etcd" {
|
||||
name = "${var.cluster_name}-k8s-master-ne-${count.index+1}"
|
||||
count = "${var.number_of_k8s_masters_no_etcd}"
|
||||
count = "${var.master_root_volume_size_in_gb == 0 ? var.number_of_k8s_masters_no_etcd : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
@ -133,26 +267,76 @@ resource "openstack_compute_instance_v2" "k8s_master_no_etcd" {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${compact(list(
|
||||
openstack_networking_secgroup_v2.k8s_master.name,
|
||||
join(" ", openstack_networking_secgroup_v2.bastion.*.id),
|
||||
openstack_networking_secgroup_v2.k8s.name,
|
||||
))}"]
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_networking_secgroup_v2.k8s.name}",
|
||||
]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_master[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-master,${var.supplementary_master_groups},k8s-cluster,vault"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element( concat(var.bastion_fips, var.k8s_master_fips), 0)}/ > contrib/terraform/group_vars/no-floating.yml"
|
||||
command = "sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element( concat(var.bastion_fips, var.k8s_master_fips), 0)}/ > group_vars/no-floating.yml"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_master_no_etcd_custom_volume_size" {
|
||||
name = "${var.cluster_name}-k8s-master-ne-${count.index+1}"
|
||||
count = "${var.master_root_volume_size_in_gb > 0 ? var.number_of_k8s_masters_no_etcd : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
block_device {
|
||||
uuid = "${data.openstack_images_image_v2.vm_image.id}"
|
||||
source_type = "image"
|
||||
volume_size = "${var.master_root_volume_size_in_gb}"
|
||||
boot_index = 0
|
||||
destination_type = "volume"
|
||||
delete_on_termination = true
|
||||
}
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_networking_secgroup_v2.k8s.name}",
|
||||
]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_master[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-master,${var.supplementary_master_groups},k8s-cluster,vault"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element( concat(var.bastion_fips, var.k8s_master_fips), 0)}/ > group_vars/no-floating.yml"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "etcd" {
|
||||
name = "${var.cluster_name}-etcd-${count.index+1}"
|
||||
count = "${var.number_of_etcd}"
|
||||
count = "${var.etcd_root_volume_size_in_gb == 0 ? var.number_of_etcd : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_etcd}"
|
||||
@ -164,16 +348,62 @@ resource "openstack_compute_instance_v2" "etcd" {
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}"]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_etcd[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_etcd[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,vault,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "etcd_custom_volume_size" {
|
||||
name = "${var.cluster_name}-etcd-${count.index+1}"
|
||||
count = "${var.etcd_root_volume_size_in_gb > 0 ? var.number_of_etcd : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_etcd}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
block_device {
|
||||
uuid = "${data.openstack_images_image_v2.vm_image.id}"
|
||||
source_type = "image"
|
||||
volume_size = "${var.etcd_root_volume_size_in_gb}"
|
||||
boot_index = 0
|
||||
destination_type = "volume"
|
||||
delete_on_termination = true
|
||||
}
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}"]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_etcd[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_etcd[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,vault,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip" {
|
||||
name = "${var.cluster_name}-k8s-master-nf-${count.index+1}"
|
||||
count = "${var.number_of_k8s_masters_no_floating_ip}"
|
||||
count = "${var.master_root_volume_size_in_gb == 0 ? var.number_of_k8s_masters_no_floating_ip : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
@ -185,19 +415,66 @@ resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip" {
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_networking_secgroup_v2.k8s.name}",
|
||||
"default",
|
||||
]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_master[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,kube-master,${var.supplementary_master_groups},k8s-cluster,vault,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip_custom_volume_size" {
|
||||
name = "${var.cluster_name}-k8s-master-nf-${count.index+1}"
|
||||
count = "${var.master_root_volume_size_in_gb > 0 ? var.number_of_k8s_masters_no_floating_ip : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
block_device {
|
||||
uuid = "${data.openstack_images_image_v2.vm_image.id}"
|
||||
source_type = "image"
|
||||
volume_size = "${var.master_root_volume_size_in_gb}"
|
||||
boot_index = 0
|
||||
destination_type = "volume"
|
||||
delete_on_termination = true
|
||||
}
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_networking_secgroup_v2.k8s.name}",
|
||||
]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_master[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "etcd,kube-master,${var.supplementary_master_groups},k8s-cluster,vault,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip_no_etcd" {
|
||||
name = "${var.cluster_name}-k8s-master-ne-nf-${count.index+1}"
|
||||
count = "${var.number_of_k8s_masters_no_floating_ip_no_etcd}"
|
||||
count = "${var.master_root_volume_size_in_gb == 0 ? var.number_of_k8s_masters_no_floating_ip_no_etcd : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
@ -210,47 +487,65 @@ resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip_no_etcd" {
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_networking_secgroup_v2.k8s.name}",
|
||||
]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_master[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-master,${var.supplementary_master_groups},k8s-cluster,vault,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_node" {
|
||||
name = "${var.cluster_name}-k8s-node-${count.index+1}"
|
||||
count = "${var.number_of_k8s_nodes}"
|
||||
resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip_no_etcd_custom_volume_size" {
|
||||
name = "${var.cluster_name}-k8s-master-ne-nf-${count.index+1}"
|
||||
count = "${var.master_root_volume_size_in_gb > 0 ? var.number_of_k8s_masters_no_floating_ip_no_etcd : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_node}"
|
||||
flavor_id = "${var.flavor_k8s_master}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
block_device {
|
||||
uuid = "${data.openstack_images_image_v2.vm_image.id}"
|
||||
source_type = "image"
|
||||
volume_size = "${var.master_root_volume_size_in_gb}"
|
||||
boot_index = 0
|
||||
destination_type = "volume"
|
||||
delete_on_termination = true
|
||||
}
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${compact(list(
|
||||
openstack_networking_secgroup_v2.k8s_master.name,
|
||||
join(" ", openstack_networking_secgroup_v2.bastion.*.id),
|
||||
openstack_networking_secgroup_v2.k8s.name,
|
||||
"default",
|
||||
))}"]
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s_master.name}",
|
||||
"${openstack_networking_secgroup_v2.k8s.name}",
|
||||
]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_master[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-node,k8s-cluster,${var.supplementary_node_groups}"
|
||||
kubespray_groups = "kube-master,${var.supplementary_master_groups},k8s-cluster,vault,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element( concat(var.bastion_fips, var.k8s_node_fips), 0)}/ > contrib/terraform/group_vars/no-floating.yml"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_node_no_floating_ip" {
|
||||
name = "${var.cluster_name}-k8s-node-nf-${count.index+1}"
|
||||
count = "${var.number_of_k8s_nodes_no_floating_ip}"
|
||||
resource "openstack_compute_instance_v2" "k8s_node" {
|
||||
name = "${var.cluster_name}-k8s-node-${count.index+1}"
|
||||
count = "${var.node_root_volume_size_in_gb == 0 ? var.number_of_k8s_nodes : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_node}"
|
||||
@ -262,44 +557,213 @@ resource "openstack_compute_instance_v2" "k8s_node_no_floating_ip" {
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}",
|
||||
"${openstack_networking_secgroup_v2.worker.name}",
|
||||
"default",
|
||||
]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_node[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_node[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-node,k8s-cluster,${var.supplementary_node_groups}"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element( concat(var.bastion_fips, var.k8s_node_fips), 0)}/ > group_vars/no-floating.yml"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_node_custom_volume_size" {
|
||||
name = "${var.cluster_name}-k8s-node-${count.index+1}"
|
||||
count = "${var.node_root_volume_size_in_gb > 0 ? var.number_of_k8s_nodes : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_node}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
block_device {
|
||||
uuid = "${data.openstack_images_image_v2.vm_image.id}"
|
||||
source_type = "image"
|
||||
volume_size = "${var.node_root_volume_size_in_gb}"
|
||||
boot_index = 0
|
||||
destination_type = "volume"
|
||||
delete_on_termination = true
|
||||
}
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}",
|
||||
"${openstack_networking_secgroup_v2.worker.name}",
|
||||
]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_node[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_node[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-node,k8s-cluster,${var.supplementary_node_groups}"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
|
||||
provisioner "local-exec" {
|
||||
command = "sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element( concat(var.bastion_fips, var.k8s_node_fips), 0)}/ > group_vars/no-floating.yml"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_node_no_floating_ip" {
|
||||
name = "${var.cluster_name}-k8s-node-nf-${count.index+1}"
|
||||
count = "${var.node_root_volume_size_in_gb == 0 ? var.number_of_k8s_nodes_no_floating_ip : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_node}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}",
|
||||
"${openstack_networking_secgroup_v2.worker.name}",
|
||||
]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_node[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_node[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-node,k8s-cluster,no-floating,${var.supplementary_node_groups}"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "k8s_node_no_floating_ip_custom_volume_size" {
|
||||
name = "${var.cluster_name}-k8s-node-nf-${count.index+1}"
|
||||
count = "${var.node_root_volume_size_in_gb > 0 ? var.number_of_k8s_nodes_no_floating_ip : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_k8s_node}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
block_device {
|
||||
uuid = "${data.openstack_images_image_v2.vm_image.id}"
|
||||
source_type = "image"
|
||||
volume_size = "${var.node_root_volume_size_in_gb}"
|
||||
boot_index = 0
|
||||
destination_type = "volume"
|
||||
delete_on_termination = true
|
||||
}
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}",
|
||||
"${openstack_networking_secgroup_v2.worker.name}",
|
||||
]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_node[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_node[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user}"
|
||||
kubespray_groups = "kube-node,k8s-cluster,no-floating,${var.supplementary_node_groups}"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_floatingip_associate_v2" "bastion" {
|
||||
count = "${var.number_of_bastions}"
|
||||
floating_ip = "${var.bastion_fips[count.index]}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.bastion.*.id, count.index)}"
|
||||
count = "${var.bastion_root_volume_size_in_gb == 0 ? var.number_of_bastions : 0}"
|
||||
floating_ip = "${var.bastion_fips[count.index]}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.bastion.*.id, count.index)}"
|
||||
wait_until_associated = "${var.wait_for_floatingip}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_floatingip_associate_v2" "bastion_custom_volume_size" {
|
||||
count = "${var.bastion_root_volume_size_in_gb > 0 ? var.number_of_bastions : 0}"
|
||||
floating_ip = "${var.bastion_fips[count.index]}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.bastion_custom_volume_size.*.id, count.index)}"
|
||||
wait_until_associated = "${var.wait_for_floatingip}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_floatingip_associate_v2" "k8s_master" {
|
||||
count = "${var.number_of_k8s_masters}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.k8s_master.*.id, count.index)}"
|
||||
floating_ip = "${var.k8s_master_fips[count.index]}"
|
||||
count = "${var.master_root_volume_size_in_gb == 0 ? var.number_of_k8s_masters : 0}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.k8s_master.*.id, count.index)}"
|
||||
floating_ip = "${var.k8s_master_fips[count.index]}"
|
||||
wait_until_associated = "${var.wait_for_floatingip}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_floatingip_associate_v2" "k8s_master_custom_volume_size" {
|
||||
count = "${var.master_root_volume_size_in_gb > 0 ? var.number_of_k8s_masters : 0}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.k8s_master_custom_volume_size.*.id, count.index)}"
|
||||
floating_ip = "${var.k8s_master_fips[count.index]}"
|
||||
wait_until_associated = "${var.wait_for_floatingip}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_floatingip_associate_v2" "k8s_master_no_etcd" {
|
||||
count = "${var.master_root_volume_size_in_gb == 0 ? var.number_of_k8s_masters_no_etcd : 0}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.k8s_master_no_etcd.*.id, count.index)}"
|
||||
floating_ip = "${var.k8s_master_no_etcd_fips[count.index]}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_floatingip_associate_v2" "k8s_master_no_etcd_custom_volume_size" {
|
||||
count = "${var.master_root_volume_size_in_gb > 0 ? var.number_of_k8s_masters_no_etcd : 0}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.k8s_master_no_etcd_custom_volume_size.*.id, count.index)}"
|
||||
floating_ip = "${var.k8s_master_no_etcd_fips[count.index]}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_floatingip_associate_v2" "k8s_node" {
|
||||
count = "${var.number_of_k8s_nodes}"
|
||||
floating_ip = "${var.k8s_node_fips[count.index]}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.k8s_node.*.id, count.index)}"
|
||||
count = "${var.node_root_volume_size_in_gb == 0 ? var.number_of_k8s_nodes : 0}"
|
||||
floating_ip = "${var.k8s_node_fips[count.index]}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.k8s_node.*.id, count.index)}"
|
||||
wait_until_associated = "${var.wait_for_floatingip}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_floatingip_associate_v2" "k8s_node_custom_volume_size" {
|
||||
count = "${var.node_root_volume_size_in_gb > 0 ? var.number_of_k8s_nodes : 0}"
|
||||
floating_ip = "${var.k8s_node_fips[count.index]}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.k8s_node_custom_volume_size.*.id, count.index)}"
|
||||
wait_until_associated = "${var.wait_for_floatingip}"
|
||||
}
|
||||
|
||||
resource "openstack_blockstorage_volume_v2" "glusterfs_volume" {
|
||||
name = "${var.cluster_name}-glusterfs_volume-${count.index+1}"
|
||||
count = "${var.number_of_gfs_nodes_no_floating_ip}"
|
||||
count = "${var.gfs_root_volume_size_in_gb == 0 ? var.number_of_gfs_nodes_no_floating_ip : 0}"
|
||||
description = "Non-ephemeral volume for GlusterFS"
|
||||
size = "${var.gfs_volume_size_in_gb}"
|
||||
}
|
||||
|
||||
resource "openstack_blockstorage_volume_v2" "glusterfs_volume_custom_volume_size" {
|
||||
name = "${var.cluster_name}-glusterfs_volume-${count.index+1}"
|
||||
count = "${var.gfs_root_volume_size_in_gb > 0 ? var.number_of_gfs_nodes_no_floating_ip : 0}"
|
||||
description = "Non-ephemeral volume for GlusterFS"
|
||||
size = "${var.gfs_volume_size_in_gb}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "glusterfs_node_no_floating_ip" {
|
||||
name = "${var.cluster_name}-gfs-node-nf-${count.index+1}"
|
||||
count = "${var.number_of_gfs_nodes_no_floating_ip}"
|
||||
count = "${var.gfs_root_volume_size_in_gb == 0 ? var.number_of_gfs_nodes_no_floating_ip : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image_gfs}"
|
||||
flavor_id = "${var.flavor_gfs_node}"
|
||||
@ -309,19 +773,69 @@ resource "openstack_compute_instance_v2" "glusterfs_node_no_floating_ip" {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}",
|
||||
"default",
|
||||
]
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}"]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_node[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_node[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user_gfs}"
|
||||
kubespray_groups = "gfs-cluster,network-storage,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_instance_v2" "glusterfs_node_no_floating_ip_custom_volume_size" {
|
||||
name = "${var.cluster_name}-gfs-node-nf-${count.index+1}"
|
||||
count = "${var.gfs_root_volume_size_in_gb > 0 ? var.number_of_gfs_nodes_no_floating_ip : 0}"
|
||||
availability_zone = "${element(var.az_list, count.index)}"
|
||||
image_name = "${var.image}"
|
||||
flavor_id = "${var.flavor_gfs_node}"
|
||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
||||
|
||||
block_device {
|
||||
uuid = "${data.openstack_images_image_v2.gfs_image.id}"
|
||||
source_type = "image"
|
||||
volume_size = "${var.gfs_root_volume_size_in_gb}"
|
||||
boot_index = 0
|
||||
destination_type = "volume"
|
||||
delete_on_termination = true
|
||||
}
|
||||
|
||||
network {
|
||||
name = "${var.network_name}"
|
||||
}
|
||||
|
||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}"]
|
||||
|
||||
dynamic "scheduler_hints" {
|
||||
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_node[0]] : []
|
||||
content {
|
||||
group = "${openstack_compute_servergroup_v2.k8s_node[0].id}"
|
||||
}
|
||||
}
|
||||
|
||||
metadata = {
|
||||
ssh_user = "${var.ssh_user_gfs}"
|
||||
kubespray_groups = "gfs-cluster,network-storage,no-floating"
|
||||
depends_on = "${var.network_id}"
|
||||
use_access_ip = "${var.use_access_ip}"
|
||||
}
|
||||
}
|
||||
|
||||
resource "openstack_compute_volume_attach_v2" "glusterfs_volume" {
|
||||
count = "${var.number_of_gfs_nodes_no_floating_ip}"
|
||||
count = "${var.gfs_root_volume_size_in_gb == 0 ? var.number_of_gfs_nodes_no_floating_ip : 0}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.glusterfs_node_no_floating_ip.*.id, count.index)}"
|
||||
volume_id = "${element(openstack_blockstorage_volume_v2.glusterfs_volume.*.id, count.index)}"
|
||||
}
|
||||
|
||||
resource "openstack_compute_volume_attach_v2" "glusterfs_volume_custom_root_volume_size" {
|
||||
count = "${var.gfs_root_volume_size_in_gb > 0 ? var.number_of_gfs_nodes_no_floating_ip : 0}"
|
||||
instance_id = "${element(openstack_compute_instance_v2.glusterfs_node_no_floating_ip_custom_volume_size.*.id, count.index)}"
|
||||
volume_id = "${element(openstack_blockstorage_volume_v2.glusterfs_volume_custom_volume_size.*.id, count.index)}"
|
||||
}
|
||||
|
@ -22,6 +22,16 @@ variable "number_of_bastions" {}
|
||||
|
||||
variable "number_of_gfs_nodes_no_floating_ip" {}
|
||||
|
||||
variable "bastion_root_volume_size_in_gb" {}
|
||||
|
||||
variable "etcd_root_volume_size_in_gb" {}
|
||||
|
||||
variable "master_root_volume_size_in_gb" {}
|
||||
|
||||
variable "node_root_volume_size_in_gb" {}
|
||||
|
||||
variable "gfs_root_volume_size_in_gb" {}
|
||||
|
||||
variable "gfs_volume_size_in_gb" {}
|
||||
|
||||
variable "public_key_path" {}
|
||||
@ -54,6 +64,10 @@ variable "k8s_master_fips" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "k8s_master_no_etcd_fips" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "k8s_node_fips" {
|
||||
type = "list"
|
||||
}
|
||||
@ -66,6 +80,20 @@ variable "bastion_allowed_remote_ips" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "master_allowed_remote_ips" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "k8s_allowed_remote_ips" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "k8s_allowed_egress_ips" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "wait_for_floatingip" {}
|
||||
|
||||
variable "supplementary_master_groups" {
|
||||
default = ""
|
||||
}
|
||||
@ -77,3 +105,9 @@ variable "supplementary_node_groups" {
|
||||
variable "worker_allowed_ports" {
|
||||
type = "list"
|
||||
}
|
||||
|
||||
variable "use_access_ip" {}
|
||||
|
||||
variable "use_server_groups" {
|
||||
type = bool
|
||||
}
|
@ -1,5 +1,5 @@
|
||||
resource "null_resource" "dummy_dependency" {
|
||||
triggers {
|
||||
triggers = {
|
||||
dependency_id = "${var.router_id}"
|
||||
}
|
||||
}
|
||||
@ -10,6 +10,12 @@ resource "openstack_networking_floatingip_v2" "k8s_master" {
|
||||
depends_on = ["null_resource.dummy_dependency"]
|
||||
}
|
||||
|
||||
resource "openstack_networking_floatingip_v2" "k8s_master_no_etcd" {
|
||||
count = "${var.number_of_k8s_masters_no_etcd}"
|
||||
pool = "${var.floatingip_pool}"
|
||||
depends_on = ["null_resource.dummy_dependency"]
|
||||
}
|
||||
|
||||
resource "openstack_networking_floatingip_v2" "k8s_node" {
|
||||
count = "${var.number_of_k8s_nodes}"
|
||||
pool = "${var.floatingip_pool}"
|
||||
|
@ -1,11 +1,15 @@
|
||||
output "k8s_master_fips" {
|
||||
value = ["${openstack_networking_floatingip_v2.k8s_master.*.address}"]
|
||||
value = "${openstack_networking_floatingip_v2.k8s_master[*].address}"
|
||||
}
|
||||
|
||||
output "k8s_master_no_etcd_fips" {
|
||||
value = "${openstack_networking_floatingip_v2.k8s_master_no_etcd[*].address}"
|
||||
}
|
||||
|
||||
output "k8s_node_fips" {
|
||||
value = ["${openstack_networking_floatingip_v2.k8s_node.*.address}"]
|
||||
value = "${openstack_networking_floatingip_v2.k8s_node[*].address}"
|
||||
}
|
||||
|
||||
output "bastion_fips" {
|
||||
value = ["${openstack_networking_floatingip_v2.bastion.*.address}"]
|
||||
value = "${openstack_networking_floatingip_v2.bastion[*].address}"
|
||||
}
|
||||
|
@ -14,4 +14,4 @@ variable "network_name" {}
|
||||
|
||||
variable "router_id" {
|
||||
default = ""
|
||||
}
|
||||
}
|
@ -8,13 +8,14 @@ resource "openstack_networking_router_v2" "k8s" {
|
||||
resource "openstack_networking_network_v2" "k8s" {
|
||||
name = "${var.network_name}"
|
||||
count = "${var.use_neutron}"
|
||||
dns_domain = var.network_dns_domain != null ? "${var.network_dns_domain}" : null
|
||||
admin_state_up = "true"
|
||||
}
|
||||
|
||||
resource "openstack_networking_subnet_v2" "k8s" {
|
||||
name = "${var.cluster_name}-internal-network"
|
||||
count = "${var.use_neutron}"
|
||||
network_id = "${openstack_networking_network_v2.k8s.id}"
|
||||
network_id = "${openstack_networking_network_v2.k8s[count.index].id}"
|
||||
cidr = "${var.subnet_cidr}"
|
||||
ip_version = 4
|
||||
dns_nameservers = "${var.dns_nameservers}"
|
||||
@ -22,6 +23,6 @@ resource "openstack_networking_subnet_v2" "k8s" {
|
||||
|
||||
resource "openstack_networking_router_interface_v2" "k8s" {
|
||||
count = "${var.use_neutron}"
|
||||
router_id = "${openstack_networking_router_v2.k8s.id}"
|
||||
subnet_id = "${openstack_networking_subnet_v2.k8s.id}"
|
||||
router_id = "${openstack_networking_router_v2.k8s[count.index].id}"
|
||||
subnet_id = "${openstack_networking_subnet_v2.k8s[count.index].id}"
|
||||
}
|
||||
|
@ -2,6 +2,8 @@ variable "external_net" {}
|
||||
|
||||
variable "network_name" {}
|
||||
|
||||
variable "network_dns_domain" {}
|
||||
|
||||
variable "cluster_name" {}
|
||||
|
||||
variable "dns_nameservers" {
|
||||
|
@ -1,6 +1,9 @@
|
||||
# your Kubernetes cluster name here
|
||||
cluster_name = "i-didnt-read-the-docs"
|
||||
|
||||
# list of availability zones available in your OpenStack cluster
|
||||
#az_list = ["nova"]
|
||||
|
||||
# SSH key to use for access to nodes
|
||||
public_key_path = "~/.ssh/id_rsa.pub"
|
||||
|
@ -44,6 +44,26 @@ variable "number_of_gfs_nodes_no_floating_ip" {
|
||||
default = 0
|
||||
}
|
||||
|
||||
variable "bastion_root_volume_size_in_gb" {
|
||||
default = 0
|
||||
}
|
||||
|
||||
variable "etcd_root_volume_size_in_gb" {
|
||||
default = 0
|
||||
}
|
||||
|
||||
variable "master_root_volume_size_in_gb" {
|
||||
default = 0
|
||||
}
|
||||
|
||||
variable "node_root_volume_size_in_gb" {
|
||||
default = 0
|
||||
}
|
||||
|
||||
variable "gfs_root_volume_size_in_gb" {
|
||||
default = 0
|
||||
}
|
||||
|
||||
variable "gfs_volume_size_in_gb" {
|
||||
default = 75
|
||||
}
|
||||
@ -55,12 +75,12 @@ variable "public_key_path" {
|
||||
|
||||
variable "image" {
|
||||
description = "the image to use"
|
||||
default = "ubuntu-14.04"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "image_gfs" {
|
||||
description = "Glance image to use for GlusterFS"
|
||||
default = "ubuntu-16.04"
|
||||
default = ""
|
||||
}
|
||||
|
||||
variable "ssh_user" {
|
||||
@ -103,6 +123,12 @@ variable "network_name" {
|
||||
default = "internal"
|
||||
}
|
||||
|
||||
variable "network_dns_domain" {
|
||||
description = "dns_domain for the internal network"
|
||||
type = "string"
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "use_neutron" {
|
||||
description = "Use neutron"
|
||||
default = 1
|
||||
@ -125,6 +151,11 @@ variable "floatingip_pool" {
|
||||
default = "external"
|
||||
}
|
||||
|
||||
variable "wait_for_floatingip" {
|
||||
description = "Terraform will poll the instance until the floating IP has been associated."
|
||||
default = "false"
|
||||
}
|
||||
|
||||
variable "external_net" {
|
||||
description = "uuid of the external/public network"
|
||||
}
|
||||
@ -145,6 +176,24 @@ variable "bastion_allowed_remote_ips" {
|
||||
default = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
variable "master_allowed_remote_ips" {
|
||||
description = "An array of CIDRs allowed to access API of masters"
|
||||
type = "list"
|
||||
default = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
variable "k8s_allowed_remote_ips" {
|
||||
description = "An array of CIDRs allowed to SSH to hosts"
|
||||
type = "list"
|
||||
default = []
|
||||
}
|
||||
|
||||
variable "k8s_allowed_egress_ips" {
|
||||
description = "An array of CIDRs allowed for egress traffic"
|
||||
type = "list"
|
||||
default = ["0.0.0.0/0"]
|
||||
}
|
||||
|
||||
variable "worker_allowed_ports" {
|
||||
type = "list"
|
||||
|
||||
@ -157,3 +206,11 @@ variable "worker_allowed_ports" {
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
variable "use_access_ip" {
|
||||
default = 1
|
||||
}
|
||||
|
||||
variable "use_server_groups" {
|
||||
default = false
|
||||
}
|
@ -38,7 +38,7 @@ now six total etcd replicas.
|
||||
|
||||
## SSH Key Setup
|
||||
|
||||
An SSH keypair is required so Ansible can access the newly provisioned nodes (bare metal Packet hosts). By default, the public SSH key defined in cluster.tf will be installed in authorized_key on the newly provisioned nodes (~/.ssh/id_rsa.pub). Terraform will upload this public key and then it will be distributed out to all the nodes. If you have already set this public key in Packet (i.e. via the portal), then set the public keyfile name in cluster.tf to blank to prevent the duplicate key from being uploaded which will cause an error.
|
||||
An SSH keypair is required so Ansible can access the newly provisioned nodes (bare metal Packet hosts). By default, the public SSH key defined in cluster.tfvars will be installed in authorized_key on the newly provisioned nodes (~/.ssh/id_rsa.pub). Terraform will upload this public key and then it will be distributed out to all the nodes. If you have already set this public key in Packet (i.e. via the portal), then set the public keyfile name in cluster.tfvars to blank to prevent the duplicate key from being uploaded which will cause an error.
|
||||
|
||||
If you don't already have a keypair generated (~/.ssh/id_rsa and ~/.ssh/id_rsa.pub), then a new keypair can be generated with the command:
|
||||
|
||||
@ -72,7 +72,7 @@ If someone gets this key, they can startup/shutdown hosts in your project!
|
||||
For more information on how to generate an API key or find your project ID, please see:
|
||||
https://support.packet.com/kb/articles/api-integrations
|
||||
|
||||
The Packet Project ID associated with the key will be set later in cluster.tf.
|
||||
The Packet Project ID associated with the key will be set later in cluster.tfvars.
|
||||
|
||||
For more information about the API, please see:
|
||||
https://www.packet.com/developers/api/
|
||||
@ -88,7 +88,7 @@ Note that to deploy several clusters within the same project you need to use [te
|
||||
The construction of the cluster is driven by values found in
|
||||
[variables.tf](variables.tf).
|
||||
|
||||
For your cluster, edit `inventory/$CLUSTER/cluster.tf`.
|
||||
For your cluster, edit `inventory/$CLUSTER/cluster.tfvars`.
|
||||
|
||||
The `cluster_name` is used to set a tag on each server deployed as part of this cluster.
|
||||
This helps when identifying which hosts are associated with each cluster.
|
||||
@ -138,7 +138,7 @@ This should finish fairly quickly telling you Terraform has successfully initial
|
||||
You can apply the Terraform configuration to your cluster with the following command
|
||||
issued from your cluster's inventory directory (`inventory/$CLUSTER`):
|
||||
```ShellSession
|
||||
$ terraform apply -var-file=cluster.tf ../../contrib/terraform/packet
|
||||
$ terraform apply -var-file=cluster.tfvars ../../contrib/terraform/packet
|
||||
$ export ANSIBLE_HOST_KEY_CHECKING=False
|
||||
$ ansible-playbook -i hosts ../../cluster.yml
|
||||
```
|
||||
@ -147,7 +147,7 @@ $ ansible-playbook -i hosts ../../cluster.yml
|
||||
You can destroy your new cluster with the following command issued from the cluster's inventory directory:
|
||||
|
||||
```ShellSession
|
||||
$ terraform destroy -var-file=cluster.tf ../../contrib/terraform/packet
|
||||
$ terraform destroy -var-file=cluster.tfvars ../../contrib/terraform/packet
|
||||
```
|
||||
|
||||
If you've started the Ansible run, it may also be a good idea to do some manual cleanup:
|
||||
|
@ -1,60 +1,63 @@
|
||||
# Configure the Packet Provider
|
||||
provider "packet" {}
|
||||
provider "packet" {
|
||||
version = "~> 2.0"
|
||||
}
|
||||
|
||||
resource "packet_ssh_key" "k8s" {
|
||||
count = "${var.public_key_path != "" ? 1 : 0}"
|
||||
count = var.public_key_path != "" ? 1 : 0
|
||||
name = "kubernetes-${var.cluster_name}"
|
||||
public_key = "${chomp(file(var.public_key_path))}"
|
||||
public_key = chomp(file(var.public_key_path))
|
||||
}
|
||||
|
||||
resource "packet_device" "k8s_master" {
|
||||
depends_on = ["packet_ssh_key.k8s"]
|
||||
depends_on = [packet_ssh_key.k8s]
|
||||
|
||||
count = "${var.number_of_k8s_masters}"
|
||||
hostname = "${var.cluster_name}-k8s-master-${count.index+1}"
|
||||
plan = "${var.plan_k8s_masters}"
|
||||
facility = "${var.facility}"
|
||||
operating_system = "${var.operating_system}"
|
||||
billing_cycle = "${var.billing_cycle}"
|
||||
project_id = "${var.packet_project_id}"
|
||||
count = var.number_of_k8s_masters
|
||||
hostname = "${var.cluster_name}-k8s-master-${count.index + 1}"
|
||||
plan = var.plan_k8s_masters
|
||||
facilities = [var.facility]
|
||||
operating_system = var.operating_system
|
||||
billing_cycle = var.billing_cycle
|
||||
project_id = var.packet_project_id
|
||||
tags = ["cluster-${var.cluster_name}", "k8s-cluster", "kube-master", "etcd", "kube-node"]
|
||||
}
|
||||
|
||||
resource "packet_device" "k8s_master_no_etcd" {
|
||||
depends_on = ["packet_ssh_key.k8s"]
|
||||
depends_on = [packet_ssh_key.k8s]
|
||||
|
||||
count = "${var.number_of_k8s_masters_no_etcd}"
|
||||
hostname = "${var.cluster_name}-k8s-master-${count.index+1}"
|
||||
plan = "${var.plan_k8s_masters_no_etcd}"
|
||||
facility = "${var.facility}"
|
||||
operating_system = "${var.operating_system}"
|
||||
billing_cycle = "${var.billing_cycle}"
|
||||
project_id = "${var.packet_project_id}"
|
||||
count = var.number_of_k8s_masters_no_etcd
|
||||
hostname = "${var.cluster_name}-k8s-master-${count.index + 1}"
|
||||
plan = var.plan_k8s_masters_no_etcd
|
||||
facilities = [var.facility]
|
||||
operating_system = var.operating_system
|
||||
billing_cycle = var.billing_cycle
|
||||
project_id = var.packet_project_id
|
||||
tags = ["cluster-${var.cluster_name}", "k8s-cluster", "kube-master"]
|
||||
}
|
||||
|
||||
resource "packet_device" "k8s_etcd" {
|
||||
depends_on = ["packet_ssh_key.k8s"]
|
||||
depends_on = [packet_ssh_key.k8s]
|
||||
|
||||
count = "${var.number_of_etcd}"
|
||||
hostname = "${var.cluster_name}-etcd-${count.index+1}"
|
||||
plan = "${var.plan_etcd}"
|
||||
facility = "${var.facility}"
|
||||
operating_system = "${var.operating_system}"
|
||||
billing_cycle = "${var.billing_cycle}"
|
||||
project_id = "${var.packet_project_id}"
|
||||
count = var.number_of_etcd
|
||||
hostname = "${var.cluster_name}-etcd-${count.index + 1}"
|
||||
plan = var.plan_etcd
|
||||
facilities = [var.facility]
|
||||
operating_system = var.operating_system
|
||||
billing_cycle = var.billing_cycle
|
||||
project_id = var.packet_project_id
|
||||
tags = ["cluster-${var.cluster_name}", "etcd"]
|
||||
}
|
||||
|
||||
resource "packet_device" "k8s_node" {
|
||||
depends_on = ["packet_ssh_key.k8s"]
|
||||
depends_on = [packet_ssh_key.k8s]
|
||||
|
||||
count = "${var.number_of_k8s_nodes}"
|
||||
hostname = "${var.cluster_name}-k8s-node-${count.index+1}"
|
||||
plan = "${var.plan_k8s_nodes}"
|
||||
facility = "${var.facility}"
|
||||
operating_system = "${var.operating_system}"
|
||||
billing_cycle = "${var.billing_cycle}"
|
||||
project_id = "${var.packet_project_id}"
|
||||
count = var.number_of_k8s_nodes
|
||||
hostname = "${var.cluster_name}-k8s-node-${count.index + 1}"
|
||||
plan = var.plan_k8s_nodes
|
||||
facilities = [var.facility]
|
||||
operating_system = var.operating_system
|
||||
billing_cycle = var.billing_cycle
|
||||
project_id = var.packet_project_id
|
||||
tags = ["cluster-${var.cluster_name}", "k8s-cluster", "kube-node"]
|
||||
}
|
||||
|
||||
|
@ -1,15 +1,16 @@
|
||||
output "k8s_masters" {
|
||||
value = "${packet_device.k8s_master.*.access_public_ipv4}"
|
||||
value = packet_device.k8s_master.*.access_public_ipv4
|
||||
}
|
||||
|
||||
output "k8s_masters_no_etc" {
|
||||
value = "${packet_device.k8s_master_no_etcd.*.access_public_ipv4}"
|
||||
value = packet_device.k8s_master_no_etcd.*.access_public_ipv4
|
||||
}
|
||||
|
||||
output "k8s_etcds" {
|
||||
value = "${packet_device.k8s_etcd.*.access_public_ipv4}"
|
||||
value = packet_device.k8s_etcd.*.access_public_ipv4
|
||||
}
|
||||
|
||||
output "k8s_nodes" {
|
||||
value = "${packet_device.k8s_node.*.access_public_ipv4}"
|
||||
value = packet_device.k8s_node.*.access_public_ipv4
|
||||
}
|
||||
|
||||
|
@ -54,3 +54,4 @@ variable "number_of_etcd" {
|
||||
variable "number_of_k8s_nodes" {
|
||||
default = 0
|
||||
}
|
||||
|
||||
|
4
contrib/terraform/packet/versions.tf
Normal file
4
contrib/terraform/packet/versions.tf
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
terraform {
|
||||
required_version = ">= 0.12"
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python2
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Copyright 2015 Cisco Systems, Inc.
|
||||
#
|
||||
@ -20,15 +20,15 @@
|
||||
Dynamic inventory for Terraform - finds all `.tfstate` files below the working
|
||||
directory and generates an inventory based on them.
|
||||
"""
|
||||
from __future__ import unicode_literals, print_function
|
||||
import argparse
|
||||
from collections import defaultdict
|
||||
import random
|
||||
from functools import wraps
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
|
||||
VERSION = '0.3.0pre'
|
||||
VERSION = '0.4.0pre'
|
||||
|
||||
|
||||
def tfstates(root=None):
|
||||
@ -38,15 +38,58 @@ def tfstates(root=None):
|
||||
if os.path.splitext(name)[-1] == '.tfstate':
|
||||
yield os.path.join(dirpath, name)
|
||||
|
||||
def convert_to_v3_structure(attributes, prefix=''):
|
||||
""" Convert the attributes from v4 to v3
|
||||
Receives a dict and return a dictionary """
|
||||
result = {}
|
||||
if isinstance(attributes, str):
|
||||
# In the case when we receive a string (e.g. values for security_groups)
|
||||
return {'{}{}'.format(prefix, random.randint(1,10**10)): attributes}
|
||||
for key, value in attributes.items():
|
||||
if isinstance(value, list):
|
||||
if len(value):
|
||||
result['{}{}.#'.format(prefix, key, hash)] = len(value)
|
||||
for i, v in enumerate(value):
|
||||
result.update(convert_to_v3_structure(v, '{}{}.{}.'.format(prefix, key, i)))
|
||||
elif isinstance(value, dict):
|
||||
result['{}{}.%'.format(prefix, key)] = len(value)
|
||||
for k, v in value.items():
|
||||
result['{}{}.{}'.format(prefix, key, k)] = v
|
||||
else:
|
||||
result['{}{}'.format(prefix, key)] = value
|
||||
return result
|
||||
|
||||
def iterresources(filenames):
|
||||
for filename in filenames:
|
||||
with open(filename, 'r') as json_file:
|
||||
state = json.load(json_file)
|
||||
for module in state['modules']:
|
||||
name = module['path'][-1]
|
||||
for key, resource in module['resources'].items():
|
||||
yield name, key, resource
|
||||
tf_version = state['version']
|
||||
if tf_version == 3:
|
||||
for module in state['modules']:
|
||||
name = module['path'][-1]
|
||||
for key, resource in module['resources'].items():
|
||||
yield name, key, resource
|
||||
elif tf_version == 4:
|
||||
# In version 4 the structure changes so we need to iterate
|
||||
# each instance inside the resource branch.
|
||||
for resource in state['resources']:
|
||||
name = resource['provider'].split('.')[-1]
|
||||
for instance in resource['instances']:
|
||||
key = "{}.{}".format(resource['type'], resource['name'])
|
||||
if 'index_key' in instance:
|
||||
key = "{}.{}".format(key, instance['index_key'])
|
||||
data = {}
|
||||
data['type'] = resource['type']
|
||||
data['provider'] = resource['provider']
|
||||
data['depends_on'] = instance.get('depends_on', [])
|
||||
data['primary'] = {'attributes': convert_to_v3_structure(instance['attributes'])}
|
||||
if 'id' in instance['attributes']:
|
||||
data['primary']['id'] = instance['attributes']['id']
|
||||
data['primary']['meta'] = instance['attributes'].get('meta',{})
|
||||
yield name, key, data
|
||||
else:
|
||||
raise KeyError('tfstate version %d not supported' % tf_version)
|
||||
|
||||
|
||||
## READ RESOURCES
|
||||
PARSERS = {}
|
||||
@ -109,7 +152,7 @@ def calculate_mantl_vars(func):
|
||||
|
||||
|
||||
def _parse_prefix(source, prefix, sep='.'):
|
||||
for compkey, value in source.items():
|
||||
for compkey, value in list(source.items()):
|
||||
try:
|
||||
curprefix, rest = compkey.split(sep, 1)
|
||||
except ValueError:
|
||||
@ -127,7 +170,7 @@ def parse_attr_list(source, prefix, sep='.'):
|
||||
idx, key = compkey.split(sep, 1)
|
||||
attrs[idx][key] = value
|
||||
|
||||
return attrs.values()
|
||||
return list(attrs.values())
|
||||
|
||||
|
||||
def parse_dict(source, prefix, sep='.'):
|
||||
@ -139,6 +182,9 @@ def parse_list(source, prefix, sep='.'):
|
||||
|
||||
|
||||
def parse_bool(string_form):
|
||||
if type(string_form) is bool:
|
||||
return string_form
|
||||
|
||||
token = string_form.lower()[0]
|
||||
|
||||
if token == 't':
|
||||
@ -149,75 +195,6 @@ def parse_bool(string_form):
|
||||
raise ValueError('could not convert %r to a bool' % string_form)
|
||||
|
||||
|
||||
@parses('triton_machine')
|
||||
@calculate_mantl_vars
|
||||
def triton_machine(resource, module_name):
|
||||
raw_attrs = resource['primary']['attributes']
|
||||
name = raw_attrs.get('name')
|
||||
groups = []
|
||||
|
||||
attrs = {
|
||||
'id': raw_attrs['id'],
|
||||
'dataset': raw_attrs['dataset'],
|
||||
'disk': raw_attrs['disk'],
|
||||
'firewall_enabled': parse_bool(raw_attrs['firewall_enabled']),
|
||||
'image': raw_attrs['image'],
|
||||
'ips': parse_list(raw_attrs, 'ips'),
|
||||
'memory': raw_attrs['memory'],
|
||||
'name': raw_attrs['name'],
|
||||
'networks': parse_list(raw_attrs, 'networks'),
|
||||
'package': raw_attrs['package'],
|
||||
'primary_ip': raw_attrs['primaryip'],
|
||||
'root_authorized_keys': raw_attrs['root_authorized_keys'],
|
||||
'state': raw_attrs['state'],
|
||||
'tags': parse_dict(raw_attrs, 'tags'),
|
||||
'type': raw_attrs['type'],
|
||||
'user_data': raw_attrs['user_data'],
|
||||
'user_script': raw_attrs['user_script'],
|
||||
|
||||
# ansible
|
||||
'ansible_ssh_host': raw_attrs['primaryip'],
|
||||
'ansible_ssh_port': 22,
|
||||
'ansible_ssh_user': 'root', # it's "root" on Triton by default
|
||||
|
||||
# generic
|
||||
'public_ipv4': raw_attrs['primaryip'],
|
||||
'provider': 'triton',
|
||||
}
|
||||
|
||||
# private IPv4
|
||||
for ip in attrs['ips']:
|
||||
if ip.startswith('10') or ip.startswith('192.168'): # private IPs
|
||||
attrs['private_ipv4'] = ip
|
||||
break
|
||||
|
||||
if 'private_ipv4' not in attrs:
|
||||
attrs['private_ipv4'] = attrs['public_ipv4']
|
||||
|
||||
# attrs specific to Mantl
|
||||
attrs.update({
|
||||
'consul_dc': _clean_dc(attrs['tags'].get('dc', 'none')),
|
||||
'role': attrs['tags'].get('role', 'none'),
|
||||
'ansible_python_interpreter': attrs['tags'].get('python_bin', 'python')
|
||||
})
|
||||
|
||||
# add groups based on attrs
|
||||
groups.append('triton_image=' + attrs['image'])
|
||||
groups.append('triton_package=' + attrs['package'])
|
||||
groups.append('triton_state=' + attrs['state'])
|
||||
groups.append('triton_firewall_enabled=%s' % attrs['firewall_enabled'])
|
||||
groups.extend('triton_tags_%s=%s' % item
|
||||
for item in attrs['tags'].items())
|
||||
groups.extend('triton_network=' + network
|
||||
for network in attrs['networks'])
|
||||
|
||||
# groups specific to Mantl
|
||||
groups.append('role=' + attrs['role'])
|
||||
groups.append('dc=' + attrs['consul_dc'])
|
||||
|
||||
return name, attrs, groups
|
||||
|
||||
|
||||
@parses('packet_device')
|
||||
def packet_device(resource, tfvars=None):
|
||||
raw_attrs = resource['primary']['attributes']
|
||||
@ -226,7 +203,7 @@ def packet_device(resource, tfvars=None):
|
||||
|
||||
attrs = {
|
||||
'id': raw_attrs['id'],
|
||||
'facility': raw_attrs['facility'],
|
||||
'facilities': parse_list(raw_attrs, 'facilities'),
|
||||
'hostname': raw_attrs['hostname'],
|
||||
'operating_system': raw_attrs['operating_system'],
|
||||
'locked': parse_bool(raw_attrs['locked']),
|
||||
@ -236,7 +213,7 @@ def packet_device(resource, tfvars=None):
|
||||
'state': raw_attrs['state'],
|
||||
# ansible
|
||||
'ansible_ssh_host': raw_attrs['network.0.address'],
|
||||
'ansible_ssh_user': 'root', # it's always "root" on Packet
|
||||
'ansible_ssh_user': 'root', # Use root by default in packet
|
||||
# generic
|
||||
'ipv4_address': raw_attrs['network.0.address'],
|
||||
'public_ipv4': raw_attrs['network.0.address'],
|
||||
@ -246,8 +223,11 @@ def packet_device(resource, tfvars=None):
|
||||
'provider': 'packet',
|
||||
}
|
||||
|
||||
if raw_attrs['operating_system'] == 'coreos_stable':
|
||||
# For CoreOS set the ssh_user to core
|
||||
attrs.update({'ansible_ssh_user': 'core'})
|
||||
|
||||
# add groups based on attrs
|
||||
groups.append('packet_facility=' + attrs['facility'])
|
||||
groups.append('packet_operating_system=' + attrs['operating_system'])
|
||||
groups.append('packet_locked=%s' % attrs['locked'])
|
||||
groups.append('packet_state=' + attrs['state'])
|
||||
@ -259,94 +239,6 @@ def packet_device(resource, tfvars=None):
|
||||
return name, attrs, groups
|
||||
|
||||
|
||||
@parses('digitalocean_droplet')
|
||||
@calculate_mantl_vars
|
||||
def digitalocean_host(resource, tfvars=None):
|
||||
raw_attrs = resource['primary']['attributes']
|
||||
name = raw_attrs['name']
|
||||
groups = []
|
||||
|
||||
attrs = {
|
||||
'id': raw_attrs['id'],
|
||||
'image': raw_attrs['image'],
|
||||
'ipv4_address': raw_attrs['ipv4_address'],
|
||||
'locked': parse_bool(raw_attrs['locked']),
|
||||
'metadata': json.loads(raw_attrs.get('user_data', '{}')),
|
||||
'region': raw_attrs['region'],
|
||||
'size': raw_attrs['size'],
|
||||
'ssh_keys': parse_list(raw_attrs, 'ssh_keys'),
|
||||
'status': raw_attrs['status'],
|
||||
# ansible
|
||||
'ansible_ssh_host': raw_attrs['ipv4_address'],
|
||||
'ansible_ssh_port': 22,
|
||||
'ansible_ssh_user': 'root', # it's always "root" on DO
|
||||
# generic
|
||||
'public_ipv4': raw_attrs['ipv4_address'],
|
||||
'private_ipv4': raw_attrs.get('ipv4_address_private',
|
||||
raw_attrs['ipv4_address']),
|
||||
'provider': 'digitalocean',
|
||||
}
|
||||
|
||||
# attrs specific to Mantl
|
||||
attrs.update({
|
||||
'consul_dc': _clean_dc(attrs['metadata'].get('dc', attrs['region'])),
|
||||
'role': attrs['metadata'].get('role', 'none'),
|
||||
'ansible_python_interpreter': attrs['metadata'].get('python_bin','python')
|
||||
})
|
||||
|
||||
# add groups based on attrs
|
||||
groups.append('do_image=' + attrs['image'])
|
||||
groups.append('do_locked=%s' % attrs['locked'])
|
||||
groups.append('do_region=' + attrs['region'])
|
||||
groups.append('do_size=' + attrs['size'])
|
||||
groups.append('do_status=' + attrs['status'])
|
||||
groups.extend('do_metadata_%s=%s' % item
|
||||
for item in attrs['metadata'].items())
|
||||
|
||||
# groups specific to Mantl
|
||||
groups.append('role=' + attrs['role'])
|
||||
groups.append('dc=' + attrs['consul_dc'])
|
||||
|
||||
return name, attrs, groups
|
||||
|
||||
|
||||
@parses('softlayer_virtualserver')
|
||||
@calculate_mantl_vars
|
||||
def softlayer_host(resource, module_name):
|
||||
raw_attrs = resource['primary']['attributes']
|
||||
name = raw_attrs['name']
|
||||
groups = []
|
||||
|
||||
attrs = {
|
||||
'id': raw_attrs['id'],
|
||||
'image': raw_attrs['image'],
|
||||
'ipv4_address': raw_attrs['ipv4_address'],
|
||||
'metadata': json.loads(raw_attrs.get('user_data', '{}')),
|
||||
'region': raw_attrs['region'],
|
||||
'ram': raw_attrs['ram'],
|
||||
'cpu': raw_attrs['cpu'],
|
||||
'ssh_keys': parse_list(raw_attrs, 'ssh_keys'),
|
||||
'public_ipv4': raw_attrs['ipv4_address'],
|
||||
'private_ipv4': raw_attrs['ipv4_address_private'],
|
||||
'ansible_ssh_host': raw_attrs['ipv4_address'],
|
||||
'ansible_ssh_port': 22,
|
||||
'ansible_ssh_user': 'root',
|
||||
'provider': 'softlayer',
|
||||
}
|
||||
|
||||
# attrs specific to Mantl
|
||||
attrs.update({
|
||||
'consul_dc': _clean_dc(attrs['metadata'].get('dc', attrs['region'])),
|
||||
'role': attrs['metadata'].get('role', 'none'),
|
||||
'ansible_python_interpreter': attrs['metadata'].get('python_bin','python')
|
||||
})
|
||||
|
||||
# groups specific to Mantl
|
||||
groups.append('role=' + attrs['role'])
|
||||
groups.append('dc=' + attrs['consul_dc'])
|
||||
|
||||
return name, attrs, groups
|
||||
|
||||
def openstack_floating_ips(resource):
|
||||
raw_attrs = resource['primary']['attributes']
|
||||
attrs = {
|
||||
@ -397,10 +289,16 @@ def openstack_host(resource, module_name):
|
||||
attrs['private_ipv4'] = raw_attrs['network.0.fixed_ip_v4']
|
||||
|
||||
try:
|
||||
attrs.update({
|
||||
'ansible_ssh_host': raw_attrs['access_ip_v4'],
|
||||
'publicly_routable': True,
|
||||
})
|
||||
if 'metadata.prefer_ipv6' in raw_attrs and raw_attrs['metadata.prefer_ipv6'] == "1":
|
||||
attrs.update({
|
||||
'ansible_ssh_host': re.sub("[\[\]]", "", raw_attrs['access_ip_v6']),
|
||||
'publicly_routable': True,
|
||||
})
|
||||
else:
|
||||
attrs.update({
|
||||
'ansible_ssh_host': raw_attrs['access_ip_v4'],
|
||||
'publicly_routable': True,
|
||||
})
|
||||
except (KeyError, ValueError):
|
||||
attrs.update({'ansible_ssh_host': '', 'publicly_routable': False})
|
||||
|
||||
@ -410,9 +308,9 @@ def openstack_host(resource, module_name):
|
||||
if 'metadata.ssh_user' in raw_attrs:
|
||||
attrs['ansible_ssh_user'] = raw_attrs['metadata.ssh_user']
|
||||
|
||||
if 'volume.#' in raw_attrs.keys() and int(raw_attrs['volume.#']) > 0:
|
||||
if 'volume.#' in list(raw_attrs.keys()) and int(raw_attrs['volume.#']) > 0:
|
||||
device_index = 1
|
||||
for key, value in raw_attrs.items():
|
||||
for key, value in list(raw_attrs.items()):
|
||||
match = re.search("^volume.*.device$", key)
|
||||
if match:
|
||||
attrs['disk_volume_device_'+str(device_index)] = value
|
||||
@ -430,7 +328,7 @@ def openstack_host(resource, module_name):
|
||||
groups.append('os_image=' + attrs['image']['name'])
|
||||
groups.append('os_flavor=' + attrs['flavor']['name'])
|
||||
groups.extend('os_metadata_%s=%s' % item
|
||||
for item in attrs['metadata'].items())
|
||||
for item in list(attrs['metadata'].items()))
|
||||
groups.append('os_region=' + attrs['region'])
|
||||
|
||||
# groups specific to Mantl
|
||||
@ -444,293 +342,24 @@ def openstack_host(resource, module_name):
|
||||
return name, attrs, groups
|
||||
|
||||
|
||||
@parses('aws_instance')
|
||||
@calculate_mantl_vars
|
||||
def aws_host(resource, module_name):
|
||||
name = resource['primary']['attributes']['tags.Name']
|
||||
raw_attrs = resource['primary']['attributes']
|
||||
|
||||
groups = []
|
||||
|
||||
attrs = {
|
||||
'ami': raw_attrs['ami'],
|
||||
'availability_zone': raw_attrs['availability_zone'],
|
||||
'ebs_block_device': parse_attr_list(raw_attrs, 'ebs_block_device'),
|
||||
'ebs_optimized': parse_bool(raw_attrs['ebs_optimized']),
|
||||
'ephemeral_block_device': parse_attr_list(raw_attrs,
|
||||
'ephemeral_block_device'),
|
||||
'id': raw_attrs['id'],
|
||||
'key_name': raw_attrs['key_name'],
|
||||
'private': parse_dict(raw_attrs, 'private',
|
||||
sep='_'),
|
||||
'public': parse_dict(raw_attrs, 'public',
|
||||
sep='_'),
|
||||
'root_block_device': parse_attr_list(raw_attrs, 'root_block_device'),
|
||||
'security_groups': parse_list(raw_attrs, 'security_groups'),
|
||||
'subnet': parse_dict(raw_attrs, 'subnet',
|
||||
sep='_'),
|
||||
'tags': parse_dict(raw_attrs, 'tags'),
|
||||
'tenancy': raw_attrs['tenancy'],
|
||||
'vpc_security_group_ids': parse_list(raw_attrs,
|
||||
'vpc_security_group_ids'),
|
||||
# ansible-specific
|
||||
'ansible_ssh_port': 22,
|
||||
'ansible_ssh_host': raw_attrs['public_ip'],
|
||||
# generic
|
||||
'public_ipv4': raw_attrs['public_ip'],
|
||||
'private_ipv4': raw_attrs['private_ip'],
|
||||
'provider': 'aws',
|
||||
}
|
||||
|
||||
# attrs specific to Ansible
|
||||
if 'tags.sshUser' in raw_attrs:
|
||||
attrs['ansible_ssh_user'] = raw_attrs['tags.sshUser']
|
||||
if 'tags.sshPrivateIp' in raw_attrs:
|
||||
attrs['ansible_ssh_host'] = raw_attrs['private_ip']
|
||||
|
||||
# attrs specific to Mantl
|
||||
attrs.update({
|
||||
'consul_dc': _clean_dc(attrs['tags'].get('dc', module_name)),
|
||||
'role': attrs['tags'].get('role', 'none'),
|
||||
'ansible_python_interpreter': attrs['tags'].get('python_bin','python')
|
||||
})
|
||||
|
||||
# groups specific to Mantl
|
||||
groups.extend(['aws_ami=' + attrs['ami'],
|
||||
'aws_az=' + attrs['availability_zone'],
|
||||
'aws_key_name=' + attrs['key_name'],
|
||||
'aws_tenancy=' + attrs['tenancy']])
|
||||
groups.extend('aws_tag_%s=%s' % item for item in attrs['tags'].items())
|
||||
groups.extend('aws_vpc_security_group=' + group
|
||||
for group in attrs['vpc_security_group_ids'])
|
||||
groups.extend('aws_subnet_%s=%s' % subnet
|
||||
for subnet in attrs['subnet'].items())
|
||||
|
||||
# groups specific to Mantl
|
||||
groups.append('role=' + attrs['role'])
|
||||
groups.append('dc=' + attrs['consul_dc'])
|
||||
|
||||
return name, attrs, groups
|
||||
|
||||
|
||||
@parses('google_compute_instance')
|
||||
@calculate_mantl_vars
|
||||
def gce_host(resource, module_name):
|
||||
name = resource['primary']['id']
|
||||
raw_attrs = resource['primary']['attributes']
|
||||
groups = []
|
||||
|
||||
# network interfaces
|
||||
interfaces = parse_attr_list(raw_attrs, 'network_interface')
|
||||
for interface in interfaces:
|
||||
interface['access_config'] = parse_attr_list(interface,
|
||||
'access_config')
|
||||
for key in interface.keys():
|
||||
if '.' in key:
|
||||
del interface[key]
|
||||
|
||||
# general attrs
|
||||
attrs = {
|
||||
'can_ip_forward': raw_attrs['can_ip_forward'] == 'true',
|
||||
'disks': parse_attr_list(raw_attrs, 'disk'),
|
||||
'machine_type': raw_attrs['machine_type'],
|
||||
'metadata': parse_dict(raw_attrs, 'metadata'),
|
||||
'network': parse_attr_list(raw_attrs, 'network'),
|
||||
'network_interface': interfaces,
|
||||
'self_link': raw_attrs['self_link'],
|
||||
'service_account': parse_attr_list(raw_attrs, 'service_account'),
|
||||
'tags': parse_list(raw_attrs, 'tags'),
|
||||
'zone': raw_attrs['zone'],
|
||||
# ansible
|
||||
'ansible_ssh_port': 22,
|
||||
'provider': 'gce',
|
||||
}
|
||||
|
||||
# attrs specific to Ansible
|
||||
if 'metadata.ssh_user' in raw_attrs:
|
||||
attrs['ansible_ssh_user'] = raw_attrs['metadata.ssh_user']
|
||||
|
||||
# attrs specific to Mantl
|
||||
attrs.update({
|
||||
'consul_dc': _clean_dc(attrs['metadata'].get('dc', module_name)),
|
||||
'role': attrs['metadata'].get('role', 'none'),
|
||||
'ansible_python_interpreter': attrs['metadata'].get('python_bin','python')
|
||||
})
|
||||
|
||||
try:
|
||||
attrs.update({
|
||||
'ansible_ssh_host': interfaces[0]['access_config'][0]['nat_ip'] or interfaces[0]['access_config'][0]['assigned_nat_ip'],
|
||||
'public_ipv4': interfaces[0]['access_config'][0]['nat_ip'] or interfaces[0]['access_config'][0]['assigned_nat_ip'],
|
||||
'private_ipv4': interfaces[0]['address'],
|
||||
'publicly_routable': True,
|
||||
})
|
||||
except (KeyError, ValueError):
|
||||
attrs.update({'ansible_ssh_host': '', 'publicly_routable': False})
|
||||
|
||||
# add groups based on attrs
|
||||
groups.extend('gce_image=' + disk['image'] for disk in attrs['disks'])
|
||||
groups.append('gce_machine_type=' + attrs['machine_type'])
|
||||
groups.extend('gce_metadata_%s=%s' % (key, value)
|
||||
for (key, value) in attrs['metadata'].items()
|
||||
if key not in set(['sshKeys']))
|
||||
groups.extend('gce_tag=' + tag for tag in attrs['tags'])
|
||||
groups.append('gce_zone=' + attrs['zone'])
|
||||
|
||||
if attrs['can_ip_forward']:
|
||||
groups.append('gce_ip_forward')
|
||||
if attrs['publicly_routable']:
|
||||
groups.append('gce_publicly_routable')
|
||||
|
||||
# groups specific to Mantl
|
||||
groups.append('role=' + attrs['metadata'].get('role', 'none'))
|
||||
groups.append('dc=' + attrs['consul_dc'])
|
||||
|
||||
return name, attrs, groups
|
||||
|
||||
|
||||
@parses('vsphere_virtual_machine')
|
||||
@calculate_mantl_vars
|
||||
def vsphere_host(resource, module_name):
|
||||
raw_attrs = resource['primary']['attributes']
|
||||
network_attrs = parse_dict(raw_attrs, 'network_interface')
|
||||
network = parse_dict(network_attrs, '0')
|
||||
ip_address = network.get('ipv4_address', network['ip_address'])
|
||||
name = raw_attrs['name']
|
||||
groups = []
|
||||
|
||||
attrs = {
|
||||
'id': raw_attrs['id'],
|
||||
'ip_address': ip_address,
|
||||
'private_ipv4': ip_address,
|
||||
'public_ipv4': ip_address,
|
||||
'metadata': parse_dict(raw_attrs, 'custom_configuration_parameters'),
|
||||
'ansible_ssh_port': 22,
|
||||
'provider': 'vsphere',
|
||||
}
|
||||
|
||||
try:
|
||||
attrs.update({
|
||||
'ansible_ssh_host': ip_address,
|
||||
})
|
||||
except (KeyError, ValueError):
|
||||
attrs.update({'ansible_ssh_host': '', })
|
||||
|
||||
attrs.update({
|
||||
'consul_dc': _clean_dc(attrs['metadata'].get('consul_dc', module_name)),
|
||||
'role': attrs['metadata'].get('role', 'none'),
|
||||
'ansible_python_interpreter': attrs['metadata'].get('python_bin','python')
|
||||
})
|
||||
|
||||
# attrs specific to Ansible
|
||||
if 'ssh_user' in attrs['metadata']:
|
||||
attrs['ansible_ssh_user'] = attrs['metadata']['ssh_user']
|
||||
|
||||
groups.append('role=' + attrs['role'])
|
||||
groups.append('dc=' + attrs['consul_dc'])
|
||||
|
||||
return name, attrs, groups
|
||||
|
||||
@parses('azure_instance')
|
||||
@calculate_mantl_vars
|
||||
def azure_host(resource, module_name):
|
||||
name = resource['primary']['attributes']['name']
|
||||
raw_attrs = resource['primary']['attributes']
|
||||
|
||||
groups = []
|
||||
|
||||
attrs = {
|
||||
'automatic_updates': raw_attrs['automatic_updates'],
|
||||
'description': raw_attrs['description'],
|
||||
'hosted_service_name': raw_attrs['hosted_service_name'],
|
||||
'id': raw_attrs['id'],
|
||||
'image': raw_attrs['image'],
|
||||
'ip_address': raw_attrs['ip_address'],
|
||||
'location': raw_attrs['location'],
|
||||
'name': raw_attrs['name'],
|
||||
'reverse_dns': raw_attrs['reverse_dns'],
|
||||
'security_group': raw_attrs['security_group'],
|
||||
'size': raw_attrs['size'],
|
||||
'ssh_key_thumbprint': raw_attrs['ssh_key_thumbprint'],
|
||||
'subnet': raw_attrs['subnet'],
|
||||
'username': raw_attrs['username'],
|
||||
'vip_address': raw_attrs['vip_address'],
|
||||
'virtual_network': raw_attrs['virtual_network'],
|
||||
'endpoint': parse_attr_list(raw_attrs, 'endpoint'),
|
||||
# ansible
|
||||
'ansible_ssh_port': 22,
|
||||
'ansible_ssh_user': raw_attrs['username'],
|
||||
'ansible_ssh_host': raw_attrs['vip_address'],
|
||||
}
|
||||
|
||||
# attrs specific to mantl
|
||||
attrs.update({
|
||||
'consul_dc': attrs['location'].lower().replace(" ", "-"),
|
||||
'role': attrs['description']
|
||||
})
|
||||
|
||||
# groups specific to mantl
|
||||
groups.extend(['azure_image=' + attrs['image'],
|
||||
'azure_location=' + attrs['location'].lower().replace(" ", "-"),
|
||||
'azure_username=' + attrs['username'],
|
||||
'azure_security_group=' + attrs['security_group']])
|
||||
|
||||
# groups specific to mantl
|
||||
groups.append('role=' + attrs['role'])
|
||||
groups.append('dc=' + attrs['consul_dc'])
|
||||
|
||||
return name, attrs, groups
|
||||
|
||||
|
||||
@parses('clc_server')
|
||||
@calculate_mantl_vars
|
||||
def clc_server(resource, module_name):
|
||||
raw_attrs = resource['primary']['attributes']
|
||||
name = raw_attrs.get('id')
|
||||
groups = []
|
||||
md = parse_dict(raw_attrs, 'metadata')
|
||||
attrs = {
|
||||
'metadata': md,
|
||||
'ansible_ssh_port': md.get('ssh_port', 22),
|
||||
'ansible_ssh_user': md.get('ssh_user', 'root'),
|
||||
'provider': 'clc',
|
||||
'publicly_routable': False,
|
||||
}
|
||||
|
||||
try:
|
||||
attrs.update({
|
||||
'public_ipv4': raw_attrs['public_ip_address'],
|
||||
'private_ipv4': raw_attrs['private_ip_address'],
|
||||
'ansible_ssh_host': raw_attrs['public_ip_address'],
|
||||
'publicly_routable': True,
|
||||
})
|
||||
except (KeyError, ValueError):
|
||||
attrs.update({
|
||||
'ansible_ssh_host': raw_attrs['private_ip_address'],
|
||||
'private_ipv4': raw_attrs['private_ip_address'],
|
||||
})
|
||||
|
||||
attrs.update({
|
||||
'consul_dc': _clean_dc(attrs['metadata'].get('dc', module_name)),
|
||||
'role': attrs['metadata'].get('role', 'none'),
|
||||
})
|
||||
|
||||
groups.append('role=' + attrs['role'])
|
||||
groups.append('dc=' + attrs['consul_dc'])
|
||||
return name, attrs, groups
|
||||
|
||||
|
||||
def iter_host_ips(hosts, ips):
|
||||
'''Update hosts that have an entry in the floating IP list'''
|
||||
for host in hosts:
|
||||
host_id = host[1]['id']
|
||||
|
||||
if host_id in ips:
|
||||
ip = ips[host_id]
|
||||
|
||||
host[1].update({
|
||||
'access_ip_v4': ip,
|
||||
'access_ip': ip,
|
||||
'public_ipv4': ip,
|
||||
'ansible_ssh_host': ip,
|
||||
})
|
||||
|
||||
if 'use_access_ip' in host[1]['metadata'] and host[1]['metadata']['use_access_ip'] == "0":
|
||||
host[1].pop('access_ip')
|
||||
|
||||
yield host
|
||||
|
||||
|
||||
|
@ -13,7 +13,7 @@
|
||||
/usr/local/share/ca-certificates/vault-ca.crt
|
||||
{%- elif ansible_os_family == "RedHat" -%}
|
||||
/etc/pki/ca-trust/source/anchors/vault-ca.crt
|
||||
{%- elif ansible_os_family in ["CoreOS", "Container Linux by CoreOS"] -%}
|
||||
{%- elif ansible_os_family in ["Coreos", "Container Linux by CoreOS", "Flatcar", "Flatcar Container Linux by Kinvolk"] -%}
|
||||
/etc/ssl/certs/vault-ca.pem
|
||||
{%- endif %}
|
||||
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
- name: bootstrap/ca_trust | update ca-certificates (Debian/Ubuntu/CoreOS)
|
||||
command: update-ca-certificates
|
||||
when: vault_ca_cert.changed and ansible_os_family in ["Debian", "CoreOS", "Container Linux by CoreOS"]
|
||||
when: vault_ca_cert.changed and ansible_os_family in ["Debian", "CoreOS", "Coreos", "Container Linux by CoreOS", "Flatcar", "Flatcar Container Linux by Kinvolk"]
|
||||
|
||||
- name: bootstrap/ca_trust | update ca-certificates (RedHat)
|
||||
command: update-ca-trust extract
|
||||
|
@ -21,7 +21,7 @@
|
||||
- name: bootstrap/sync_secrets | Print out warning message if secrets are not available and vault is initialized
|
||||
pause:
|
||||
prompt: >
|
||||
Vault orchestration may not be able to proceed. The Vault cluster is initialzed, but
|
||||
Vault orchestration may not be able to proceed. The Vault cluster is initialized, but
|
||||
'root_token' or 'unseal_keys' were not found in {{ vault_secrets_dir }}. These are
|
||||
needed for many vault orchestration steps.
|
||||
when: vault_cluster_is_initialized and not vault_secrets_available
|
||||
|
@ -11,7 +11,7 @@
|
||||
until: vault_etcd_health_check.status == 200 or vault_etcd_health_check.status == 401
|
||||
retries: 3
|
||||
delay: 2
|
||||
delegate_to: "{{groups['etcd'][0]}}"
|
||||
delegate_to: "{{ groups['etcd'][0] }}"
|
||||
run_once: true
|
||||
failed_when: false
|
||||
register: vault_etcd_health_check
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
# Stop temporary Vault if it's running (can linger if playbook fails out)
|
||||
- name: stop vault-temp container
|
||||
shell: docker stop {{ vault_temp_container_name }} || rkt stop {{ vault_temp_container_name }}
|
||||
shell: docker stop {{ vault_temp_container_name }}
|
||||
failed_when: false
|
||||
register: vault_temp_stop
|
||||
changed_when: vault_temp_stop is succeeded
|
||||
|
@ -5,17 +5,19 @@
|
||||
set_fact:
|
||||
sync_file_dir: "{{ sync_file_path | dirname }}"
|
||||
sync_file: "{{ sync_file_path | basename }}"
|
||||
when: sync_file_path is defined and sync_file_path != ''
|
||||
when:
|
||||
- sync_file_path is defined
|
||||
- sync_file_path
|
||||
|
||||
- name: "sync_file | Set fact for sync_file_path when undefined"
|
||||
set_fact:
|
||||
sync_file_path: "{{ (sync_file_dir, sync_file)|join('/') }}"
|
||||
when: sync_file_path is not defined or sync_file_path == ''
|
||||
when: sync_file_path is not defined or not sync_file_path
|
||||
|
||||
- name: "sync_file | Set fact for key path name"
|
||||
set_fact:
|
||||
sync_file_key_path: "{{ sync_file_path.rsplit('.', 1)|first + '-key.' + sync_file_path.rsplit('.', 1)|last }}"
|
||||
when: sync_file_key_path is not defined or sync_file_key_path == ''
|
||||
when: sync_file_key_path is not defined or not sync_file_key_path
|
||||
|
||||
- name: "sync_file | Check if {{sync_file_path}} file exists"
|
||||
stat:
|
||||
@ -46,17 +48,17 @@
|
||||
- name: "sync_file | Remove sync sources with files that do not match sync_file_srcs|first"
|
||||
set_fact:
|
||||
_: "{% if inventory_hostname in sync_file_srcs %}{{ sync_file_srcs.remove(inventory_hostname) }}{% endif %}"
|
||||
when: >-
|
||||
sync_file_srcs|d([])|length > 1 and
|
||||
inventory_hostname != sync_file_srcs|first
|
||||
when:
|
||||
- sync_file_srcs|d([])|length > 1
|
||||
- inventory_hostname != sync_file_srcs|first
|
||||
|
||||
- name: "sync_file | Remove sync sources with keys that do not match sync_file_srcs|first"
|
||||
set_fact:
|
||||
_: "{% if inventory_hostname in sync_file_srcs %}{{ sync_file_srcs.remove(inventory_hostname) }}{% endif %}"
|
||||
when: >-
|
||||
sync_file_is_cert|d() and
|
||||
sync_file_key_srcs|d([])|length > 1 and
|
||||
inventory_hostname != sync_file_key_srcs|first
|
||||
when:
|
||||
- sync_file_is_cert|d()
|
||||
- sync_file_key_srcs|d([])|length > 1
|
||||
- inventory_hostname != sync_file_key_srcs|first
|
||||
|
||||
- name: "sync_file | Consolidate file and key sources"
|
||||
set_fact:
|
||||
|
@ -1,45 +0,0 @@
|
||||
[Unit]
|
||||
Description=hashicorp vault on rkt
|
||||
Documentation=https://github.com/hashicorp/vault
|
||||
Wants=network.target
|
||||
|
||||
[Service]
|
||||
User=root
|
||||
Restart=on-failure
|
||||
RestartSec=10s
|
||||
TimeoutStartSec=5
|
||||
LimitNOFILE=40000
|
||||
# Container has the following internal mount points:
|
||||
# /vault/file/ # File backend storage location
|
||||
# /vault/logs/ # Log files
|
||||
ExecStartPre=-/usr/bin/rkt rm --uuid-file=/var/run/vault.uuid
|
||||
|
||||
ExecStart=/usr/bin/rkt run \
|
||||
--insecure-options=image \
|
||||
--volume hosts,kind=host,source=/etc/hosts,readOnly=true \
|
||||
--mount volume=hosts,target=/etc/hosts \
|
||||
--volume=volume-vault-file,kind=host,source=/var/lib/vault \
|
||||
--volume=volume-vault-logs,kind=host,source={{ vault_log_dir }} \
|
||||
--volume=vault-cert-dir,kind=host,source={{ vault_cert_dir }} \
|
||||
--mount=volume=vault-cert-dir,target={{ vault_cert_dir }} \
|
||||
--volume=vault-conf-dir,kind=host,source={{ vault_config_dir }} \
|
||||
--mount=volume=vault-conf-dir,target={{ vault_config_dir }} \
|
||||
--volume=vault-secrets-dir,kind=host,source={{ vault_secrets_dir }} \
|
||||
--mount=volume=vault-secrets-dir,target={{ vault_secrets_dir }} \
|
||||
--volume=vault-roles-dir,kind=host,source={{ vault_roles_dir }} \
|
||||
--mount=volume=vault-roles-dir,target={{ vault_roles_dir }} \
|
||||
--volume=etcd-cert-dir,kind=host,source={{ etcd_cert_dir }} \
|
||||
--mount=volume=etcd-cert-dir,target={{ etcd_cert_dir }} \
|
||||
docker://{{ vault_image_repo }}:{{ vault_image_tag }} \
|
||||
--uuid-file-save=/var/run/vault.uuid \
|
||||
--name={{ vault_container_name }} \
|
||||
--net=host \
|
||||
--caps-retain=CAP_IPC_LOCK \
|
||||
--exec vault -- \
|
||||
server \
|
||||
--config={{ vault_config_dir }}/config.json
|
||||
|
||||
ExecStop=-/usr/bin/rkt stop --uuid-file=/var/run/vault.uuid
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -93,6 +93,6 @@ 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 the ability to start temp Vault with Host or Docker
|
||||
- Add a dynamic way to change out the backend role creation during Bootstrap,
|
||||
so other services can be used (such as Consul)
|
||||
|
@ -3,7 +3,6 @@
|
||||
* [Getting started](/docs/getting-started.md)
|
||||
* [Ansible](docs/ansible.md)
|
||||
* [Variables](/docs/vars.md)
|
||||
* [Ansible](/docs/ansible.md)
|
||||
* Operations
|
||||
* [Integration](docs/integration.md)
|
||||
* [Upgrades](/docs/upgrades.md)
|
||||
@ -20,6 +19,7 @@
|
||||
* [AWS](docs/aws.md)
|
||||
* [Azure](docs/azure.md)
|
||||
* [OpenStack](/docs/openstack.md)
|
||||
* [Packet](/docs/packet.md)
|
||||
* [vSphere](/docs/vsphere.md)
|
||||
* Operating Systems
|
||||
* [Atomic](docs/atomic.md)
|
||||
|
@ -1,9 +1,7 @@
|
||||
Ansible variables
|
||||
===============
|
||||
# Ansible variables
|
||||
|
||||
## Inventory
|
||||
|
||||
Inventory
|
||||
-------------
|
||||
The inventory is composed of 3 groups:
|
||||
|
||||
* **kube-node** : list of kubernetes nodes where the pods will run.
|
||||
@ -14,7 +12,7 @@ Note: do not modify the children of _k8s-cluster_, like putting
|
||||
the _etcd_ group into the _k8s-cluster_, unless you are certain
|
||||
to do that and you have it fully contained in the latter:
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
k8s-cluster ⊂ etcd => kube-node ∩ etcd = etcd
|
||||
```
|
||||
|
||||
@ -32,15 +30,15 @@ There are also two special groups:
|
||||
|
||||
Below is a complete inventory example:
|
||||
|
||||
```
|
||||
```ini
|
||||
## Configure 'ip' variable to bind kubernetes services on a
|
||||
## different ip than the default iface
|
||||
node1 ansible_ssh_host=95.54.0.12 ip=10.3.0.1
|
||||
node2 ansible_ssh_host=95.54.0.13 ip=10.3.0.2
|
||||
node3 ansible_ssh_host=95.54.0.14 ip=10.3.0.3
|
||||
node4 ansible_ssh_host=95.54.0.15 ip=10.3.0.4
|
||||
node5 ansible_ssh_host=95.54.0.16 ip=10.3.0.5
|
||||
node6 ansible_ssh_host=95.54.0.17 ip=10.3.0.6
|
||||
node1 ansible_host=95.54.0.12 ip=10.3.0.1
|
||||
node2 ansible_host=95.54.0.13 ip=10.3.0.2
|
||||
node3 ansible_host=95.54.0.14 ip=10.3.0.3
|
||||
node4 ansible_host=95.54.0.15 ip=10.3.0.4
|
||||
node5 ansible_host=95.54.0.16 ip=10.3.0.5
|
||||
node6 ansible_host=95.54.0.17 ip=10.3.0.6
|
||||
|
||||
[kube-master]
|
||||
node1
|
||||
@ -63,17 +61,16 @@ kube-node
|
||||
kube-master
|
||||
```
|
||||
|
||||
Group vars and overriding variables precedence
|
||||
----------------------------------------------
|
||||
## Group vars and overriding variables precedence
|
||||
|
||||
The group variables to control main deployment options are located in the directory ``inventory/sample/group_vars``.
|
||||
Optional variables are located in the `inventory/sample/group_vars/all.yml`.
|
||||
Mandatory variables that are common for at least one role (or a node group) can be found in the
|
||||
`inventory/sample/group_vars/k8s-cluster.yml`.
|
||||
There are also role vars for docker, rkt, kubernetes preinstall and master roles.
|
||||
There are also role vars for docker, 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 overridden from the group vars. In order to override, one should use
|
||||
the `-e ` runtime flags (most simple way) or other layers described in the docs.
|
||||
the `-e` runtime flags (most simple way) or other layers described in the docs.
|
||||
|
||||
Kubespray uses only a few layers to override things (or expect them to
|
||||
be overridden for roles):
|
||||
@ -97,8 +94,8 @@ block vars (only for tasks in block) | Kubespray overrides for internal roles' l
|
||||
task vars (only for the task) | Unused for roles, but only for helper scripts
|
||||
**extra vars** (always win precedence) | override with ``ansible-playbook -e @foo.yml``
|
||||
|
||||
Ansible tags
|
||||
------------
|
||||
## Ansible tags
|
||||
|
||||
The following tags are defined in playbooks:
|
||||
|
||||
| Tag name | Used for
|
||||
@ -145,21 +142,25 @@ Note: Use the ``bash scripts/gen_tags.sh`` command to generate a list of all
|
||||
tags found in the codebase. New tags will be listed with the empty "Used for"
|
||||
field.
|
||||
|
||||
Example commands
|
||||
----------------
|
||||
## Example commands
|
||||
|
||||
Example command to filter and apply only DNS configuration tasks and skip
|
||||
everything else related to host OS configuration and downloading images of containers:
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
ansible-playbook -i inventory/sample/hosts.ini cluster.yml --tags preinstall,facts --skip-tags=download,bootstrap-os
|
||||
```
|
||||
|
||||
And this play only removes the K8s cluster DNS resolver IP from hosts' /etc/resolv.conf files:
|
||||
```
|
||||
|
||||
```ShellSession
|
||||
ansible-playbook -i inventory/sample/hosts.ini -e dns_mode='none' cluster.yml --tags resolvconf
|
||||
```
|
||||
|
||||
And this prepares all container images locally (at the ansible runner node) without installing
|
||||
or upgrading related stuff or trying to upload container to K8s cluster nodes:
|
||||
```
|
||||
|
||||
```ShellSession
|
||||
ansible-playbook -i inventory/sample/hosts.ini cluster.yml \
|
||||
-e download_run_once=true -e download_localhost=true \
|
||||
--tags download --skip-tags upload,upgrade
|
||||
@ -167,15 +168,16 @@ ansible-playbook -i inventory/sample/hosts.ini cluster.yml \
|
||||
|
||||
Note: use `--tags` and `--skip-tags` wise and only if you're 100% sure what you're doing.
|
||||
|
||||
Bastion host
|
||||
--------------
|
||||
## Bastion host
|
||||
|
||||
If you prefer to not make your nodes publicly accessible (nodes with private IPs only),
|
||||
you can use a so called *bastion* host to connect to your nodes. To specify and use a bastion,
|
||||
simply add a line to your inventory, where you have to replace x.x.x.x with the public IP of the
|
||||
bastion host.
|
||||
|
||||
```
|
||||
bastion ansible_ssh_host=x.x.x.x
|
||||
```ShellSession
|
||||
[bastion]
|
||||
bastion ansible_host=x.x.x.x
|
||||
```
|
||||
|
||||
For more information about Ansible and bastion hosts, read
|
||||
|
17
docs/arch.md
Normal file
17
docs/arch.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Architecture compatibility
|
||||
|
||||
The following table shows the impact of the CPU architecture on compatible features:
|
||||
|
||||
- amd64: Cluster using only x86/amd64 CPUs
|
||||
- arm64: Cluster using only arm64 CPUs
|
||||
- amd64 + arm64: Cluster with a mix of x86/amd64 and arm64 CPUs
|
||||
|
||||
| kube_network_plugin | amd64 | arm64 | amd64 + arm64 |
|
||||
| ------------------- | ----- | ----- | ------------- |
|
||||
| Calico | Y | Y | Y |
|
||||
| Weave | Y | Y | Y |
|
||||
| Flannel | Y | N | N |
|
||||
| Canal | Y | N | N |
|
||||
| Cilium | Y | N | N |
|
||||
| Contib | Y | N | N |
|
||||
| kube-router | Y | N | N |
|
@ -1,23 +1,22 @@
|
||||
Atomic host bootstrap
|
||||
=====================
|
||||
# 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
|
||||
## Vagrant
|
||||
|
||||
* For bootstrapping with Vagrant, use box centos/atomic-host or fedora/atomic-host
|
||||
* For bootstrapping with Vagrant, use box centos/atomic-host or fedora/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.
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
vagrant ssh
|
||||
sudo /sbin/ifup enp0s8
|
||||
```
|
||||
|
||||
* For users of vagrant-libvirt download centos/atomic-host qcow2 format from https://wiki.centos.org/SpecialInterestGroup/Atomic/Download/
|
||||
* For users of vagrant-libvirt download fedora/atomic-host qcow2 format from https://getfedora.org/en/atomic/download/
|
||||
* For users of vagrant-libvirt download centos/atomic-host qcow2 format from <https://wiki.centos.org/SpecialInterestGroup/Atomic/Download/>
|
||||
* For users of vagrant-libvirt download fedora/atomic-host qcow2 format from <https://dl.fedoraproject.org/pub/alt/atomic/stable/>
|
||||
|
||||
Then you can proceed to [cluster deployment](#run-deployment)
|
||||
|
17
docs/aws.md
17
docs/aws.md
@ -1,11 +1,10 @@
|
||||
AWS
|
||||
===============
|
||||
# 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'`. Refer to the [Kubespray Configuration](#kubespray-configuration) for customizing the provider.
|
||||
|
||||
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-sigs/kubespray/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.
|
||||
|
||||
You would also need to tag the resources in your VPC accordingly for the aws provider to utilize them. Tag the subnets, route tables and all instances that kubernetes will be run on with key `kubernetes.io/cluster/$cluster_name` (`$cluster_name` must be a unique identifier for the cluster). Tag the subnets that must be targetted by external ELBs with the key `kubernetes.io/role/elb` and internal ELBs with the key `kubernetes.io/role/internal-elb`.
|
||||
You would also need to tag the resources in your VPC accordingly for the aws provider to utilize them. Tag the subnets, route tables and all instances that kubernetes will be run on with key `kubernetes.io/cluster/$cluster_name` (`$cluster_name` must be a unique identifier for the cluster). Tag the subnets that must be targeted by external ELBs with the key `kubernetes.io/role/elb` and internal ELBs with the key `kubernetes.io/role/internal-elb`.
|
||||
|
||||
Make sure your VPC has both DNS Hostnames support and Private DNS enabled.
|
||||
|
||||
@ -13,11 +12,13 @@ The next step is to make sure the hostnames in your `inventory` file are identic
|
||||
|
||||
You can now create your cluster!
|
||||
|
||||
### Dynamic Inventory ###
|
||||
## Dynamic Inventory
|
||||
|
||||
There is also a dynamic inventory script for AWS that can be used if desired. However, be aware that it makes some certain assumptions about how you'll create your inventory. It also does not handle all use cases and groups that we may use as part of more advanced deployments. Additions welcome.
|
||||
|
||||
This will produce an inventory that is passed into Ansible that looks like the following:
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"_meta": {
|
||||
"hostvars": {
|
||||
@ -48,15 +49,18 @@ This will produce an inventory that is passed into Ansible that looks like the f
|
||||
```
|
||||
|
||||
Guide:
|
||||
|
||||
- Create instances in AWS as needed.
|
||||
- Either during or after creation, add tags to the instances with a key of `kubespray-role` and a value of `kube-master`, `etcd`, or `kube-node`. You can also share roles like `kube-master, etcd`
|
||||
- Copy the `kubespray-aws-inventory.py` script from `kubespray/contrib/aws_inventory` to the `kubespray/inventory` directory.
|
||||
- Set the following AWS credentials and info as environment variables in your terminal:
|
||||
```
|
||||
|
||||
```ShellSession
|
||||
export AWS_ACCESS_KEY_ID="xxxxx"
|
||||
export AWS_SECRET_ACCESS_KEY="yyyyy"
|
||||
export REGION="us-east-2"
|
||||
```
|
||||
|
||||
- We will now create our cluster. There will be either one or two small changes. The first is that we will specify `-i inventory/kubespray-aws-inventory.py` as our inventory script. The other is conditional. If your AWS instances are public facing, you can set the `VPC_VISIBILITY` variable to `public` and that will result in public IP and DNS names being passed into the inventory. This causes your cluster.yml command to look like `VPC_VISIBILITY="public" ansible-playbook ... cluster.yml`
|
||||
|
||||
## Kubespray configuration
|
||||
@ -75,4 +79,3 @@ aws_kubernetes_cluster_id|string|KubernetesClusterID is the cluster id we'll use
|
||||
aws_disable_security_group_ingress|bool|The aws provider creates an inbound rule per load balancer on the node security group. However, this can run into the AWS security group rule limit of 50 if many LoadBalancers are created. This flag disables the automatic ingress creation. It requires that the user has setup a rule that allows inbound traffic on kubelet ports from the local VPC subnet (so load balancers can access it). E.g. 10.82.0.0/16 30000-32000.
|
||||
aws_elb_security_group|string|Only in Kubelet version >= 1.7 : AWS has a hard limit of 500 security groups. For large clusters creating a security group for each ELB can cause the max number of security groups to be reached. If this is set instead of creating a new Security group for each ELB this security group will be used instead.
|
||||
aws_disable_strict_zone_check|bool|During the instantiation of an new AWS cloud provider, the detected region is validated against a known set of regions. In a non-standard, AWS like environment (e.g. Eucalyptus), this check may be undesirable. Setting this to true will disable the check and provide a warning that the check was skipped. Please note that this is an experimental feature and work-in-progress for the moment.
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
Azure
|
||||
===============
|
||||
# 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'`.
|
||||
|
||||
@ -7,49 +6,77 @@ All your instances are required to run in a resource group and a routing table h
|
||||
|
||||
Not all features are supported yet though, for a list of the current status have a look [here](https://github.com/colemickens/azure-kubernetes-status)
|
||||
|
||||
### Parameters
|
||||
## Parameters
|
||||
|
||||
Before creating the instances you must first set the `azure_` variables in the `group_vars/all.yml` file.
|
||||
|
||||
All of the values can be retrieved using the azure cli tool which can be downloaded here: https://docs.microsoft.com/en-gb/azure/xplat-cli-install
|
||||
All of the values can be retrieved using the azure cli tool which can be downloaded here: <https://docs.microsoft.com/en-gb/azure/xplat-cli-install>
|
||||
After installation you have to run `azure login` to get access to your account.
|
||||
|
||||
### azure\_tenant\_id + azure\_subscription\_id
|
||||
|
||||
#### azure\_tenant\_id + azure\_subscription\_id
|
||||
run `azure account show` to retrieve your subscription id and tenant id:
|
||||
`azure_tenant_id` -> Tenant ID field
|
||||
`azure_subscription_id` -> ID field
|
||||
|
||||
### azure\_location
|
||||
|
||||
#### azure\_location
|
||||
The region your instances are located, can be something like `westeurope` or `westcentralus`. A full list of region names can be retrieved via `azure location list`
|
||||
|
||||
### azure\_resource\_group
|
||||
|
||||
#### azure\_resource\_group
|
||||
The name of the resource group your instances are in, can be retrieved via `azure group list`
|
||||
|
||||
#### azure\_vnet\_name
|
||||
### azure\_vnet\_name
|
||||
|
||||
The name of the virtual network your instances are in, can be retrieved via `azure network vnet list`
|
||||
|
||||
#### azure\_subnet\_name
|
||||
The name of the subnet your instances are in, can be retrieved via `azure network vnet subnet list RESOURCE_GROUP VNET_NAME`
|
||||
### azure\_subnet\_name
|
||||
|
||||
The name of the subnet your instances are in, can be retrieved via `azure network vnet subnet list --resource-group RESOURCE_GROUP --vnet-name VNET_NAME`
|
||||
|
||||
### azure\_security\_group\_name
|
||||
|
||||
#### azure\_security\_group\_name
|
||||
The name of the network security group your instances are in, can be retrieved via `azure network nsg list`
|
||||
|
||||
#### azure\_aad\_client\_id + azure\_aad\_client\_secret
|
||||
### azure\_aad\_client\_id + azure\_aad\_client\_secret
|
||||
|
||||
These will have to be generated first:
|
||||
|
||||
- Create an Azure AD Application with:
|
||||
`azure ad app create --name kubernetes --identifier-uris http://kubernetes --home-page http://example.com --password CLIENT_SECRET`
|
||||
The name, identifier-uri, home-page and the password can be choosen
|
||||
`azure ad app create --display-name kubernetes --identifier-uris http://kubernetes --homepage http://example.com --password CLIENT_SECRET`
|
||||
display name, identifier-uri, homepage and the password can be chosen
|
||||
Note the AppId in the output.
|
||||
- Create Service principal for the application with:
|
||||
`azure ad sp create --applicationId AppId`
|
||||
`azure ad sp create --id AppId`
|
||||
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 role assignment create --role "Owner" --assignee http://kubernetes --subscription SUBSCRIPTION_ID`
|
||||
|
||||
azure\_aad\_client\_id must be set to the AppId, azure\_aad\_client\_secret is your choosen secret.
|
||||
azure\_aad\_client\_id must be set to the AppId, azure\_aad\_client\_secret is your chosen secret.
|
||||
|
||||
### azure\_loadbalancer\_sku
|
||||
|
||||
Sku of Load Balancer and Public IP. Candidate values are: basic and standard.
|
||||
|
||||
### azure\_exclude\_master\_from\_standard\_lb
|
||||
|
||||
azure\_exclude\_master\_from\_standard\_lb excludes master nodes from `standard` load balancer.
|
||||
|
||||
### azure\_disable\_outbound\_snat
|
||||
|
||||
azure\_disable\_outbound\_snat disables the outbound SNAT for public load balancer rules. It should only be set when azure\_exclude\_master\_from\_standard\_lb is `standard`.
|
||||
|
||||
### azure\_primary\_availability\_set\_name
|
||||
|
||||
(Optional) The name of the availability set that should be used as the load balancer backend .If this is set, the Azure
|
||||
cloudprovider will only add nodes from that availability set to the load balancer backend pool. If this is not set, and
|
||||
multiple agent pools (availability sets) are used, then the cloudprovider will try to add all nodes to a single backend
|
||||
pool which is forbidden. In other words, if you use multiple agent pools (availability sets), you MUST set this field.
|
||||
|
||||
### azure\_use\_instance\_metadata
|
||||
|
||||
Use instance metadata service where possible
|
||||
|
||||
## Provisioning Azure with Resource Group Templates
|
||||
|
||||
|
@ -1,82 +1,83 @@
|
||||
Calico
|
||||
===========
|
||||
# Calico
|
||||
|
||||
---
|
||||
**N.B. Version 2.6.5 upgrade to 3.1.1 is upgrading etcd store to etcdv3**
|
||||
If you create automated backups of etcdv2 please switch for creating etcdv3 backups, as kubernetes and calico now uses etcdv3
|
||||
N.B. **Version 2.6.5 upgrade to 3.1.1 is upgrading etcd store to etcdv3**
|
||||
|
||||
If you create automated backups of etcdv2 please switch for creating etcdv3 backups, as kubernetes and calico now uses etcdv3
|
||||
After migration you can check `/tmp/calico_upgrade/` directory for converted items to etcdv3.
|
||||
**PLEASE TEST upgrade before upgrading production cluster.**
|
||||
---
|
||||
|
||||
Check if the calico-node container is running
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
docker ps | grep calico
|
||||
```
|
||||
|
||||
The **calicoctl** command allows to check the status of the network workloads.
|
||||
|
||||
* Check the status of Calico nodes
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
calicoctl node status
|
||||
```
|
||||
|
||||
or for versions prior to *v1.0.0*:
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
calicoctl status
|
||||
```
|
||||
|
||||
* Show the configured network subnet for containers
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
calicoctl get ippool -o wide
|
||||
```
|
||||
|
||||
or for versions prior to *v1.0.0*:
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
calicoctl pool show
|
||||
```
|
||||
|
||||
* Show the workloads (ip addresses of containers and their located)
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
calicoctl get workloadEndpoint -o wide
|
||||
```
|
||||
|
||||
and
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
calicoctl get hostEndpoint -o wide
|
||||
```
|
||||
|
||||
or for versions prior *v1.0.0*:
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
calicoctl endpoint show --detail
|
||||
```
|
||||
|
||||
##### Optional : Define network backend
|
||||
## Configuration
|
||||
|
||||
### Optional : Define network backend
|
||||
|
||||
In some cases you may want to define Calico network backend. Allowed values are 'bird', 'gobgp' or 'none'. Bird is a default value.
|
||||
|
||||
To re-define you need to edit the inventory and add a group variable `calico_network_backend`
|
||||
|
||||
```
|
||||
```yml
|
||||
calico_network_backend: none
|
||||
```
|
||||
|
||||
##### Optional : Define the default pool CIDR
|
||||
### Optional : Define the default pool CIDR
|
||||
|
||||
By default, `kube_pods_subnet` is used as the IP range CIDR for the default IP Pool.
|
||||
In some cases you may want to add several pools and not have them considered by Kubernetes as external (which means that they must be within or equal to the range defined in `kube_pods_subnet`), it starts with the default IP Pool of which IP range CIDR can by defined in group_vars (k8s-cluster/k8s-net-calico.yml):
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
calico_pool_cidr: 10.233.64.0/20
|
||||
```
|
||||
|
||||
##### Optional : BGP Peering with border routers
|
||||
### Optional : BGP Peering with border routers
|
||||
|
||||
In some cases you may want to route the pods subnet and so NAT is not needed on the nodes.
|
||||
For instance if you have a cluster spread on different locations and you want your pods to talk each other no matter where they are located.
|
||||
@ -84,11 +85,11 @@ The following variables need to be set:
|
||||
`peer_with_router` to enable the peering with the datacenter's border router (default value: false).
|
||||
you'll need to edit the inventory and add a hostvar `local_as` by node.
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
node1 ansible_ssh_host=95.54.0.12 local_as=xxxxxx
|
||||
```
|
||||
|
||||
##### Optional : Defining BGP peers
|
||||
### Optional : Defining BGP peers
|
||||
|
||||
Peers can be defined using the `peers` variable (see docs/calico_peer_example examples).
|
||||
In order to define global peers, the `peers` variable can be defined in group_vars with the "scope" attribute of each global peer set to "global".
|
||||
@ -97,16 +98,17 @@ NB: Ansible's `hash_behaviour` is by default set to "replace", thus defining bot
|
||||
|
||||
Since calico 3.4, Calico supports advertising Kubernetes service cluster IPs over BGP, just as it advertises pod IPs.
|
||||
This can be enabled by setting the following variable as follow in group_vars (k8s-cluster/k8s-net-calico.yml)
|
||||
```
|
||||
|
||||
```yml
|
||||
calico_advertise_cluster_ips: true
|
||||
```
|
||||
|
||||
##### Optional : Define global AS number
|
||||
### Optional : Define global AS number
|
||||
|
||||
Optional parameter `global_as_num` defines Calico global AS number (`/calico/bgp/v1/global/as_num` etcd key).
|
||||
It defaults to "64512".
|
||||
|
||||
##### Optional : BGP Peering with route reflectors
|
||||
### Optional : BGP Peering with route reflectors
|
||||
|
||||
At large scale you may want to disable full node-to-node mesh in order to
|
||||
optimize your BGP topology and improve `calico-node` containers' start times.
|
||||
@ -114,20 +116,20 @@ optimize your BGP topology and improve `calico-node` containers' start times.
|
||||
To do so you can deploy BGP route reflectors and peer `calico-node` with them as
|
||||
recommended here:
|
||||
|
||||
* https://hub.docker.com/r/calico/routereflector/
|
||||
* https://docs.projectcalico.org/v3.1/reference/private-cloud/l3-interconnect-fabric
|
||||
* <https://hub.docker.com/r/calico/routereflector/>
|
||||
* <https://docs.projectcalico.org/v3.1/reference/private-cloud/l3-interconnect-fabric>
|
||||
|
||||
You need to edit your inventory and add:
|
||||
|
||||
* `calico-rr` group with nodes in it. At the moment it's incompatible with
|
||||
`kube-node` due to BGP port conflict with `calico-node` container. So you
|
||||
should not have nodes in both `calico-rr` and `kube-node` groups.
|
||||
* `calico-rr` group with nodes in it. `calico-rr` can be combined with
|
||||
`kube-node` and/or `kube-master`. `calico-rr` group also must be a child
|
||||
group of `k8s-cluster` group.
|
||||
* `cluster_id` by route reflector node/group (see details
|
||||
[here](https://hub.docker.com/r/calico/routereflector/))
|
||||
|
||||
Here's an example of Kubespray inventory with route reflectors:
|
||||
Here's an example of Kubespray inventory with standalone route reflectors:
|
||||
|
||||
```
|
||||
```ini
|
||||
[all]
|
||||
rr0 ansible_ssh_host=10.210.1.10 ip=10.210.1.10
|
||||
rr1 ansible_ssh_host=10.210.1.11 ip=10.210.1.11
|
||||
@ -154,6 +156,7 @@ node5
|
||||
[k8s-cluster:children]
|
||||
kube-node
|
||||
kube-master
|
||||
calico-rr
|
||||
|
||||
[calico-rr]
|
||||
rr0
|
||||
@ -176,35 +179,35 @@ 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 kubespray) 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) within the same node are dropped.
|
||||
### 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 kubespray) 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) within the same node are dropped.
|
||||
|
||||
To re-define default action please set the following variable in your inventory:
|
||||
```
|
||||
|
||||
```yml
|
||||
calico_endpoint_to_host_action: "ACCEPT"
|
||||
```
|
||||
|
||||
##### Optional : Define address on which Felix will respond to health requests
|
||||
## Optional : Define address on which Felix will respond to health requests
|
||||
|
||||
Since Calico 3.2.0, HealthCheck default behavior changed from listening on all interfaces to just listening on localhost.
|
||||
|
||||
To re-define health host please set the following variable in your inventory:
|
||||
```
|
||||
|
||||
```yml
|
||||
calico_healthhost: "0.0.0.0"
|
||||
```
|
||||
|
||||
Cloud providers configuration
|
||||
=============================
|
||||
## Cloud providers configuration
|
||||
|
||||
Please refer to the official documentation, for example [GCE configuration](http://docs.projectcalico.org/v1.5/getting-started/docker/installation/gce) requires a security rule for calico ip-ip tunnels. Note, calico is always configured with ``ipip: true`` if the cloud provider was defined.
|
||||
|
||||
##### Optional : Ignore kernel's RPF check setting
|
||||
### Optional : Ignore kernel's RPF check setting
|
||||
|
||||
By default the felix agent(calico-node) will abort if the Kernel RPF setting is not 'strict'. If you want Calico to ignore the Kernel setting:
|
||||
|
||||
```
|
||||
```yml
|
||||
calico_node_ignorelooserpf: true
|
||||
```
|
||||
|
||||
@ -212,7 +215,7 @@ Note that in OpenStack you must allow `ipip` traffic in your security groups,
|
||||
otherwise you will experience timeouts.
|
||||
To do this you must add a rule which allows it, for example:
|
||||
|
||||
```
|
||||
```ShellSession
|
||||
neutron security-group-rule-create --protocol 4 --direction egress k8s-a0tp4t
|
||||
neutron security-group-rule-create --protocol 4 --direction igress k8s-a0tp4t
|
||||
```
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user