Compare commits
1053 Commits
Author | SHA1 | Date | |
---|---|---|---|
b39a196cfb | |||
9fc14b3e6c | |||
f9a7dce7ca | |||
fbbbd90732 | |||
9869b46432 | |||
6cd33700f5 | |||
a1f04e9869 | |||
961149b865 | |||
597c810ef0 | |||
2de6a5676d | |||
050578da94 | |||
5a437add01 | |||
6fc73e3038 | |||
d97e9b9e50 | |||
fa0eb11bf4 | |||
f660c29348 | |||
6613895de0 | |||
803d52ffce | |||
fc61f8d52e | |||
0553814b4f | |||
f1566cb8c2 | |||
c1ba8e1b3a | |||
2ff7ab8d40 | |||
93698a8f73 | |||
6245587dc8 | |||
2faf53b039 | |||
e0b1787740 | |||
9849dba5d3 | |||
03c9c091f2 | |||
5a8b68a429 | |||
34d88ea6d9 | |||
0665b45e61 | |||
648fcf3a2e | |||
058438a25d | |||
6e938a3106 | |||
2f93d62aa5 | |||
8ba3d7ec75 | |||
9e2d282709 | |||
706c7cb4f1 | |||
5884eeb606 | |||
e7ee19bd66 | |||
2f8fc92182 | |||
f59d3fc4a3 | |||
8e2bae0f2a | |||
e6dae03a0d | |||
2f2ed116f7 | |||
e91c6a7bd1 | |||
1ff95e85f4 | |||
36924b63dc | |||
0c80d3d9fa | |||
411510cbe6 | |||
6e2b8a5750 | |||
ca66a96d0a | |||
0c09ec5d13 | |||
a8e2110b2d | |||
250541d29d | |||
142b9e1eff | |||
f204212963 | |||
91ae87fa60 | |||
85646c96ad | |||
d6456d13c2 | |||
98f7485303 | |||
a42d811420 | |||
bf6fdce339 | |||
fa378f09c3 | |||
d9d11e2291 | |||
73b2683697 | |||
d8a749fd27 | |||
f2d2d080f6 | |||
78ceef6b15 | |||
ca8e59fa85 | |||
b0210567aa | |||
33ec13293b | |||
bedb411d06 | |||
ef3e98807e | |||
49158dbe40 | |||
35682b5228 | |||
9cc70e9e70 | |||
50598d9d47 | |||
fc23f37af7 | |||
bfe143808f | |||
91742055e0 | |||
6c41f64a98 | |||
e72dbf3dfc | |||
c3b78c3255 | |||
fb666c44b3 | |||
58b5bf7886 | |||
cc70200a07 | |||
ffbd98fec6 | |||
f3c17361da | |||
bdf0238328 | |||
39b907cdfb | |||
24a7878e7c | |||
2364a84579 | |||
c6e5be91e9 | |||
ce22c0e6a4 | |||
bd60df97aa | |||
94df580674 | |||
90e5f8ffe1 | |||
bf6168fca8 | |||
a78e861a89 | |||
3550e3c145 | |||
8425c2363b | |||
15ec44901d | |||
924cc11af6 | |||
0fa5a252b9 | |||
fe46349786 | |||
96a2b386f2 | |||
214e08f8c9 | |||
8bd3b50e31 | |||
b8c4bd200e | |||
e70f27dd79 | |||
b680cdd0e4 | |||
c9f63e5016 | |||
d8a197ca51 | |||
1f9841f609 | |||
aa21edeb53 | |||
eb69f126de | |||
70edccf7e0 | |||
4b80a7f6fe | |||
e06e6895da | |||
50fc82acdc | |||
ea67bb6e41 | |||
b19f2e2d3d | |||
9c48f666ec | |||
4990eec4a2 | |||
bf8c8976dd | |||
a7ec0ed587 | |||
1a1fe99669 | |||
8818073ff3 | |||
b35e6558bc | |||
5e22574402 | |||
e1873ab872 | |||
29312a3ec0 | |||
feeb701c13 | |||
b347aefd61 | |||
abfa1636e4 | |||
deca5ec903 | |||
05b9f14b76 | |||
4cb576da19 | |||
8cb644fbec | |||
22996babcf | |||
75ad868cbd | |||
9433fe46c8 | |||
935c5093e2 | |||
6bb47d8adb | |||
57eefdd458 | |||
060d25fc79 | |||
4ce970c0b2 | |||
017df7113d | |||
00fe3d5094 | |||
bcac3c62a2 | |||
2a82dff3ae | |||
16ec5939c2 | |||
b064274e27 | |||
ae003af262 | |||
f515898cb5 | |||
25bab0e976 | |||
8213b1802b | |||
4c1e0b188d | |||
09b23f96d7 | |||
56f389a9f3 | |||
45e12df8a3 | |||
1892cd65f6 | |||
d3ca9d1db9 | |||
16ad344c41 | |||
8ca2a9a7d5 | |||
93cbcb61b8 | |||
276c450759 | |||
a6a6e843af | |||
f54f63ec3f | |||
93951f2ed5 | |||
c29b21717d | |||
80d16e6c91 | |||
68cfb9a053 | |||
d50fe9550c | |||
8f5c4dcd2e | |||
1a802726d2 | |||
90c867b424 | |||
eeb77369cb | |||
69a48cbdd7 | |||
33b8ad0d89 | |||
605cfeb3e4 | |||
c6588856c7 | |||
dba645421f | |||
f437ac0b27 | |||
8ec6729cae | |||
19d4b5dd04 | |||
78251b0304 | |||
10e54eca26 | |||
a8740c6e13 | |||
06391b6dd9 | |||
8dc01df60b | |||
a9de6dde33 | |||
75571ed303 | |||
1912df7e3e | |||
bacbb2a0ca | |||
e1ba25a4fb | |||
10a17cfe54 | |||
5a311236c4 | |||
a7b8708dfc | |||
8964dc53df | |||
ecc3a0aec5 | |||
144743e818 | |||
7712bd0c76 | |||
101686c665 | |||
f2ca929a4a | |||
13f2b3d134 | |||
50204d9551 | |||
6852f821a5 | |||
953bc8dee2 | |||
9afd3f0c32 | |||
3f443f3878 | |||
5dd85197af | |||
764a851189 | |||
b98cb74f5e | |||
750db9139a | |||
f2c8b393e1 | |||
fd59556222 | |||
0b54e8e04c | |||
85b3526617 | |||
7ff8fc259b | |||
cc507d7ace | |||
7c0fbe2959 | |||
6bc60e021e | |||
54816f1217 | |||
be3283c9ba | |||
249b0a2a80 | |||
71d476b121 | |||
45d8797dce | |||
b6e21a18cc | |||
f959cc296f | |||
ab44beba17 | |||
b2a0b649fd | |||
6179405e84 | |||
83d945127f | |||
1be15a0864 | |||
41b44739b1 | |||
38ca58ae8d | |||
fd7829d468 | |||
d62836f2ab | |||
4fd03b93f7 | |||
1617a6ea8e | |||
e9ce7243b8 | |||
d036a04d4d | |||
35ad57674e | |||
437189c213 | |||
0f5fd1edc0 | |||
b5aaaf864d | |||
d948839320 | |||
a5af58c05a | |||
d8a61b94a9 | |||
fda05df5f1 | |||
3997aa9a0f | |||
81292f9cf3 | |||
167e293594 | |||
1f9ccfe54d | |||
d3d0360526 | |||
826b0f384d | |||
a3131e271a | |||
ed12936be2 | |||
7c00ce5f30 | |||
c87bd53352 | |||
af1c93cdfc | |||
9ce7fc9b2c | |||
b6243bfc1c | |||
21ea079896 | |||
93579773d6 | |||
0bd23f720d | |||
dca3bf0e80 | |||
c605a05c6b | |||
c44f13114f | |||
ef7076e36f | |||
324106e91e | |||
218b2a5992 | |||
61e7afa9f0 | |||
367566adaa | |||
c06f482901 | |||
965fe1db94 | |||
f6be326feb | |||
c58e5e80ce | |||
641a2a8bb4 | |||
7d497e46c5 | |||
d414588a47 | |||
79de8ff169 | |||
38daee41d5 | |||
f8f55bc413 | |||
7457ce7f2d | |||
01dbc909be | |||
0512c22607 | |||
f0d5a96464 | |||
361645e8b6 | |||
353d44a4a6 | |||
680aa60429 | |||
6b3cf8c4b8 | |||
e41766fd58 | |||
e4c820c35e | |||
db5f83f8c9 | |||
412d560bcf | |||
a468954519 | |||
a3d3f27aaa | |||
72b68c7f82 | |||
28333d4513 | |||
ed8c0ee95a | |||
724a316204 | |||
d70cafc1e4 | |||
18c8e0a14a | |||
3ff6a2e7ff | |||
1ee3ff738e | |||
52edd4c9bc | |||
d8345c5eae | |||
98e7a07fba | |||
3d5988577a | |||
69603aed34 | |||
299e35ebe4 | |||
6674be2572 | |||
cf1566e8ed | |||
c6d91b89d7 | |||
b44f7957d5 | |||
aead0e3a69 | |||
b0484fe3e5 | |||
b8cd9403df | |||
d7df577898 | |||
09bccc97ba | |||
1c187e9729 | |||
8939196f0d | |||
15be42abfd | |||
ca45d5ffbe | |||
2bec26dba5 | |||
03c8d0113c | |||
536606c2ed | |||
6e29a47784 | |||
826a440fa6 | |||
baff4e61cf | |||
4d7eca7d2e | |||
32fec3bb74 | |||
3134dd4c0d | |||
56a9c7a802 | |||
bfa468c771 | |||
6318bb9f96 | |||
8618a3119b | |||
27a268df33 | |||
7930f6fa0a | |||
49bd208026 | |||
83fe607f62 | |||
ea8b799ff0 | |||
e2d6f8d897 | |||
0924c2510c | |||
065292f8a4 | |||
35f248dff0 | |||
b09fe64ff1 | |||
54debdbda2 | |||
b6341287bb | |||
6a92e34994 | |||
00efc63f74 | |||
b061cce913 | |||
c929b5e82e | |||
58f48500b1 | |||
b5125e59ab | |||
d316b02d28 | |||
7910198b93 | |||
7b2f35c7d4 | |||
45874a23bb | |||
9c3b573f8e | |||
7d6ef61491 | |||
6a7c3c6e3f | |||
883194afec | |||
3a63aa6b1e | |||
337499d772 | |||
82123f3c4e | |||
8f3d820664 | |||
7d812f8112 | |||
473a8beff0 | |||
0d675cdd1a | |||
9cce46ea8c | |||
2e67289473 | |||
980aeafebe | |||
7d1ab3374e | |||
01b9b263ed | |||
c33a049292 | |||
7eaa7c957a | |||
f055ba7965 | |||
157c247563 | |||
a35b6dc1af | |||
910a821d0b | |||
2c21e7bd3a | |||
45a177e2a0 | |||
0c51352a74 | |||
9b1980cfff | |||
ae29296e20 | |||
75e743bfae | |||
2f19d964f6 | |||
0d2990510e | |||
e732df56a1 | |||
2f92d6bca3 | |||
c72903e8d6 | |||
ded58d3b66 | |||
be9414fabe | |||
033afe1574 | |||
c35461a005 | |||
a93421019b | |||
4fd3e2ece7 | |||
937adec515 | |||
bce3f282f1 | |||
f8ad44a99f | |||
7ee2f0d918 | |||
9cbb373ae2 | |||
484df62c5a | |||
79a6b72a13 | |||
d439564a7e | |||
b0a5f265e3 | |||
8800eb3492 | |||
09308d6125 | |||
a8822e24b0 | |||
a60e4c0a3f | |||
b2d740dd1f | |||
3237b2702f | |||
e8c49b0090 | |||
3dd51cd648 | |||
e03aa795fa | |||
a8a05a21a4 | |||
63fa406c3c | |||
6ad6609872 | |||
474fbf09c4 | |||
47849b8ff7 | |||
0379a52f03 | |||
bc2eeb0560 | |||
81f07c3783 | |||
f90926389a | |||
dcb97e775e | |||
096de82fd9 | |||
db693d46df | |||
b8d628c5f3 | |||
0aa22998e2 | |||
afe047a77f | |||
1ae794e5e4 | |||
a7a204ebca | |||
8774d7e4d5 | |||
34e51ac1cb | |||
d152dc2e6a | |||
8ce5a9dd19 | |||
820d8e6ce6 | |||
3cefd60c37 | |||
876d4de6be | |||
974902af31 | |||
45626a05dc | |||
4b5299bb7a | |||
ceab27c97a | |||
03d1b56a8f | |||
64190dfc73 | |||
29128eb316 | |||
ea9f8b4258 | |||
1cb03a184b | |||
158d998ec4 | |||
168241df4f | |||
f5417032bf | |||
d69db3469e | |||
980a4fa401 | |||
027e2e8a11 | |||
dcfda9d9d2 | |||
ca73e29ec5 | |||
0330442c63 | |||
221c6a8eef | |||
25a1e5f952 | |||
38df80046e | |||
57bb7aa5f6 | |||
86996704ce | |||
f53ac2a5a0 | |||
d0af5979c8 | |||
43020bd064 | |||
dc00b96f47 | |||
71c856878c | |||
19865e81db | |||
a4258b1244 | |||
e0b76b185a | |||
c47f441b13 | |||
7c854a18bb | |||
8df2c0a7c6 | |||
e60b9f796e | |||
2c8bcc6722 | |||
e257d92f41 | |||
f697338eec | |||
e2ec7c76a4 | |||
058d101bf9 | |||
833794feef | |||
a3dedb68d1 | |||
4a463567ac | |||
9f3ed7d855 | |||
221b429c24 | |||
b937d1cd9a | |||
986c46c2b6 | |||
e029216566 | |||
2d4595887d | |||
2beffe688a | |||
66408a87ee | |||
62b418cd16 | |||
5361cc075d | |||
be12164290 | |||
588896712e | |||
6221b94fdf | |||
efef80f67b | |||
0c1a0ab966 | |||
678ed5ced5 | |||
7f87ce0362 | |||
d1acf7f192 | |||
171d2ce59c | |||
c6170eb79d | |||
d2c44dd4df | |||
9b7090ca1d | |||
ee8e88b111 | |||
a901b1f0d7 | |||
82efd95901 | |||
4c803d579b | |||
b34ec6c46b | |||
6368c626c5 | |||
a5445d9c5c | |||
da86457cda | |||
eb00693325 | |||
a15a0b5eb9 | |||
646fd5f47b | |||
277b347604 | |||
12bc634ec3 | |||
769e54d8f5 | |||
ad50bc4ccb | |||
0ca7aa126b | |||
d0d9967457 | |||
b51b52ac0e | |||
36c1f32ef9 | |||
fa245ffdd5 | |||
f7c5f45833 | |||
579976260f | |||
d56e9f6b80 | |||
57b0b6a9b1 | |||
640190217d | |||
a08f485d76 | |||
f6b66839bd | |||
26700e7882 | |||
d86229dc2b | |||
f56171b513 | |||
516e9a4de6 | |||
765d907ea1 | |||
287421e21e | |||
2761fda2c9 | |||
339e36fbe6 | |||
5e648b96e8 | |||
ac2135e450 | |||
68c8c05775 | |||
14b1cab5d2 | |||
e570e2e736 | |||
16fd2e5d68 | |||
422b25ab1f | |||
b7527399b5 | |||
89bad11ad8 | |||
9d32e2c3b0 | |||
099341582a | |||
942c98003f | |||
cad3bf3e8c | |||
2ab5cc73cd | |||
9f2dd09628 | |||
2798adc837 | |||
54d9404c0e | |||
f1025dce4e | |||
538f4dad9d | |||
5323e232b2 | |||
5d9986ab5f | |||
38688a4486 | |||
d640a57f9b | |||
5e9479cded | |||
06ffe44f1f | |||
b35b816287 | |||
bf15d06568 | |||
2c2ffa846c | |||
48c41bcbe7 | |||
beb47e1c63 | |||
303c3654a1 | |||
5fab610fab | |||
3c3ebc05cc | |||
94956ebde9 | |||
e716bed11b | |||
ccbcad9741 | |||
15a8c34717 | |||
b815f48803 | |||
95c97332bf | |||
9bdf6b00cc | |||
91b23caa19 | |||
5df48ef8fd | |||
109078c5e0 | |||
c0b262a22a | |||
8bb1af9926 | |||
538f1f1a68 | |||
b60ab3ae44 | |||
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 |
20
.ansible-lint
Normal file
20
.ansible-lint
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
parseable: true
|
||||||
|
skip_list:
|
||||||
|
# see https://docs.ansible.com/ansible-lint/rules/default_rules.html for a list of all default rules
|
||||||
|
|
||||||
|
# DO NOT add any other rules to this skip_list, instead use local `# noqa` with a comment explaining WHY it is necessary
|
||||||
|
|
||||||
|
# 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'
|
15
.editorconfig
Normal file
15
.editorconfig
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
root = true
|
||||||
|
|
||||||
|
[*.{yaml,yml,yml.j2,yaml.j2}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
[{Dockerfile}]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
insert_final_newline = true
|
||||||
|
charset = utf-8
|
@ -1,16 +1,11 @@
|
|||||||
<!-- Thanks for filing an issue! Before hitting the button, please answer these questions.-->
|
---
|
||||||
|
name: Bug Report
|
||||||
**Is this a BUG REPORT or FEATURE REQUEST?** (choose one):
|
about: Report a bug encountered while operating Kubernetes
|
||||||
|
labels: kind/bug
|
||||||
|
|
||||||
|
---
|
||||||
<!--
|
<!--
|
||||||
If this is a BUG REPORT, please:
|
Please, be ready for followup questions, and please respond in a timely
|
||||||
- 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
|
|
||||||
manner. If we can't reproduce a bug or think a feature already exists, we
|
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
|
might close your issue. If we're wrong, PLEASE feel free to reopen it and
|
||||||
explain why.
|
explain why.
|
||||||
@ -23,6 +18,8 @@ explain why.
|
|||||||
|
|
||||||
- **Version of Ansible** (`ansible --version`):
|
- **Version of Ansible** (`ansible --version`):
|
||||||
|
|
||||||
|
- **Version of Python** (`python --version`):
|
||||||
|
|
||||||
|
|
||||||
**Kubespray version (commit) (`git rev-parse --short HEAD`):**
|
**Kubespray version (commit) (`git rev-parse --short HEAD`):**
|
||||||
|
|
||||||
@ -30,8 +27,8 @@ explain why.
|
|||||||
**Network plugin used**:
|
**Network plugin used**:
|
||||||
|
|
||||||
|
|
||||||
**Copy of your inventory file:**
|
**Full inventory with variables (`ansible -i inventory/sample/inventory.ini all -m debug -a "var=hostvars[inventory_hostname]"`):**
|
||||||
|
<!-- We recommend using snippets services like https://gist.github.com/ etc. -->
|
||||||
|
|
||||||
**Command used to invoke ansible**:
|
**Command used to invoke ansible**:
|
||||||
|
|
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/first-contribution.md and developer guide https://git.k8s.io/community/contributors/devel/development.md
|
||||||
|
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/sig-release/release.md#issuepr-kind-label
|
||||||
|
3. Ensure you have added or ran the appropriate tests for your PR: https://git.k8s.io/community/contributors/devel/sig-testing/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
|
||||||
|
|
||||||
|
```
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
|||||||
.vagrant
|
.vagrant
|
||||||
*.retry
|
*.retry
|
||||||
**/vagrant_ansible_inventory
|
**/vagrant_ansible_inventory
|
||||||
|
*.iml
|
||||||
temp
|
temp
|
||||||
.idea
|
.idea
|
||||||
.tox
|
.tox
|
||||||
|
797
.gitlab-ci.yml
797
.gitlab-ci.yml
@ -1,15 +1,16 @@
|
|||||||
---
|
---
|
||||||
stages:
|
stages:
|
||||||
- unit-tests
|
- unit-tests
|
||||||
- moderator
|
|
||||||
- deploy-part1
|
- deploy-part1
|
||||||
|
- moderator
|
||||||
- deploy-part2
|
- deploy-part2
|
||||||
|
- deploy-part3
|
||||||
- deploy-special
|
- deploy-special
|
||||||
|
|
||||||
variables:
|
variables:
|
||||||
|
KUBESPRAY_VERSION: v2.13.3
|
||||||
FAILFASTCI_NAMESPACE: 'kargo-ci'
|
FAILFASTCI_NAMESPACE: 'kargo-ci'
|
||||||
GITLAB_REPOSITORY: 'kargo-ci/kubernetes-sigs-kubespray'
|
GITLAB_REPOSITORY: 'kargo-ci/kubernetes-sigs-kubespray'
|
||||||
# DOCKER_HOST: tcp://localhost:2375
|
|
||||||
ANSIBLE_FORCE_COLOR: "true"
|
ANSIBLE_FORCE_COLOR: "true"
|
||||||
MAGIC: "ci check this"
|
MAGIC: "ci check this"
|
||||||
TEST_ID: "$CI_PIPELINE_ID-$CI_BUILD_ID"
|
TEST_ID: "$CI_PIPELINE_ID-$CI_BUILD_ID"
|
||||||
@ -25,787 +26,51 @@ variables:
|
|||||||
IDEMPOT_CHECK: "false"
|
IDEMPOT_CHECK: "false"
|
||||||
RESET_CHECK: "false"
|
RESET_CHECK: "false"
|
||||||
UPGRADE_TEST: "false"
|
UPGRADE_TEST: "false"
|
||||||
LOG_LEVEL: "-vv"
|
MITOGEN_ENABLE: "false"
|
||||||
|
ANSIBLE_LOG_LEVEL: "-vv"
|
||||||
# asia-east1-a
|
RECOVER_CONTROL_PLANE_TEST: "false"
|
||||||
# asia-northeast1-a
|
RECOVER_CONTROL_PLANE_TEST_GROUPS: "etcd[2:],kube-master[1:]"
|
||||||
# europe-west1-b
|
|
||||||
# us-central1-a
|
|
||||||
# us-east1-b
|
|
||||||
# us-west1-a
|
|
||||||
|
|
||||||
before_script:
|
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
|
- mkdir -p /.ssh
|
||||||
|
|
||||||
.job: &job
|
.job: &job
|
||||||
tags:
|
tags:
|
||||||
- kubernetes
|
- packet
|
||||||
- docker
|
image: quay.io/kubespray/kubespray:$KUBESPRAY_VERSION
|
||||||
image: quay.io/kubespray/kubespray:v2.8
|
artifacts:
|
||||||
|
when: always
|
||||||
.docker_service: &docker_service
|
paths:
|
||||||
services:
|
- cluster-dump/
|
||||||
- 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
|
|
||||||
|
|
||||||
|
|
||||||
.testcases: &testcases
|
.testcases: &testcases
|
||||||
<<: *job
|
<<: *job
|
||||||
<<: *docker_service
|
|
||||||
cache:
|
|
||||||
key: "$CI_BUILD_REF_NAME"
|
|
||||||
paths:
|
|
||||||
- downloads/
|
|
||||||
- $HOME/.cache
|
|
||||||
before_script:
|
before_script:
|
||||||
- docker info
|
- update-alternatives --install /usr/bin/python python /usr/bin/python3 1
|
||||||
- /usr/bin/python -m pip install -r requirements.txt
|
- ./tests/scripts/rebase.sh
|
||||||
- /usr/bin/python -m pip install -r tests/requirements.txt
|
- ./tests/scripts/testcases_prepare.sh
|
||||||
- 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"
|
|
||||||
script:
|
script:
|
||||||
- pwd
|
- ./tests/scripts/testcases_run.sh
|
||||||
- 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
|
|
||||||
|
|
||||||
after_script:
|
after_script:
|
||||||
- cd tests && make delete-${CI_PLATFORM} -s ; cd -
|
- chronic ./tests/scripts/testcases_cleanup.sh
|
||||||
|
|
||||||
.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-.*$/]
|
|
||||||
|
|
||||||
|
# For failfast, at least 1 job must be defined in .gitlab-ci.yml
|
||||||
# Premoderated with manual actions
|
# Premoderated with manual actions
|
||||||
ci-authorized:
|
ci-authorized:
|
||||||
<<: *job
|
extends: .job
|
||||||
stage: moderator
|
stage: moderator
|
||||||
before_script:
|
|
||||||
- apt-get -y install jq
|
|
||||||
script:
|
script:
|
||||||
- /bin/sh scripts/premoderator.sh
|
- /bin/sh scripts/premoderator.sh
|
||||||
except: ['triggers', 'master']
|
except: ['triggers', 'master']
|
||||||
|
# Disable ci moderator
|
||||||
|
only: []
|
||||||
|
|
||||||
syntax-check:
|
include:
|
||||||
<<: *job
|
- .gitlab-ci/lint.yml
|
||||||
stage: unit-tests
|
- .gitlab-ci/shellcheck.yml
|
||||||
script:
|
- .gitlab-ci/terraform.yml
|
||||||
- ansible-playbook -i inventory/local-tests.cfg -u root -e ansible_ssh_user=root -b --become-user=root cluster.yml -vvv --syntax-check
|
- .gitlab-ci/packet.yml
|
||||||
- ansible-playbook -i inventory/local-tests.cfg -u root -e ansible_ssh_user=root -b --become-user=root upgrade-cluster.yml -vvv --syntax-check
|
- .gitlab-ci/vagrant.yml
|
||||||
- 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"
|
|
||||||
|
76
.gitlab-ci/lint.yml
Normal file
76
.gitlab-ci/lint.yml
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
---
|
||||||
|
yamllint:
|
||||||
|
extends: .job
|
||||||
|
stage: unit-tests
|
||||||
|
tags: [light]
|
||||||
|
variables:
|
||||||
|
LANG: C.UTF-8
|
||||||
|
script:
|
||||||
|
- yamllint --strict .
|
||||||
|
except: ['triggers', 'master']
|
||||||
|
|
||||||
|
vagrant-validate:
|
||||||
|
extends: .job
|
||||||
|
stage: unit-tests
|
||||||
|
tags: [light]
|
||||||
|
variables:
|
||||||
|
VAGRANT_VERSION: 2.2.4
|
||||||
|
script:
|
||||||
|
- ./tests/scripts/vagrant-validate.sh
|
||||||
|
except: ['triggers', 'master']
|
||||||
|
|
||||||
|
ansible-lint:
|
||||||
|
extends: .job
|
||||||
|
stage: unit-tests
|
||||||
|
tags: [light]
|
||||||
|
# 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
|
||||||
|
tags: [light]
|
||||||
|
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
|
||||||
|
tags: [light]
|
||||||
|
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
|
||||||
|
tags: [light]
|
||||||
|
image: node
|
||||||
|
before_script:
|
||||||
|
- npm install -g markdownlint-cli
|
||||||
|
script:
|
||||||
|
- markdownlint README.md docs --ignore docs/_sidebar.md
|
||||||
|
|
||||||
|
ci-matrix:
|
||||||
|
stage: unit-tests
|
||||||
|
tags: [light]
|
||||||
|
image: python:3
|
||||||
|
script:
|
||||||
|
- tests/scripts/md-table/test.sh
|
229
.gitlab-ci/packet.yml
Normal file
229
.gitlab-ci/packet.yml
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
---
|
||||||
|
.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
|
||||||
|
|
||||||
|
# Future AIO job
|
||||||
|
packet_ubuntu20-calico-aio:
|
||||||
|
stage: deploy-part1
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
|
||||||
|
# ### PR JOBS PART2
|
||||||
|
|
||||||
|
packet_centos7-flannel-containerd-addons-ha:
|
||||||
|
extends: .packet
|
||||||
|
stage: deploy-part2
|
||||||
|
when: on_success
|
||||||
|
variables:
|
||||||
|
MITOGEN_ENABLE: "true"
|
||||||
|
|
||||||
|
packet_centos7-crio:
|
||||||
|
extends: .packet
|
||||||
|
stage: deploy-part2
|
||||||
|
when: on_success
|
||||||
|
variables:
|
||||||
|
MITOGEN_ENABLE: "true"
|
||||||
|
|
||||||
|
packet_ubuntu18-crio:
|
||||||
|
extends: .packet
|
||||||
|
stage: deploy-part2
|
||||||
|
when: manual
|
||||||
|
variables:
|
||||||
|
MITOGEN_ENABLE: "true"
|
||||||
|
|
||||||
|
packet_ubuntu16-canal-kubeadm-ha:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
|
||||||
|
packet_ubuntu16-canal-sep:
|
||||||
|
stage: deploy-special
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_ubuntu16-flannel-ha:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_ubuntu16-kube-router-sep:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_ubuntu16-kube-router-svc-proxy:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_debian10-cilium-svc-proxy:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_debian10-containerd:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
variables:
|
||||||
|
MITOGEN_ENABLE: "true"
|
||||||
|
|
||||||
|
packet_centos7-calico-ha-once-localhost:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
variables:
|
||||||
|
# This will instruct Docker not to start over TLS.
|
||||||
|
DOCKER_TLS_CERTDIR: ""
|
||||||
|
services:
|
||||||
|
- docker:19.03.9-dind
|
||||||
|
|
||||||
|
packet_centos8-kube-ovn:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
|
||||||
|
packet_centos8-calico:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
|
||||||
|
packet_fedora32-weave:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
|
||||||
|
packet_opensuse-canal:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
|
||||||
|
packet_ubuntu18-ovn4nfv:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
|
||||||
|
# Contiv does not work in k8s v1.16
|
||||||
|
# packet_ubuntu16-contiv-sep:
|
||||||
|
# stage: deploy-part2
|
||||||
|
# extends: .packet
|
||||||
|
# when: on_success
|
||||||
|
|
||||||
|
# ### MANUAL JOBS
|
||||||
|
|
||||||
|
packet_ubuntu16-weave-sep:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_ubuntu18-cilium-sep:
|
||||||
|
stage: deploy-special
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_ubuntu18-flannel-containerd-ha:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_ubuntu18-flannel-containerd-ha-once:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_debian9-macvlan:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_centos7-calico-ha:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_centos7-kube-router:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_centos7-multus-calico:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_oracle7-canal-ha:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_fedora31-flannel:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
variables:
|
||||||
|
MITOGEN_ENABLE: "true"
|
||||||
|
|
||||||
|
packet_amazon-linux-2-aio:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
packet_fedora32-kube-ovn-containerd:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
|
||||||
|
# ### PR JOBS PART3
|
||||||
|
# Long jobs (45min+)
|
||||||
|
|
||||||
|
packet_centos7-weave-upgrade-ha:
|
||||||
|
stage: deploy-part3
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
variables:
|
||||||
|
UPGRADE_TEST: basic
|
||||||
|
MITOGEN_ENABLE: "false"
|
||||||
|
|
||||||
|
packet_debian9-calico-upgrade:
|
||||||
|
stage: deploy-part3
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
variables:
|
||||||
|
UPGRADE_TEST: graceful
|
||||||
|
MITOGEN_ENABLE: "false"
|
||||||
|
|
||||||
|
packet_debian9-calico-upgrade-once:
|
||||||
|
stage: deploy-part3
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
variables:
|
||||||
|
UPGRADE_TEST: graceful
|
||||||
|
MITOGEN_ENABLE: "false"
|
||||||
|
|
||||||
|
packet_ubuntu18-calico-ha-recover:
|
||||||
|
stage: deploy-part3
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
variables:
|
||||||
|
RECOVER_CONTROL_PLANE_TEST: "true"
|
||||||
|
RECOVER_CONTROL_PLANE_TEST_GROUPS: "etcd[2:],kube-master[1:]"
|
||||||
|
|
||||||
|
packet_ubuntu18-calico-ha-recover-noquorum:
|
||||||
|
stage: deploy-part3
|
||||||
|
extends: .packet
|
||||||
|
when: on_success
|
||||||
|
variables:
|
||||||
|
RECOVER_CONTROL_PLANE_TEST: "true"
|
||||||
|
RECOVER_CONTROL_PLANE_TEST_GROUPS: "etcd[1:],kube-master[1:]"
|
16
.gitlab-ci/shellcheck.yml
Normal file
16
.gitlab-ci/shellcheck.yml
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
shellcheck:
|
||||||
|
extends: .job
|
||||||
|
stage: unit-tests
|
||||||
|
tags: [light]
|
||||||
|
variables:
|
||||||
|
SHELLCHECK_VERSION: v0.6.0
|
||||||
|
before_script:
|
||||||
|
- ./tests/scripts/rebase.sh
|
||||||
|
- curl --silent --location "https://github.com/koalaman/shellcheck/releases/download/"${SHELLCHECK_VERSION}"/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']
|
217
.gitlab-ci/terraform.yml
Normal file
217
.gitlab-ci/terraform.yml
Normal file
@ -0,0 +1,217 @@
|
|||||||
|
---
|
||||||
|
# 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
|
||||||
|
- mkdir -p group_vars
|
||||||
|
# Random subnet to avoid routing conflicts
|
||||||
|
- export TF_VAR_subnet_cidr="10.$(( $RANDOM % 256 )).$(( $RANDOM % 256 )).0/24"
|
||||||
|
|
||||||
|
.terraform_validate:
|
||||||
|
extends: .terraform_install
|
||||||
|
stage: unit-tests
|
||||||
|
tags: [light]
|
||||||
|
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
|
||||||
|
tags: [light]
|
||||||
|
stage: deploy-part3
|
||||||
|
when: manual
|
||||||
|
only: [/^pr-.*$/]
|
||||||
|
artifacts:
|
||||||
|
when: always
|
||||||
|
paths:
|
||||||
|
- cluster-dump/
|
||||||
|
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
|
||||||
|
- chronic ./tests/scripts/testcases_cleanup.sh
|
||||||
|
|
||||||
|
tf-validate-openstack:
|
||||||
|
extends: .terraform_validate
|
||||||
|
variables:
|
||||||
|
TF_VERSION: 0.12.24
|
||||||
|
PROVIDER: openstack
|
||||||
|
CLUSTER: $CI_COMMIT_REF_NAME
|
||||||
|
|
||||||
|
tf-validate-packet:
|
||||||
|
extends: .terraform_validate
|
||||||
|
variables:
|
||||||
|
TF_VERSION: 0.12.24
|
||||||
|
PROVIDER: packet
|
||||||
|
CLUSTER: $CI_COMMIT_REF_NAME
|
||||||
|
|
||||||
|
tf-validate-aws:
|
||||||
|
extends: .terraform_validate
|
||||||
|
variables:
|
||||||
|
TF_VERSION: 0.12.24
|
||||||
|
PROVIDER: aws
|
||||||
|
CLUSTER: $CI_COMMIT_REF_NAME
|
||||||
|
|
||||||
|
# tf-packet-ubuntu16-default:
|
||||||
|
# extends: .terraform_apply
|
||||||
|
# variables:
|
||||||
|
# TF_VERSION: 0.12.24
|
||||||
|
# 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.24
|
||||||
|
# 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"
|
||||||
|
|
||||||
|
# Elastx is generously donating resources for Kubespray on Openstack CI
|
||||||
|
# Contacts: @gix @bl0m1
|
||||||
|
.elastx_variables: &elastx_variables
|
||||||
|
OS_AUTH_URL: https://ops.elastx.cloud:5000
|
||||||
|
OS_PROJECT_ID: 564c6b461c6b44b1bb19cdb9c2d928e4
|
||||||
|
OS_PROJECT_NAME: kubespray_ci
|
||||||
|
OS_USER_DOMAIN_NAME: Default
|
||||||
|
OS_PROJECT_DOMAIN_ID: default
|
||||||
|
OS_USERNAME: kubespray@root314.com
|
||||||
|
OS_REGION_NAME: se-sto
|
||||||
|
OS_INTERFACE: public
|
||||||
|
OS_IDENTITY_API_VERSION: "3"
|
||||||
|
TF_VAR_router_id: "ab95917c-41fb-4881-b507-3a6dfe9403df"
|
||||||
|
# Since ELASTX is in Stockholm, Mitogen helps with latency
|
||||||
|
MITOGEN_ENABLE: "false"
|
||||||
|
# Mitogen doesn't support interpreter discovery yet
|
||||||
|
ANSIBLE_PYTHON_INTERPRETER: "/usr/bin/python3"
|
||||||
|
|
||||||
|
tf-elastx_cleanup:
|
||||||
|
stage: unit-tests
|
||||||
|
tags: [light]
|
||||||
|
image: python
|
||||||
|
variables:
|
||||||
|
<<: *elastx_variables
|
||||||
|
before_script:
|
||||||
|
- pip install -r scripts/openstack-cleanup/requirements.txt
|
||||||
|
script:
|
||||||
|
- ./scripts/openstack-cleanup/main.py
|
||||||
|
|
||||||
|
tf-elastx_ubuntu18-calico:
|
||||||
|
extends: .terraform_apply
|
||||||
|
stage: deploy-part3
|
||||||
|
when: on_success
|
||||||
|
variables:
|
||||||
|
<<: *elastx_variables
|
||||||
|
TF_VERSION: 0.12.24
|
||||||
|
PROVIDER: openstack
|
||||||
|
CLUSTER: $CI_COMMIT_REF_NAME
|
||||||
|
ANSIBLE_TIMEOUT: "60"
|
||||||
|
SSH_USER: ubuntu
|
||||||
|
TF_VAR_number_of_k8s_masters: "1"
|
||||||
|
TF_VAR_number_of_k8s_masters_no_floating_ip: "0"
|
||||||
|
TF_VAR_number_of_k8s_masters_no_floating_ip_no_etcd: "0"
|
||||||
|
TF_VAR_number_of_etcd: "0"
|
||||||
|
TF_VAR_number_of_k8s_nodes: "1"
|
||||||
|
TF_VAR_number_of_k8s_nodes_no_floating_ip: "0"
|
||||||
|
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_floatingip_pool: "elx-public1"
|
||||||
|
TF_VAR_dns_nameservers: '["1.1.1.1", "8.8.8.8", "8.8.4.4"]'
|
||||||
|
TF_VAR_use_access_ip: "0"
|
||||||
|
TF_VAR_external_net: "600b8501-78cb-4155-9c9f-23dfcba88828"
|
||||||
|
TF_VAR_network_name: "ci-$CI_JOB_ID"
|
||||||
|
TF_VAR_az_list: '["sto1"]'
|
||||||
|
TF_VAR_az_list_node: '["sto1"]'
|
||||||
|
TF_VAR_flavor_k8s_master: 3f73fc93-ec61-4808-88df-2580d94c1a9b # v1-standard-2
|
||||||
|
TF_VAR_flavor_k8s_node: 3f73fc93-ec61-4808-88df-2580d94c1a9b # v1-standard-2
|
||||||
|
TF_VAR_image: ubuntu-18.04-server-latest
|
||||||
|
TF_VAR_k8s_allowed_remote_ips: '["0.0.0.0/0"]'
|
||||||
|
|
||||||
|
|
||||||
|
tf-ovh_cleanup:
|
||||||
|
stage: unit-tests
|
||||||
|
tags: [light]
|
||||||
|
image: python
|
||||||
|
environment: ovh
|
||||||
|
variables:
|
||||||
|
<<: *ovh_variables
|
||||||
|
before_script:
|
||||||
|
- pip install -r scripts/openstack-cleanup/requirements.txt
|
||||||
|
script:
|
||||||
|
- ./scripts/openstack-cleanup/main.py
|
||||||
|
|
||||||
|
tf-ovh_ubuntu18-calico:
|
||||||
|
extends: .terraform_apply
|
||||||
|
when: on_success
|
||||||
|
environment: ovh
|
||||||
|
variables:
|
||||||
|
<<: *ovh_variables
|
||||||
|
TF_VERSION: 0.12.24
|
||||||
|
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"]'
|
54
.gitlab-ci/vagrant.yml
Normal file
54
.gitlab-ci/vagrant.yml
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
molecule_tests:
|
||||||
|
tags: [c3.small.x86]
|
||||||
|
only: [/^pr-.*$/]
|
||||||
|
except: ['triggers']
|
||||||
|
image: quay.io/kubespray/vagrant:$KUBESPRAY_VERSION
|
||||||
|
services: []
|
||||||
|
stage: deploy-part1
|
||||||
|
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
|
||||||
|
- ./tests/scripts/vagrant_clean.sh
|
||||||
|
script:
|
||||||
|
- ./tests/scripts/molecule_run.sh
|
||||||
|
|
||||||
|
.vagrant:
|
||||||
|
extends: .testcases
|
||||||
|
variables:
|
||||||
|
CI_PLATFORM: "vagrant"
|
||||||
|
SSH_USER: "vagrant"
|
||||||
|
VAGRANT_DEFAULT_PROVIDER: "libvirt"
|
||||||
|
KUBESPRAY_VAGRANT_CONFIG: tests/files/${CI_JOB_NAME}.rb
|
||||||
|
tags: [c3.small.x86]
|
||||||
|
only: [/^pr-.*$/]
|
||||||
|
except: ['triggers']
|
||||||
|
image: quay.io/kubespray/vagrant:$KUBESPRAY_VERSION
|
||||||
|
services: []
|
||||||
|
before_script:
|
||||||
|
- 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
|
||||||
|
- ./tests/scripts/vagrant_clean.sh
|
||||||
|
script:
|
||||||
|
- ./tests/scripts/testcases_run.sh
|
||||||
|
after_script:
|
||||||
|
- chronic ./tests/scripts/testcases_cleanup.sh
|
||||||
|
|
||||||
|
vagrant_ubuntu18-flannel:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .vagrant
|
||||||
|
when: on_success
|
||||||
|
|
||||||
|
vagrant_ubuntu18-weave-medium:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .vagrant
|
||||||
|
when: manual
|
||||||
|
|
||||||
|
vagrant_ubuntu20-flannel:
|
||||||
|
stage: deploy-part2
|
||||||
|
extends: .vagrant
|
||||||
|
when: on_success
|
2
.markdownlint.yaml
Normal file
2
.markdownlint.yaml
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
MD013: false
|
@ -2,10 +2,30 @@
|
|||||||
|
|
||||||
## How to become a contributor and submit your own code
|
## How to become a contributor and submit your own code
|
||||||
|
|
||||||
|
### Environment setup
|
||||||
|
|
||||||
|
It is recommended to use filter to manage the GitHub email notification, see [examples for setting filters to Kubernetes Github notifications](https://github.com/kubernetes/community/blob/master/communication/best-practices.md#examples-for-setting-filters-to-kubernetes-github-notifications)
|
||||||
|
|
||||||
|
To install development dependencies you can use `pip install -r tests/requirements.txt`
|
||||||
|
|
||||||
|
#### Linting
|
||||||
|
|
||||||
|
Kubespray uses `yamllint` and `ansible-lint`. To run them locally use `yamllint .` and `./tests/scripts/ansible-lint.sh`
|
||||||
|
|
||||||
|
#### Molecule
|
||||||
|
|
||||||
|
[molecule](https://github.com/ansible-community/molecule) is designed to help the development and testing of Ansible roles. In Kubespray you can run it all for all roles with `./tests/scripts/molecule_run.sh` or for a specific role (that you are working with) with `molecule test` from the role directory (`cd roles/my-role`).
|
||||||
|
|
||||||
|
When developing or debugging a role it can be useful to run `molecule create` and `molecule converge` separately. Then you can use `molecule login` to SSH into the test environment.
|
||||||
|
|
||||||
|
#### Vagrant
|
||||||
|
|
||||||
|
Vagrant with VirtualBox or libvirt driver helps you to quickly spin test clusters to test things end to end. See [README.md#vagrant](README.md)
|
||||||
|
|
||||||
### Contributing A Patch
|
### Contributing A Patch
|
||||||
|
|
||||||
1. Submit an issue describing your proposed change to the repo in question.
|
1. Submit an issue describing your proposed change to the repo in question.
|
||||||
2. The [repo owners](OWNERS) will respond to your issue promptly.
|
2. The [repo owners](OWNERS) will respond to your issue promptly.
|
||||||
3. Fork the desired repo, develop and test your code changes.
|
3. Fork the desired repo, develop and test your code changes.
|
||||||
4. Sign the CNCF CLA (https://git.k8s.io/community/CLA.md#the-contributor-license-agreement)
|
4. Sign the CNCF CLA (<https://git.k8s.io/community/CLA.md#the-contributor-license-agreement>)
|
||||||
5. Submit a pull request.
|
5. Submit a pull request.
|
||||||
|
24
Dockerfile
24
Dockerfile
@ -1,19 +1,21 @@
|
|||||||
FROM ubuntu:16.04
|
FROM ubuntu:18.04
|
||||||
|
|
||||||
RUN mkdir /kubespray
|
RUN mkdir /kubespray
|
||||||
WORKDIR /kubespray
|
WORKDIR /kubespray
|
||||||
RUN apt update -y && \
|
RUN apt update -y && \
|
||||||
apt install -y \
|
apt install -y \
|
||||||
libssl-dev python-dev sshpass apt-transport-https jq \
|
libssl-dev python3-dev sshpass apt-transport-https jq moreutils \
|
||||||
ca-certificates curl gnupg2 software-properties-common python-pip
|
ca-certificates curl gnupg2 software-properties-common python3-pip rsync
|
||||||
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - && \
|
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | apt-key add - && \
|
||||||
add-apt-repository \
|
add-apt-repository \
|
||||||
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
|
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
|
||||||
$(lsb_release -cs) \
|
$(lsb_release -cs) \
|
||||||
stable" \
|
stable" \
|
||||||
&& apt update -y && apt-get install docker-ce -y
|
&& apt update -y && apt-get install docker-ce -y
|
||||||
COPY . .
|
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 /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.11.3/bin/linux/amd64/kubectl \
|
RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.17.5/bin/linux/amd64/kubectl \
|
||||||
&& chmod a+x kubectl && cp kubectl /usr/local/bin/kubectl
|
&& chmod a+x kubectl && cp kubectl /usr/local/bin/kubectl
|
||||||
|
|
||||||
|
# Some tools like yamllint need this
|
||||||
|
ENV LANG=C.UTF-8
|
||||||
|
2
Makefile
2
Makefile
@ -1,5 +1,5 @@
|
|||||||
mitogen:
|
mitogen:
|
||||||
ansible-playbook -c local mitogen.yaml -vv
|
ansible-playbook -c local mitogen.yml -vv
|
||||||
clean:
|
clean:
|
||||||
rm -rf dist/
|
rm -rf dist/
|
||||||
rm *.retry
|
rm *.retry
|
||||||
|
@ -4,17 +4,16 @@ aliases:
|
|||||||
- mattymo
|
- mattymo
|
||||||
- atoms
|
- atoms
|
||||||
- chadswen
|
- chadswen
|
||||||
- rsmitty
|
- mirwan
|
||||||
- bogdando
|
- miouge1
|
||||||
- bradbeam
|
|
||||||
- woopstar
|
|
||||||
- riverzhang
|
- riverzhang
|
||||||
- holser
|
|
||||||
- smana
|
|
||||||
- verwilst
|
- verwilst
|
||||||
|
- woopstar
|
||||||
|
- luckysb
|
||||||
kubespray-reviewers:
|
kubespray-reviewers:
|
||||||
- jjungnickel
|
- jjungnickel
|
||||||
- archifleks
|
- archifleks
|
||||||
- chapsuk
|
- holmsten
|
||||||
- mirwan
|
- bozzo
|
||||||
- miouge1
|
- floryut
|
||||||
|
- eppo
|
||||||
|
284
README.md
284
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 at [kubespray.io](https://kubespray.io) and join us on the [kubernetes slack](https://kubernetes.slack.com), channel **\#kubespray**.
|
||||||
============================================
|
|
||||||
|
|
||||||
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/)
|
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**
|
- Can be deployed on **[AWS](docs/aws.md), GCE, [Azure](docs/azure.md), [OpenStack](docs/openstack.md), [vSphere](docs/vsphere.md), [Packet](docs/packet.md) (bare metal), Oracle Cloud Infrastructure (Experimental), or Baremetal**
|
||||||
- **Highly available** cluster
|
- **Highly available** cluster
|
||||||
- **Composable** (Choice of the network plugin for instance)
|
- **Composable** (Choice of the network plugin for instance)
|
||||||
- Supports most popular **Linux distributions**
|
- Supports most popular **Linux distributions**
|
||||||
- **Continuous integration tests**
|
- **Continuous integration tests**
|
||||||
|
|
||||||
Quick Start
|
## Quick Start
|
||||||
-----------
|
|
||||||
|
|
||||||
To deploy the cluster you can use :
|
To deploy the cluster you can use :
|
||||||
|
|
||||||
@ -21,31 +19,35 @@ To deploy the cluster you can use :
|
|||||||
|
|
||||||
#### Usage
|
#### Usage
|
||||||
|
|
||||||
# Install dependencies from ``requirements.txt``
|
```ShellSession
|
||||||
sudo pip install -r requirements.txt
|
# Install dependencies from ``requirements.txt``
|
||||||
|
sudo pip3 install -r requirements.txt
|
||||||
|
|
||||||
# Copy ``inventory/sample`` as ``inventory/mycluster``
|
# Copy ``inventory/sample`` as ``inventory/mycluster``
|
||||||
cp -rfp inventory/sample inventory/mycluster
|
cp -rfp inventory/sample inventory/mycluster
|
||||||
|
|
||||||
# Update Ansible inventory file with inventory builder
|
# Update Ansible inventory file with inventory builder
|
||||||
declare -a IPS=(10.10.1.3 10.10.1.4 10.10.1.5)
|
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[@]}
|
CONFIG_FILE=inventory/mycluster/hosts.yaml python3 contrib/inventory_builder/inventory.py ${IPS[@]}
|
||||||
|
|
||||||
# Review and change parameters under ``inventory/mycluster/group_vars``
|
# Review and change parameters under ``inventory/mycluster/group_vars``
|
||||||
cat inventory/mycluster/group_vars/all/all.yml
|
cat inventory/mycluster/group_vars/all/all.yml
|
||||||
cat inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml
|
cat inventory/mycluster/group_vars/k8s-cluster/k8s-cluster.yml
|
||||||
|
|
||||||
# Deploy Kubespray with Ansible Playbook - run the playbook as root
|
# Deploy Kubespray with Ansible Playbook - run the playbook as root
|
||||||
# The option `-b` is required, as for example writing SSL keys in /etc/,
|
# The option `--become` is required, as for example writing SSL keys in /etc/,
|
||||||
# installing packages and interacting with various systemd daemons.
|
# installing packages and interacting with various systemd daemons.
|
||||||
# Without -b the playbook will fail to run!
|
# Without --become the playbook will fail to run!
|
||||||
ansible-playbook -i inventory/mycluster/hosts.ini --become --become-user=root cluster.yml
|
ansible-playbook -i inventory/mycluster/hosts.yaml --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).
|
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:
|
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.
|
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").
|
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.
|
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,172 @@ A workaround consists of setting `ANSIBLE_LIBRARY` and `ANSIBLE_MODULE_UTILS` en
|
|||||||
For Vagrant we need to install python dependencies for provisioning tasks.
|
For Vagrant we need to install python dependencies for provisioning tasks.
|
||||||
Check if Python and pip are installed:
|
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/>
|
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
|
Install the necessary requirements
|
||||||
|
|
||||||
sudo pip install -r requirements.txt
|
```ShellSession
|
||||||
vagrant up
|
sudo pip install -r requirements.txt
|
||||||
|
vagrant up
|
||||||
|
```
|
||||||
|
|
||||||
Documents
|
## Documents
|
||||||
---------
|
|
||||||
|
|
||||||
- [Requirements](#requirements)
|
- [Requirements](#requirements)
|
||||||
- [Kubespray vs ...](docs/comparisons.md)
|
- [Kubespray vs ...](docs/comparisons.md)
|
||||||
- [Getting started](docs/getting-started.md)
|
- [Getting started](docs/getting-started.md)
|
||||||
- [Ansible inventory and tags](docs/ansible.md)
|
- [Setting up your first cluster](docs/setting-up-your-first-cluster.md)
|
||||||
- [Integration with existing ansible repo](docs/integration.md)
|
- [Ansible inventory and tags](docs/ansible.md)
|
||||||
- [Deployment data variables](docs/vars.md)
|
- [Integration with existing ansible repo](docs/integration.md)
|
||||||
- [DNS stack](docs/dns-stack.md)
|
- [Deployment data variables](docs/vars.md)
|
||||||
- [HA mode](docs/ha-mode.md)
|
- [DNS stack](docs/dns-stack.md)
|
||||||
- [Network plugins](#network-plugins)
|
- [HA mode](docs/ha-mode.md)
|
||||||
- [Vagrant install](docs/vagrant.md)
|
- [Network plugins](#network-plugins)
|
||||||
- [CoreOS bootstrap](docs/coreos.md)
|
- [Vagrant install](docs/vagrant.md)
|
||||||
- [Debian Jessie setup](docs/debian.md)
|
- [Flatcar Container Linux bootstrap](docs/flatcar.md)
|
||||||
- [openSUSE setup](docs/opensuse.md)
|
- [Fedora CoreOS bootstrap](docs/fcos.md)
|
||||||
- [Downloaded artifacts](docs/downloads.md)
|
- [Debian Jessie setup](docs/debian.md)
|
||||||
- [Cloud providers](docs/cloud.md)
|
- [openSUSE setup](docs/opensuse.md)
|
||||||
- [OpenStack](docs/openstack.md)
|
- [Downloaded artifacts](docs/downloads.md)
|
||||||
- [AWS](docs/aws.md)
|
- [Cloud providers](docs/cloud.md)
|
||||||
- [Azure](docs/azure.md)
|
- [OpenStack](docs/openstack.md)
|
||||||
- [vSphere](docs/vsphere.md)
|
- [AWS](docs/aws.md)
|
||||||
- [Packet Host](docs/packet.md)
|
- [Azure](docs/azure.md)
|
||||||
- [Large deployments](docs/large-deployments.md)
|
- [vSphere](docs/vsphere.md)
|
||||||
- [Upgrades basics](docs/upgrades.md)
|
- [Packet Host](docs/packet.md)
|
||||||
- [Roadmap](docs/roadmap.md)
|
- [Large deployments](docs/large-deployments.md)
|
||||||
|
- [Adding/replacing a node](docs/nodes.md)
|
||||||
|
- [Upgrades basics](docs/upgrades.md)
|
||||||
|
- [Air-Gap installation](docs/offline-environment.md)
|
||||||
|
- [Roadmap](docs/roadmap.md)
|
||||||
|
|
||||||
Supported Linux Distributions
|
## Supported Linux Distributions
|
||||||
-----------------------------
|
|
||||||
|
|
||||||
- **Container Linux by CoreOS**
|
- **Flatcar Container Linux by Kinvolk**
|
||||||
- **Debian** Buster, Jessie, Stretch, Wheezy
|
- **Debian** Buster, Jessie, Stretch, Wheezy
|
||||||
- **Ubuntu** 16.04, 18.04
|
- **Ubuntu** 16.04, 18.04, 20.04
|
||||||
- **CentOS/RHEL** 7
|
- **CentOS/RHEL** 7, 8 (experimental: see [centos 8 notes](docs/centos8.md))
|
||||||
- **Fedora** 28
|
- **Fedora** 31, 32
|
||||||
- **Fedora/CentOS** Atomic
|
- **Fedora CoreOS** (experimental: see [fcos Note](docs/fcos.md))
|
||||||
- **openSUSE** Leap 42.3/Tumbleweed
|
- **openSUSE** Leap 42.3/Tumbleweed
|
||||||
|
- **Oracle Linux** 7, 8 (experimental: [centos 8 notes](docs/centos8.md) apply)
|
||||||
|
|
||||||
Note: Upstart/SysV init based OS types are not supported.
|
Note: Upstart/SysV init based OS types are not supported.
|
||||||
|
|
||||||
Supported Components
|
## Supported Components
|
||||||
--------------------
|
|
||||||
|
|
||||||
- Core
|
- Core
|
||||||
- [kubernetes](https://github.com/kubernetes/kubernetes) v1.13.5
|
- [kubernetes](https://github.com/kubernetes/kubernetes) v1.18.9
|
||||||
- [etcd](https://github.com/coreos/etcd) v3.2.26
|
- [etcd](https://github.com/coreos/etcd) v3.4.3
|
||||||
- [docker](https://www.docker.com/) v18.06 (see note)
|
- [docker](https://www.docker.com/) v19.03 (see note)
|
||||||
- [rkt](https://github.com/rkt/rkt) v1.21.0 (see Note 2)
|
- [containerd](https://containerd.io/) v1.2.13
|
||||||
- [cri-o](http://cri-o.io/) v1.11.5 (experimental: see [CRI-O Note](docs/cri-o.md). Only on centos based OS)
|
- [cri-o](http://cri-o.io/) v1.17 (experimental: see [CRI-O Note](docs/cri-o.md). Only on fedora, ubuntu and centos based OS)
|
||||||
- Network Plugin
|
- Network Plugin
|
||||||
- [calico](https://github.com/projectcalico/calico) v3.4.0
|
- [cni-plugins](https://github.com/containernetworking/plugins) v0.8.6
|
||||||
- [canal](https://github.com/projectcalico/canal) (given calico/flannel versions)
|
- [calico](https://github.com/projectcalico/calico) v3.15.2
|
||||||
- [cilium](https://github.com/cilium/cilium) v1.3.0
|
- [canal](https://github.com/projectcalico/canal) (given calico/flannel versions)
|
||||||
- [contiv](https://github.com/contiv/install) v1.2.1
|
- [cilium](https://github.com/cilium/cilium) v1.8.3
|
||||||
- [flanneld](https://github.com/coreos/flannel) v0.11.0
|
- [contiv](https://github.com/contiv/install) v1.2.1
|
||||||
- [kube-router](https://github.com/cloudnativelabs/kube-router) v0.2.5
|
- [flanneld](https://github.com/coreos/flannel) v0.12.0
|
||||||
- [multus](https://github.com/intel/multus-cni) v3.1.autoconf
|
- [kube-ovn](https://github.com/alauda/kube-ovn) v1.3.0
|
||||||
- [weave](https://github.com/weaveworks/weave) v2.5.1
|
- [kube-router](https://github.com/cloudnativelabs/kube-router) v1.0.1
|
||||||
- Application
|
- [multus](https://github.com/intel/multus-cni) v3.6.0
|
||||||
- [cephfs-provisioner](https://github.com/kubernetes-incubator/external-storage) v2.1.0-k8s1.11
|
- [ovn4nfv](https://github.com/opnfv/ovn4nfv-k8s-plugin) v1.1.0
|
||||||
- [cert-manager](https://github.com/jetstack/cert-manager) v0.5.2
|
- [weave](https://github.com/weaveworks/weave) v2.7.0
|
||||||
- [coredns](https://github.com/coredns/coredns) v1.4.0
|
- Application
|
||||||
- [ingress-nginx](https://github.com/kubernetes/ingress-nginx) v0.21.0
|
- [ambassador](https://github.com/datawire/ambassador): v1.5
|
||||||
|
- [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.16.1
|
||||||
|
- [coredns](https://github.com/coredns/coredns) v1.6.7
|
||||||
|
- [ingress-nginx](https://github.com/kubernetes/ingress-nginx) v0.35.0
|
||||||
|
|
||||||
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://kubernetes.io/docs/setup/production-environment/container-runtimes/#docker) is 1.13.1, 17.03, 17.06, 17.09, 18.06, 18.09 and 19.03. The recommended docker version is 19.03. 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
|
## Requirements
|
||||||
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
|
- **Minimum required version of Kubernetes is v1.17**
|
||||||
------------
|
- **Ansible v2.9+, Jinja 2.11+ and python-netaddr is installed on the machine that will run Ansible commands**
|
||||||
|
- The target servers must have **access to the Internet** in order to pull docker images. Otherwise, additional configuration is required (See [Offline Environment](docs/offline-environment.md))
|
||||||
- **Ansible v2.7.6 (or newer) and python-netaddr is installed on the machine
|
- The target servers are configured to allow **IPv4 forwarding**.
|
||||||
that will run Ansible commands**
|
- **Your ssh key must be copied** to all the servers part of your inventory.
|
||||||
- **Jinja 2.9 (or newer) is required to run the Ansible Playbooks**
|
- The **firewalls are not managed**, you'll need to implement your own rules the way you used to.
|
||||||
- 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.
|
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
|
should be configured in the target servers. Then the `ansible_become` flag
|
||||||
or command parameters `--become or -b` should be specified.
|
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.
|
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
|
- Master
|
||||||
- Memory: 1500 MB
|
- Memory: 1500 MB
|
||||||
- Node
|
- Node
|
||||||
- Memory: 1024 MB
|
- 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](https://docs.projectcalico.org/latest/introduction/) is a networking and network policy provider. Calico supports a flexible set of networking options
|
||||||
|
designed to give you the most efficient networking across a range of situations, including non-overlay
|
||||||
|
and overlay networks, with or without BGP. Calico uses the same engine to enforce network policy for hosts,
|
||||||
|
pods, and (if using Istio and Envoy) applications at the service mesh layer.
|
||||||
|
|
||||||
- [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.
|
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.
|
- [ovn4nfv](docs/ovn4nfv.md): [ovn4nfv-k8s-plugins](https://github.com/opnfv/ovn4nfv-k8s-plugin) is the network controller, OVS agent and CNI server to offer basic SFC and OVN overlay networking.
|
||||||
(Please refer to `weave` [troubleshooting documentation](http://docs.weave.works/weave/latest_release/troubleshooting.html)).
|
|
||||||
|
|
||||||
- [kube-router](docs/kube-router.md): Kube-router is a L3 CNI for Kubernetes networking aiming to provide operational
|
- [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-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),
|
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).
|
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.
|
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
|
The choice is defined with the variable `kube_network_plugin`. There is also an
|
||||||
option to leverage built-in cloud provider networking instead.
|
option to leverage built-in cloud provider networking instead.
|
||||||
See also [Network checker](docs/netcheck.md).
|
See also [Network checker](docs/netcheck.md).
|
||||||
|
|
||||||
Community docs and resources
|
## Ingress Plugins
|
||||||
----------------------------
|
|
||||||
|
|
||||||
- [kubernetes.io/docs/getting-started-guides/kubespray/](https://kubernetes.io/docs/getting-started-guides/kubespray/)
|
- [ambassador](docs/ambassador.md): the Ambassador Ingress Controller and API gateway.
|
||||||
- [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
|
- [nginx](https://kubernetes.github.io/ingress-nginx): the NGINX Ingress Controller.
|
||||||
--------------------------------------
|
|
||||||
|
|
||||||
- [Digital Rebar Provision](https://github.com/digitalrebar/provision/blob/master/doc/integrations/ansible.rst)
|
## Community docs and resources
|
||||||
- [Terraform Contrib](https://github.com/kubernetes-sigs/kubespray/tree/master/contrib/terraform)
|
|
||||||
|
|
||||||
CI Tests
|
- [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=CJ5G4GpqDy0)
|
||||||
|
|
||||||
[](https://gitlab.com/kubespray-ci/kubernetes-incubator__kubespray/pipelines)
|
## Tools and projects on top of Kubespray
|
||||||
|
|
||||||
|
- [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
|
||||||
|
|
||||||
|
[](https://gitlab.com/kargo-ci/kubernetes-sigs-kubespray/pipelines)
|
||||||
|
|
||||||
|
CI/end-to-end tests sponsored by: [CNCF](https://cncf.io), [Packet](https://www.packet.com/), [OVHcloud](https://www.ovhcloud.com/), [ELASTX](https://elastx.se/).
|
||||||
|
|
||||||
CI/end-to-end tests sponsored by Google (GCE)
|
|
||||||
See the [test matrix](docs/test_cases.md) for details.
|
See the [test matrix](docs/test_cases.md) for details.
|
||||||
|
48
RELEASE.md
48
RELEASE.md
@ -3,38 +3,46 @@
|
|||||||
The Kubespray Project is released on an as-needed basis. The process is as follows:
|
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
|
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
|
2. At least one of the [approvers](OWNERS_ALIASES) must approve this release
|
||||||
3. An OWNER runs `git tag -s $VERSION` and inserts the changelog and pushes the tag with `git push $VERSION`
|
3. The `kube_version_min_required` variable is set to `n-1`
|
||||||
4. The release issue is closed
|
4. Remove hashes for [EOL versions](https://github.com/kubernetes/sig-release/blob/master/releases/patch-releases.md) of kubernetes from `*_checksums` variables.
|
||||||
5. An announcement email is sent to `kubernetes-dev@googlegroups.com` with the subject `[ANNOUNCE] Kubespray $VERSION is released`
|
5. 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
|
||||||
|
6. An approver creates a release branch in the form `release-X.Y`
|
||||||
|
7. The corresponding version of [quay.io/kubespray/kubespray:vX.Y.Z](https://quay.io/repository/kubespray/kubespray) and [quay.io/kubespray/vagrant:vX.Y.Z](https://quay.io/repository/kubespray/vagrant) docker images are built and tagged
|
||||||
|
8. The `KUBESPRAY_VERSION` variable is updated in `.gitlab-ci.yml`
|
||||||
|
9. The release issue is closed
|
||||||
|
10. An announcement email is sent to `kubernetes-dev@googlegroups.com` with the subject `[ANNOUNCE] Kubespray $VERSION is released`
|
||||||
|
11. The topic of the #kubespray channel is updated with `vX.Y.Z is released! | ...`
|
||||||
|
|
||||||
## Major/minor releases, merge freezes and milestones
|
## Major/minor releases and milestones
|
||||||
|
|
||||||
* Kubespray does not maintain stable branches for releases. Releases are tags, not
|
* For major releases (vX.Y) Kubespray maintains one branch (`release-X.Y`). Minor releases (vX.Y.Z) are available only as tags.
|
||||||
branches, and there are no backports. Therefore, there is no need for merge
|
|
||||||
freezes as well.
|
|
||||||
|
|
||||||
* Fixes for major releases (vX.x.0) and minor releases (vX.Y.x) are delivered
|
* Security patches and bugs might be backported.
|
||||||
|
|
||||||
|
* Fixes for major releases (vX.Y) and minor releases (vX.Y.Z) are delivered
|
||||||
via maintenance releases (vX.Y.Z) and assigned to the corresponding open
|
via maintenance releases (vX.Y.Z) and assigned to the corresponding open
|
||||||
milestone (vX.Y). That milestone remains open for the major/minor releases
|
[GitHub milestone](https://github.com/kubernetes-sigs/kubespray/milestones).
|
||||||
support lifetime, which ends once the milestone closed. Then only a next major
|
That milestone remains open for the major/minor releases support lifetime,
|
||||||
or minor release can be done.
|
which ends once the milestone is closed. Then only a next major or minor release
|
||||||
|
can be done.
|
||||||
|
|
||||||
* Kubespray major and minor releases are bound to the given ``kube_version`` major/minor
|
* Kubespray major and minor releases are bound to the given `kube_version` major/minor
|
||||||
version numbers and other components' arbitrary versions, like etcd or network plugins.
|
version numbers and other components' arbitrary versions, like etcd or network plugins.
|
||||||
Older or newer versions are not supported and not tested for the given release.
|
Older or newer component versions are not supported and not tested for the given
|
||||||
|
release (even if included in the checksum variables, like `kubeadm_checksums`).
|
||||||
|
|
||||||
* There is no unstable releases and no APIs, thus Kubespray doesn't follow
|
* There is no unstable releases and no APIs, thus Kubespray doesn't follow
|
||||||
[semver](http://semver.org/). Every version describes only a stable release.
|
[semver](https://semver.org/). Every version describes only a stable release.
|
||||||
Breaking changes, if any introduced by changed defaults or non-contrib ansible roles'
|
Breaking changes, if any introduced by changed defaults or non-contrib ansible roles'
|
||||||
playbooks, shall be described in the release notes. Other breaking changes, if any in
|
playbooks, shall be described in the release notes. Other breaking changes, if any in
|
||||||
the contributed addons or bound versions of Kubernetes and other components, are
|
the contributed addons or bound versions of Kubernetes and other components, are
|
||||||
considered out of Kubespray scope and are up to the components' teams to deal with and
|
considered out of Kubespray scope and are up to the components' teams to deal with and
|
||||||
document.
|
document.
|
||||||
|
|
||||||
* Minor releases can change components' versions, but not the major ``kube_version``.
|
* Minor releases can change components' versions, but not the major `kube_version`.
|
||||||
Greater ``kube_version`` requires a new major or minor release. For example, if Kubespray v2.0.0
|
Greater `kube_version` requires a new major or minor release. For example, if Kubespray v2.0.0
|
||||||
is bound to ``kube_version: 1.4.x``, ``calico_version: 0.22.0``, ``etcd_version: v3.0.6``,
|
is bound to `kube_version: 1.4.x`, `calico_version: 0.22.0`, `etcd_version: v3.0.6`,
|
||||||
then Kubespray v2.1.0 may be bound to only minor changes to ``kube_version``, like v1.5.1
|
then Kubespray v2.1.0 may be bound to only minor changes to `kube_version`, like v1.5.1
|
||||||
and *any* changes to other components, like etcd v4, or calico 1.2.3.
|
and *any* changes to other components, like etcd v4, or calico 1.2.3.
|
||||||
And Kubespray v3.x.x shall be bound to ``kube_version: 2.x.x`` respectively.
|
And Kubespray v3.x.x shall be bound to `kube_version: 2.x.x` respectively.
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
# Defined below are the security contacts for this repo.
|
# Defined below are the security contacts for this repo.
|
||||||
#
|
#
|
||||||
# They are the contact point for the Product Security Team to reach out
|
# They are the contact point for the Product Security Committee to reach out
|
||||||
# to for triaging and handling of incoming issues.
|
# to for triaging and handling of incoming issues.
|
||||||
#
|
#
|
||||||
# The below names agree to abide by the
|
# The below names agree to abide by the
|
||||||
# [Embargo Policy](https://github.com/kubernetes/sig-release/blob/master/security-release-process-documentation/security-release-process.md#embargo-policy)
|
# [Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy)
|
||||||
# and will be removed and replaced if they violate that agreement.
|
# and will be removed and replaced if they violate that agreement.
|
||||||
#
|
#
|
||||||
# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
|
# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
|
||||||
# INSTRUCTIONS AT https://kubernetes.io/security/
|
# INSTRUCTIONS AT https://kubernetes.io/security/
|
||||||
atoms
|
atoms
|
||||||
mattymo
|
mattymo
|
||||||
|
122
Vagrantfile
vendored
122
Vagrantfile
vendored
@ -7,62 +7,72 @@ require 'fileutils'
|
|||||||
|
|
||||||
Vagrant.require_version ">= 2.0.0"
|
Vagrant.require_version ">= 2.0.0"
|
||||||
|
|
||||||
CONFIG = File.join(File.dirname(__FILE__), "vagrant/config.rb")
|
CONFIG = File.join(File.dirname(__FILE__), ENV['KUBESPRAY_VAGRANT_CONFIG'] || 'vagrant/config.rb')
|
||||||
|
|
||||||
COREOS_URL_TEMPLATE = "https://storage.googleapis.com/%s.release.core-os.net/amd64-usr/current/coreos_production_vagrant.json"
|
FLATCAR_URL_TEMPLATE = "https://%s.release.flatcar-linux.net/amd64-usr/current/flatcar_production_vagrant.json"
|
||||||
|
|
||||||
# Uniq disk UUID for libvirt
|
# Uniq disk UUID for libvirt
|
||||||
DISK_UUID = Time.now.utc.to_i
|
DISK_UUID = Time.now.utc.to_i
|
||||||
|
|
||||||
SUPPORTED_OS = {
|
SUPPORTED_OS = {
|
||||||
"coreos-stable" => {box: "coreos-stable", user: "core", box_url: COREOS_URL_TEMPLATE % ["stable"]},
|
"flatcar-stable" => {box: "flatcar-stable", user: "core", box_url: FLATCAR_URL_TEMPLATE % ["stable"]},
|
||||||
"coreos-alpha" => {box: "coreos-alpha", user: "core", box_url: COREOS_URL_TEMPLATE % ["alpha"]},
|
"flatcar-beta" => {box: "flatcar-beta", user: "core", box_url: FLATCAR_URL_TEMPLATE % ["beta"]},
|
||||||
"coreos-beta" => {box: "coreos-beta", user: "core", box_url: COREOS_URL_TEMPLATE % ["beta"]},
|
"flatcar-alpha" => {box: "flatcar-alpha", user: "core", box_url: FLATCAR_URL_TEMPLATE % ["alpha"]},
|
||||||
"ubuntu1604" => {box: "generic/ubuntu1604", user: "vagrant"},
|
"flatcar-edge" => {box: "flatcar-edge", user: "core", box_url: FLATCAR_URL_TEMPLATE % ["edge"]},
|
||||||
"ubuntu1804" => {box: "generic/ubuntu1804", user: "vagrant"},
|
"ubuntu1604" => {box: "generic/ubuntu1604", user: "vagrant"},
|
||||||
"centos" => {box: "centos/7", user: "vagrant"},
|
"ubuntu1804" => {box: "generic/ubuntu1804", user: "vagrant"},
|
||||||
"centos-bento" => {box: "bento/centos-7.5", user: "vagrant"},
|
"ubuntu2004" => {box: "generic/ubuntu2004", user: "vagrant"},
|
||||||
"fedora" => {box: "fedora/28-cloud-base", user: "vagrant"},
|
"centos" => {box: "centos/7", user: "vagrant"},
|
||||||
"opensuse" => {box: "opensuse/openSUSE-15.0-x86_64", user: "vagrant"},
|
"centos-bento" => {box: "bento/centos-7.6", user: "vagrant"},
|
||||||
"opensuse-tumbleweed" => {box: "opensuse/openSUSE-Tumbleweed-x86_64", user: "vagrant"},
|
"centos8" => {box: "centos/8", user: "vagrant"},
|
||||||
|
"centos8-bento" => {box: "bento/centos-8", user: "vagrant"},
|
||||||
|
"fedora31" => {box: "fedora/31-cloud-base", user: "vagrant"},
|
||||||
|
"fedora32" => {box: "fedora/32-cloud-base", user: "vagrant"},
|
||||||
|
"opensuse" => {box: "bento/opensuse-leap-15.1", user: "vagrant"},
|
||||||
|
"opensuse-tumbleweed" => {box: "opensuse/Tumbleweed.x86_64", user: "vagrant"},
|
||||||
|
"oraclelinux" => {box: "generic/oracle7", user: "vagrant"},
|
||||||
|
"oraclelinux8" => {box: "generic/oracle8", user: "vagrant"},
|
||||||
}
|
}
|
||||||
|
|
||||||
# Defaults for config options defined in CONFIG
|
|
||||||
$num_instances = 3
|
|
||||||
$instance_name_prefix = "k8s"
|
|
||||||
$vm_gui = false
|
|
||||||
$vm_memory = 2048
|
|
||||||
$vm_cpus = 1
|
|
||||||
$shared_folders = {}
|
|
||||||
$forwarded_ports = {}
|
|
||||||
$subnet = "172.17.8"
|
|
||||||
$os = "ubuntu1804"
|
|
||||||
$network_plugin = "flannel"
|
|
||||||
# Setting multi_networking to true will install Multus: https://github.com/intel/multus-cni
|
|
||||||
$multi_networking = false
|
|
||||||
# The first three nodes are etcd servers
|
|
||||||
$etcd_instances = $num_instances
|
|
||||||
# The first two nodes are kube masters
|
|
||||||
$kube_master_instances = $num_instances == 1 ? $num_instances : ($num_instances - 1)
|
|
||||||
# All nodes are kube nodes
|
|
||||||
$kube_node_instances = $num_instances
|
|
||||||
# The following only works when using the libvirt provider
|
|
||||||
$kube_node_instances_with_disks = false
|
|
||||||
$kube_node_instances_with_disks_size = "20G"
|
|
||||||
$kube_node_instances_with_disks_number = 2
|
|
||||||
$override_disk_size = false
|
|
||||||
$disk_size = "20GB"
|
|
||||||
$local_path_provisioner_enabled = false
|
|
||||||
$local_path_provisioner_claim_root = "/opt/local-path-provisioner/"
|
|
||||||
|
|
||||||
$playbook = "cluster.yml"
|
|
||||||
|
|
||||||
host_vars = {}
|
|
||||||
|
|
||||||
if File.exist?(CONFIG)
|
if File.exist?(CONFIG)
|
||||||
require CONFIG
|
require CONFIG
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Defaults for config options defined in CONFIG
|
||||||
|
$num_instances ||= 3
|
||||||
|
$instance_name_prefix ||= "k8s"
|
||||||
|
$vm_gui ||= false
|
||||||
|
$vm_memory ||= 2048
|
||||||
|
$vm_cpus ||= 2
|
||||||
|
$shared_folders ||= {}
|
||||||
|
$forwarded_ports ||= {}
|
||||||
|
$subnet ||= "172.18.8"
|
||||||
|
$os ||= "ubuntu1804"
|
||||||
|
$network_plugin ||= "flannel"
|
||||||
|
# Setting multi_networking to true will install Multus: https://github.com/intel/multus-cni
|
||||||
|
$multi_networking ||= false
|
||||||
|
$download_run_once ||= "True"
|
||||||
|
$download_force_cache ||= "True"
|
||||||
|
# The first three nodes are etcd servers
|
||||||
|
$etcd_instances ||= $num_instances
|
||||||
|
# The first two nodes are kube masters
|
||||||
|
$kube_master_instances ||= $num_instances == 1 ? $num_instances : ($num_instances - 1)
|
||||||
|
# All nodes are kube nodes
|
||||||
|
$kube_node_instances ||= $num_instances
|
||||||
|
# The following only works when using the libvirt provider
|
||||||
|
$kube_node_instances_with_disks ||= false
|
||||||
|
$kube_node_instances_with_disks_size ||= "20G"
|
||||||
|
$kube_node_instances_with_disks_number ||= 2
|
||||||
|
$override_disk_size ||= false
|
||||||
|
$disk_size ||= "20GB"
|
||||||
|
$local_path_provisioner_enabled ||= false
|
||||||
|
$local_path_provisioner_claim_root ||= "/opt/local-path-provisioner/"
|
||||||
|
$libvirt_nested ||= false
|
||||||
|
|
||||||
|
$playbook ||= "cluster.yml"
|
||||||
|
|
||||||
|
host_vars = {}
|
||||||
|
|
||||||
$box = SUPPORTED_OS[$os][:box]
|
$box = SUPPORTED_OS[$os][:box]
|
||||||
# if $inventory is not set, try to use example
|
# if $inventory is not set, try to use example
|
||||||
$inventory = "inventory/sample" if ! $inventory
|
$inventory = "inventory/sample" if ! $inventory
|
||||||
@ -135,6 +145,8 @@ Vagrant.configure("2") do |config|
|
|||||||
end
|
end
|
||||||
|
|
||||||
node.vm.provider :libvirt do |lv|
|
node.vm.provider :libvirt do |lv|
|
||||||
|
lv.nested = $libvirt_nested
|
||||||
|
lv.cpu_mode = "host-model"
|
||||||
lv.memory = $vm_memory
|
lv.memory = $vm_memory
|
||||||
lv.cpus = $vm_cpus
|
lv.cpus = $vm_cpus
|
||||||
lv.default_prefix = 'kubespray'
|
lv.default_prefix = 'kubespray'
|
||||||
@ -175,16 +187,30 @@ Vagrant.configure("2") do |config|
|
|||||||
# Disable swap for each vm
|
# Disable swap for each vm
|
||||||
node.vm.provision "shell", inline: "swapoff -a"
|
node.vm.provision "shell", inline: "swapoff -a"
|
||||||
|
|
||||||
|
# Disable firewalld on oraclelinux vms
|
||||||
|
if ["oraclelinux","oraclelinux8"].include? $os
|
||||||
|
node.vm.provision "shell", inline: "systemctl stop firewalld; systemctl disable firewalld"
|
||||||
|
end
|
||||||
|
|
||||||
host_vars[vm_name] = {
|
host_vars[vm_name] = {
|
||||||
"ip": ip,
|
"ip": ip,
|
||||||
"flannel_interface": "eth1",
|
"flannel_interface": "eth1",
|
||||||
"kube_network_plugin": $network_plugin,
|
"kube_network_plugin": $network_plugin,
|
||||||
"kube_network_plugin_multus": $multi_networking,
|
"kube_network_plugin_multus": $multi_networking,
|
||||||
"docker_keepcache": "1",
|
"download_run_once": $download_run_once,
|
||||||
"download_run_once": "False",
|
|
||||||
"download_localhost": "False",
|
"download_localhost": "False",
|
||||||
|
"download_cache_dir": ENV['HOME'] + "/kubespray_cache",
|
||||||
|
# Make kubespray cache even when download_run_once is false
|
||||||
|
"download_force_cache": $download_force_cache,
|
||||||
|
# Keeping the cache on the nodes can improve provisioning speed while debugging kubespray
|
||||||
|
"download_keep_remote_cache": "False",
|
||||||
|
"docker_rpm_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_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.
|
# Only execute the Ansible provisioner once, when all the machines are up and ready.
|
||||||
@ -196,7 +222,7 @@ Vagrant.configure("2") do |config|
|
|||||||
ansible.inventory_path = $ansible_inventory_path
|
ansible.inventory_path = $ansible_inventory_path
|
||||||
end
|
end
|
||||||
ansible.become = true
|
ansible.become = true
|
||||||
ansible.limit = "all"
|
ansible.limit = "all,localhost"
|
||||||
ansible.host_key_checking = false
|
ansible.host_key_checking = false
|
||||||
ansible.raw_arguments = ["--forks=#{$num_instances}", "--flush-cache", "-e ansible_become_pass=vagrant"]
|
ansible.raw_arguments = ["--forks=#{$num_instances}", "--flush-cache", "-e ansible_become_pass=vagrant"]
|
||||||
ansible.host_vars = host_vars
|
ansible.host_vars = host_vars
|
||||||
|
@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
theme: jekyll-theme-slate
|
theme: jekyll-theme-slate
|
||||||
|
@ -4,16 +4,20 @@ ssh_args = -o ControlMaster=auto -o ControlPersist=30m -o ConnectionAttempts=100
|
|||||||
#control_path = ~/.ssh/ansible-%%r@%%h:%%p
|
#control_path = ~/.ssh/ansible-%%r@%%h:%%p
|
||||||
[defaults]
|
[defaults]
|
||||||
strategy_plugins = plugins/mitogen/ansible_mitogen/plugins/strategy
|
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
|
host_key_checking=False
|
||||||
gathering = smart
|
gathering = smart
|
||||||
fact_caching = jsonfile
|
fact_caching = jsonfile
|
||||||
fact_caching_connection = /tmp
|
fact_caching_connection = /tmp
|
||||||
stdout_callback = skippy
|
fact_caching_timeout = 7200
|
||||||
|
stdout_callback = default
|
||||||
|
display_skipped_hosts = no
|
||||||
library = ./library
|
library = ./library
|
||||||
callback_whitelist = profile_tasks
|
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
|
roles_path = roles:$VIRTUAL_ENV/usr/local/share/kubespray/roles:$VIRTUAL_ENV/usr/local/share/ansible/roles:/usr/share/kubespray/roles
|
||||||
deprecation_warnings=False
|
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]
|
[inventory]
|
||||||
ignore_patterns = artifacts, credentials
|
ignore_patterns = artifacts, credentials
|
||||||
|
15
ansible_version.yml
Normal file
15
ansible_version.yml
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
- hosts: localhost
|
||||||
|
gather_facts: false
|
||||||
|
become: no
|
||||||
|
vars:
|
||||||
|
minimal_ansible_version: 2.8.0
|
||||||
|
ansible_connection: local
|
||||||
|
tasks:
|
||||||
|
- name: "Check ansible version >={{ minimal_ansible_version }}"
|
||||||
|
assert:
|
||||||
|
msg: "Ansible must be {{ minimal_ansible_version }} or higher"
|
||||||
|
that:
|
||||||
|
- ansible_version.string is version(minimal_ansible_version, ">=")
|
||||||
|
tags:
|
||||||
|
- check
|
134
cluster.yml
134
cluster.yml
@ -1,117 +1,137 @@
|
|||||||
---
|
---
|
||||||
- hosts: localhost
|
- name: Check ansible version
|
||||||
|
import_playbook: ansible_version.yml
|
||||||
|
|
||||||
|
- hosts: all
|
||||||
gather_facts: false
|
gather_facts: false
|
||||||
become: no
|
tags: always
|
||||||
tasks:
|
tasks:
|
||||||
- name: "Check ansible version >=2.7.6"
|
- name: "Set up proxy environment"
|
||||||
assert:
|
set_fact:
|
||||||
msg: "Ansible must be v2.7.6 or higher"
|
proxy_env:
|
||||||
that:
|
http_proxy: "{{ http_proxy | default ('') }}"
|
||||||
- ansible_version.string is version("2.7.6", ">=")
|
HTTP_PROXY: "{{ http_proxy | default ('') }}"
|
||||||
tags:
|
https_proxy: "{{ https_proxy | default ('') }}"
|
||||||
- check
|
HTTPS_PROXY: "{{ https_proxy | default ('') }}"
|
||||||
vars:
|
no_proxy: "{{ no_proxy | default ('') }}"
|
||||||
ansible_connection: local
|
NO_PROXY: "{{ no_proxy | default ('') }}"
|
||||||
|
no_log: true
|
||||||
|
|
||||||
- hosts: bastion[0]
|
- hosts: bastion[0]
|
||||||
gather_facts: False
|
gather_facts: False
|
||||||
roles:
|
roles:
|
||||||
- { role: kubespray-defaults}
|
- { role: kubespray-defaults }
|
||||||
- { role: bastion-ssh-config, tags: ["localhost", "bastion"]}
|
- { role: bastion-ssh-config, tags: ["localhost", "bastion"] }
|
||||||
|
|
||||||
- hosts: k8s-cluster:etcd:calico-rr
|
- hosts: k8s-cluster:etcd
|
||||||
|
strategy: linear
|
||||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||||
gather_facts: false
|
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:
|
roles:
|
||||||
- { role: kubespray-defaults}
|
- { role: kubespray-defaults }
|
||||||
- { role: bootstrap-os, tags: bootstrap-os}
|
- { role: bootstrap-os, tags: bootstrap-os}
|
||||||
|
|
||||||
- hosts: k8s-cluster:etcd:calico-rr
|
- name: Gather facts
|
||||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
tags: always
|
||||||
vars:
|
import_playbook: facts.yml
|
||||||
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
|
||||||
|
gather_facts: False
|
||||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||||
roles:
|
roles:
|
||||||
- { role: kubespray-defaults}
|
- { role: kubespray-defaults }
|
||||||
- { role: kubernetes/preinstall, tags: preinstall }
|
- { role: kubernetes/preinstall, tags: preinstall }
|
||||||
- { role: "container-engine", tags: "container-engine", when: deploy_container_engine|default(true) }
|
- { role: "container-engine", tags: "container-engine", when: deploy_container_engine|default(true) }
|
||||||
- { role: download, tags: download, when: "not skip_downloads" }
|
- { role: download, tags: download, when: "not skip_downloads" }
|
||||||
environment: "{{proxy_env}}"
|
environment: "{{ proxy_env }}"
|
||||||
|
|
||||||
- hosts: etcd
|
- hosts: etcd
|
||||||
|
gather_facts: False
|
||||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||||
roles:
|
roles:
|
||||||
- { role: kubespray-defaults}
|
- { role: kubespray-defaults }
|
||||||
- { role: etcd, tags: etcd, etcd_cluster_setup: true, etcd_events_cluster_setup: "{{ etcd_events_cluster_enabled }}" }
|
- role: etcd
|
||||||
|
tags: etcd
|
||||||
- hosts: k8s-cluster:calico-rr
|
vars:
|
||||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
etcd_cluster_setup: true
|
||||||
roles:
|
etcd_events_cluster_setup: "{{ etcd_events_cluster_enabled }}"
|
||||||
- { role: kubespray-defaults}
|
when: not etcd_kubeadm_enabled| default(false)
|
||||||
- { role: etcd, tags: etcd, etcd_cluster_setup: false, etcd_events_cluster_setup: false }
|
|
||||||
|
|
||||||
- hosts: k8s-cluster
|
- hosts: k8s-cluster
|
||||||
|
gather_facts: False
|
||||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||||
roles:
|
roles:
|
||||||
- { role: kubespray-defaults}
|
- { role: kubespray-defaults }
|
||||||
|
- role: etcd
|
||||||
|
tags: etcd
|
||||||
|
vars:
|
||||||
|
etcd_cluster_setup: false
|
||||||
|
etcd_events_cluster_setup: false
|
||||||
|
when: not etcd_kubeadm_enabled| default(false)
|
||||||
|
|
||||||
|
- hosts: k8s-cluster
|
||||||
|
gather_facts: False
|
||||||
|
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||||
|
roles:
|
||||||
|
- { role: kubespray-defaults }
|
||||||
- { role: kubernetes/node, tags: node }
|
- { role: kubernetes/node, tags: node }
|
||||||
environment: "{{proxy_env}}"
|
environment: "{{ proxy_env }}"
|
||||||
|
|
||||||
- hosts: kube-master
|
- hosts: kube-master
|
||||||
|
gather_facts: False
|
||||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||||
roles:
|
roles:
|
||||||
- { role: kubespray-defaults}
|
- { role: kubespray-defaults }
|
||||||
- { role: kubernetes/master, tags: master }
|
- { role: kubernetes/master, tags: master }
|
||||||
- { role: kubernetes/client, tags: client }
|
- { role: kubernetes/client, tags: client }
|
||||||
- { role: kubernetes-apps/cluster_roles, tags: cluster-roles }
|
- { role: kubernetes-apps/cluster_roles, tags: cluster-roles }
|
||||||
|
|
||||||
- hosts: k8s-cluster
|
- hosts: k8s-cluster
|
||||||
|
gather_facts: False
|
||||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||||
roles:
|
roles:
|
||||||
- { role: kubespray-defaults}
|
- { role: kubespray-defaults }
|
||||||
- { role: kubernetes/kubeadm, tags: kubeadm}
|
- { role: kubernetes/kubeadm, tags: kubeadm}
|
||||||
- { role: network_plugin, tags: network }
|
- { role: network_plugin, tags: network }
|
||||||
|
- { role: kubernetes/node-label, tags: node-label }
|
||||||
|
|
||||||
|
- hosts: calico-rr
|
||||||
|
gather_facts: False
|
||||||
|
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]
|
- hosts: kube-master[0]
|
||||||
|
gather_facts: False
|
||||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||||
roles:
|
roles:
|
||||||
- { role: kubespray-defaults}
|
- { role: kubespray-defaults }
|
||||||
- { role: kubernetes-apps/rotate_tokens, tags: rotate_tokens, when: "secret_changed|default(false)" }
|
- { role: kubernetes-apps/rotate_tokens, tags: rotate_tokens, when: "secret_changed|default(false)" }
|
||||||
- { role: win_nodes/kubernetes_patch, tags: ["master", "win_nodes"]}
|
- { role: win_nodes/kubernetes_patch, tags: ["master", "win_nodes"] }
|
||||||
|
|
||||||
- hosts: kube-master
|
- hosts: kube-master
|
||||||
|
gather_facts: False
|
||||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||||
roles:
|
roles:
|
||||||
- { role: kubespray-defaults}
|
- { role: kubespray-defaults }
|
||||||
|
- { role: kubernetes-apps/external_cloud_controller, tags: external-cloud-controller }
|
||||||
- { role: kubernetes-apps/network_plugin, tags: network }
|
- { role: kubernetes-apps/network_plugin, tags: network }
|
||||||
- { role: kubernetes-apps/policy_controller, tags: policy-controller }
|
- { role: kubernetes-apps/policy_controller, tags: policy-controller }
|
||||||
- { role: kubernetes-apps/ingress_controller, tags: ingress-controller }
|
- { role: kubernetes-apps/ingress_controller, tags: ingress-controller }
|
||||||
- { role: kubernetes-apps/external_provisioner, tags: external-provisioner }
|
- { 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
|
- hosts: kube-master
|
||||||
|
gather_facts: False
|
||||||
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
any_errors_fatal: "{{ any_errors_fatal | default(true) }}"
|
||||||
roles:
|
roles:
|
||||||
- { role: kubespray-defaults}
|
- { role: kubespray-defaults }
|
||||||
- { role: kubernetes-apps, tags: apps }
|
- { role: kubernetes-apps, tags: apps }
|
||||||
|
environment: "{{ proxy_env }}"
|
||||||
|
|
||||||
|
- hosts: k8s-cluster
|
||||||
|
gather_facts: False
|
||||||
|
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 }
|
- { 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']
|
region = os.environ['REGION']
|
||||||
|
|
||||||
ec2 = boto3.resource('ec2', region)
|
ec2 = boto3.resource('ec2', region)
|
||||||
|
filters = [{'Name': 'tag:'+tag_key, 'Values': tag_value}, {'Name': 'instance-state-name', 'Values': ['running']}]
|
||||||
instances = ec2.instances.filter(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:
|
for instance in instances:
|
||||||
|
|
||||||
##Suppose default vpc_visibility is private
|
##Suppose default vpc_visibility is private
|
||||||
|
@ -15,8 +15,9 @@ Resource Group. It will not install Kubernetes itself, this has to be done in a
|
|||||||
|
|
||||||
## Configuration through group_vars/all
|
## Configuration through group_vars/all
|
||||||
|
|
||||||
You have to modify at least one variable in group_vars/all, which is the **cluster_name** variable. It must be globally
|
You have to modify at least two variables in group_vars/all. The one is the **cluster_name** variable, it must be globally
|
||||||
unique due to some restrictions in Azure. Most other variables should be self explanatory if you have some basic Kubernetes
|
unique due to some restrictions in Azure. The other one is the **ssh_public_keys** variable, it must be your ssh public
|
||||||
|
key to access your azure virtual machines. Most other variables should be self explanatory if you have some basic Kubernetes
|
||||||
experience.
|
experience.
|
||||||
|
|
||||||
## Bastion host
|
## Bastion host
|
||||||
@ -59,6 +60,7 @@ It will create the file ./inventory which can then be used with kubespray, e.g.:
|
|||||||
|
|
||||||
```shell
|
```shell
|
||||||
$ cd kubespray-root-dir
|
$ cd kubespray-root-dir
|
||||||
$ ansible-playbook -i contrib/azurerm/inventory -u devops --become -e "@inventory/sample/group_vars/all.yml" cluster.yml
|
$ sudo pip3 install -r requirements.txt
|
||||||
|
$ ansible-playbook -i contrib/azurerm/inventory -u devops --become -e "@inventory/sample/group_vars/all/all.yml" cluster.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -9,18 +9,11 @@ if [ "$AZURE_RESOURCE_GROUP" == "" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if az &>/dev/null; then
|
ansible-playbook generate-templates.yml
|
||||||
echo "azure cli 2.0 found, using it instead of 1.0"
|
|
||||||
./apply-rg_2.sh "$AZURE_RESOURCE_GROUP"
|
az deployment group create --template-file ./.generated/network.json -g $AZURE_RESOURCE_GROUP
|
||||||
elif azure &>/dev/null; then
|
az deployment group create --template-file ./.generated/storage.json -g $AZURE_RESOURCE_GROUP
|
||||||
ansible-playbook generate-templates.yml
|
az deployment group create --template-file ./.generated/availability-sets.json -g $AZURE_RESOURCE_GROUP
|
||||||
|
az deployment group create --template-file ./.generated/bastion.json -g $AZURE_RESOURCE_GROUP
|
||||||
azure group deployment create -f ./.generated/network.json -g $AZURE_RESOURCE_GROUP
|
az deployment group create --template-file ./.generated/masters.json -g $AZURE_RESOURCE_GROUP
|
||||||
azure group deployment create -f ./.generated/storage.json -g $AZURE_RESOURCE_GROUP
|
az deployment group create --template-file ./.generated/minions.json -g $AZURE_RESOURCE_GROUP
|
||||||
azure group deployment create -f ./.generated/availability-sets.json -g $AZURE_RESOURCE_GROUP
|
|
||||||
azure group deployment create -f ./.generated/bastion.json -g $AZURE_RESOURCE_GROUP
|
|
||||||
azure group deployment create -f ./.generated/masters.json -g $AZURE_RESOURCE_GROUP
|
|
||||||
azure group deployment create -f ./.generated/minions.json -g $AZURE_RESOURCE_GROUP
|
|
||||||
else
|
|
||||||
echo "Azure cli not found"
|
|
||||||
fi
|
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
AZURE_RESOURCE_GROUP="$1"
|
|
||||||
|
|
||||||
if [ "$AZURE_RESOURCE_GROUP" == "" ]; then
|
|
||||||
echo "AZURE_RESOURCE_GROUP is missing"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
ansible-playbook generate-templates.yml
|
|
||||||
|
|
||||||
az group deployment create --template-file ./.generated/network.json -g $AZURE_RESOURCE_GROUP
|
|
||||||
az group deployment create --template-file ./.generated/storage.json -g $AZURE_RESOURCE_GROUP
|
|
||||||
az group deployment create --template-file ./.generated/availability-sets.json -g $AZURE_RESOURCE_GROUP
|
|
||||||
az group deployment create --template-file ./.generated/bastion.json -g $AZURE_RESOURCE_GROUP
|
|
||||||
az group deployment create --template-file ./.generated/masters.json -g $AZURE_RESOURCE_GROUP
|
|
||||||
az group deployment create --template-file ./.generated/minions.json -g $AZURE_RESOURCE_GROUP
|
|
@ -9,10 +9,6 @@ if [ "$AZURE_RESOURCE_GROUP" == "" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if az &>/dev/null; then
|
ansible-playbook generate-templates.yml
|
||||||
echo "azure cli 2.0 found, using it instead of 1.0"
|
|
||||||
./clear-rg_2.sh "$AZURE_RESOURCE_GROUP"
|
az group deployment create -g "$AZURE_RESOURCE_GROUP" --template-file ./.generated/clear-rg.json --mode Complete
|
||||||
else
|
|
||||||
ansible-playbook generate-templates.yml
|
|
||||||
azure group deployment create -g "$AZURE_RESOURCE_GROUP" -f ./.generated/clear-rg.json -m Complete
|
|
||||||
fi
|
|
||||||
|
@ -1,14 +0,0 @@
|
|||||||
#!/usr/bin/env bash
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
AZURE_RESOURCE_GROUP="$1"
|
|
||||||
|
|
||||||
if [ "$AZURE_RESOURCE_GROUP" == "" ]; then
|
|
||||||
echo "AZURE_RESOURCE_GROUP is missing"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
ansible-playbook generate-templates.yml
|
|
||||||
|
|
||||||
az group deployment create -g "$AZURE_RESOURCE_GROUP" --template-file ./.generated/clear-rg.json --mode Complete
|
|
@ -7,7 +7,7 @@ cluster_name: example
|
|||||||
# node that can be used to access the masters and minions
|
# node that can be used to access the masters and minions
|
||||||
use_bastion: false
|
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.
|
# 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
|
# bastion_domain_prefix: k8s-bastion
|
||||||
|
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
- name: Query Azure VMs
|
- name: Query Azure VMs # noqa 301
|
||||||
command: azure vm list-ip-address --json {{ azure_resource_group }}
|
command: azure vm list-ip-address --json {{ azure_resource_group }}
|
||||||
register: vm_list_cmd
|
register: vm_list_cmd
|
||||||
|
|
||||||
- set_fact:
|
- name: Set vm_list
|
||||||
|
set_fact:
|
||||||
vm_list: "{{ vm_list_cmd.stdout }}"
|
vm_list: "{{ vm_list_cmd.stdout }}"
|
||||||
|
|
||||||
- name: Generate inventory
|
- name: Generate inventory
|
||||||
template: src=inventory.j2 dest="{{playbook_dir}}/inventory"
|
template:
|
||||||
|
src: inventory.j2
|
||||||
|
dest: "{{ playbook_dir }}/inventory"
|
||||||
|
@ -1,16 +1,29 @@
|
|||||||
---
|
---
|
||||||
|
|
||||||
- name: Query Azure VMs IPs
|
- name: Query Azure VMs IPs # noqa 301
|
||||||
command: az vm list-ip-addresses -o json --resource-group {{ azure_resource_group }}
|
command: az vm list-ip-addresses -o json --resource-group {{ azure_resource_group }}
|
||||||
register: vm_ip_list_cmd
|
register: vm_ip_list_cmd
|
||||||
|
|
||||||
- name: Query Azure VMs Roles
|
- name: Query Azure VMs Roles # noqa 301
|
||||||
command: az vm list -o json --resource-group {{ azure_resource_group }}
|
command: az vm list -o json --resource-group {{ azure_resource_group }}
|
||||||
register: vm_list_cmd
|
register: vm_list_cmd
|
||||||
|
|
||||||
- set_fact:
|
- name: Query Azure Load Balancer Public IP # noqa 301
|
||||||
|
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_ip_list: "{{ vm_ip_list_cmd.stdout }}"
|
||||||
vm_roles_list: "{{ vm_list_cmd.stdout }}"
|
vm_roles_list: "{{ vm_list_cmd.stdout }}"
|
||||||
|
lb_pubip: "{{ lb_pubip_cmd.stdout }}"
|
||||||
|
|
||||||
- name: Generate inventory
|
- 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:
|
imageReference:
|
||||||
publisher: "OpenLogic"
|
publisher: "OpenLogic"
|
||||||
offer: "CentOS"
|
offer: "CentOS"
|
||||||
sku: "7.2"
|
sku: "7.5"
|
||||||
version: "latest"
|
version: "latest"
|
||||||
imageReferenceJson: "{{imageReference|to_json}}"
|
imageReferenceJson: "{{imageReference|to_json}}"
|
||||||
|
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
---
|
---
|
||||||
- set_fact:
|
- name: Set base_dir
|
||||||
base_dir: "{{playbook_dir}}/.generated/"
|
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:
|
with_items:
|
||||||
- network.json
|
- network.json
|
||||||
- storage.json
|
- storage.json
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
- name: Null-ify some linux tools to ease DIND
|
- name: Null-ify some linux tools to ease DIND
|
||||||
file:
|
file:
|
||||||
src: "/bin/true"
|
src: "/bin/true"
|
||||||
dest: "{{item}}"
|
dest: "{{ item }}"
|
||||||
state: link
|
state: link
|
||||||
force: yes
|
force: yes
|
||||||
with_items:
|
with_items:
|
||||||
@ -52,7 +52,7 @@
|
|||||||
- rsyslog
|
- rsyslog
|
||||||
- "{{ distro_ssh_service }}"
|
- "{{ distro_ssh_service }}"
|
||||||
|
|
||||||
- name: Create distro user "{{distro_user}}"
|
- name: Create distro user "{{ distro_user }}"
|
||||||
user:
|
user:
|
||||||
name: "{{ distro_user }}"
|
name: "{{ distro_user }}"
|
||||||
uid: 1000
|
uid: 1000
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
- /lib/modules:/lib/modules
|
- /lib/modules:/lib/modules
|
||||||
- "{{ item }}:/dind/docker"
|
- "{{ item }}:/dind/docker"
|
||||||
register: containers
|
register: containers
|
||||||
with_items: "{{groups.containers}}"
|
with_items: "{{ groups.containers }}"
|
||||||
tags:
|
tags:
|
||||||
- addresses
|
- addresses
|
||||||
|
|
||||||
@ -69,7 +69,7 @@
|
|||||||
|
|
||||||
# Running systemd-machine-id-setup doesn't create a unique id for each node container on Debian,
|
# Running systemd-machine-id-setup doesn't create a unique id for each node container on Debian,
|
||||||
# handle manually
|
# handle manually
|
||||||
- name: Re-create unique machine-id (as we may just get what comes in the docker image), needed by some CNIs for mac address seeding (notably weave)
|
- name: Re-create unique machine-id (as we may just get what comes in the docker image), needed by some CNIs for mac address seeding (notably weave) # noqa 301
|
||||||
raw: |
|
raw: |
|
||||||
echo {{ item | hash('sha1') }} > /etc/machine-id.new
|
echo {{ item | hash('sha1') }} > /etc/machine-id.new
|
||||||
mv -b /etc/machine-id.new /etc/machine-id
|
mv -b /etc/machine-id.new /etc/machine-id
|
||||||
@ -79,6 +79,7 @@
|
|||||||
with_items: "{{ containers.results }}"
|
with_items: "{{ containers.results }}"
|
||||||
|
|
||||||
- name: Early hack image install to adapt for DIND
|
- name: Early hack image install to adapt for DIND
|
||||||
|
# noqa 302 - this task uses the raw module intentionally
|
||||||
raw: |
|
raw: |
|
||||||
rm -fv /usr/bin/udevadm /usr/sbin/udevadm
|
rm -fv /usr/bin/udevadm /usr/sbin/udevadm
|
||||||
delegate_to: "{{ item._ansible_item_label|default(item.item) }}"
|
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 range of hosts: inventory.py 10.10.1.3-10.10.1.5
|
||||||
# Add hosts with different ip and access ip:
|
# 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
|
# 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: inventory.py -10.10.1.3
|
||||||
# Delete a host by id: inventory.py -node1
|
# Delete a host by id: inventory.py -node1
|
||||||
#
|
#
|
||||||
@ -39,12 +41,14 @@ from ruamel.yaml import YAML
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
ROLES = ['all', 'kube-master', 'kube-node', 'etcd', 'k8s-cluster',
|
ROLES = ['all', 'kube-master', 'kube-node', 'etcd', 'k8s-cluster',
|
||||||
'calico-rr']
|
'calico-rr']
|
||||||
PROTECTED_NAMES = ROLES
|
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,
|
_boolean_states = {'1': True, 'yes': True, 'true': True, 'on': True,
|
||||||
'0': False, 'no': False, 'false': False, 'off': False}
|
'0': False, 'no': False, 'false': False, 'off': False}
|
||||||
yaml = YAML()
|
yaml = YAML()
|
||||||
@ -59,12 +63,14 @@ def get_var_as_bool(name, default):
|
|||||||
|
|
||||||
|
|
||||||
CONFIG_FILE = os.environ.get("CONFIG_FILE", "./inventory/sample/hosts.yaml")
|
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
|
# Reconfigures cluster distribution at scale
|
||||||
SCALE_THRESHOLD = int(os.environ.get("SCALE_THRESHOLD", 50))
|
SCALE_THRESHOLD = int(os.environ.get("SCALE_THRESHOLD", 50))
|
||||||
MASSIVE_SCALE_THRESHOLD = int(os.environ.get("SCALE_THRESHOLD", 200))
|
MASSIVE_SCALE_THRESHOLD = int(os.environ.get("SCALE_THRESHOLD", 200))
|
||||||
|
|
||||||
DEBUG = get_var_as_bool("DEBUG", True)
|
DEBUG = get_var_as_bool("DEBUG", True)
|
||||||
HOST_PREFIX = os.environ.get("HOST_PREFIX", "node")
|
HOST_PREFIX = os.environ.get("HOST_PREFIX", "node")
|
||||||
|
USE_REAL_HOSTNAME = get_var_as_bool("USE_REAL_HOSTNAME", False)
|
||||||
|
|
||||||
# Configurable as shell vars end
|
# Configurable as shell vars end
|
||||||
|
|
||||||
@ -77,8 +83,8 @@ class KubesprayInventory(object):
|
|||||||
if self.config_file:
|
if self.config_file:
|
||||||
try:
|
try:
|
||||||
self.hosts_file = open(config_file, 'r')
|
self.hosts_file = open(config_file, 'r')
|
||||||
self.yaml_config = yaml.load(self.hosts_file)
|
self.yaml_config = yaml.load_all(self.hosts_file)
|
||||||
except FileNotFoundError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if changed_hosts and changed_hosts[0] in AVAILABLE_COMMANDS:
|
if changed_hosts and changed_hosts[0] in AVAILABLE_COMMANDS:
|
||||||
@ -93,14 +99,16 @@ class KubesprayInventory(object):
|
|||||||
self.purge_invalid_hosts(self.hosts.keys(), PROTECTED_NAMES)
|
self.purge_invalid_hosts(self.hosts.keys(), PROTECTED_NAMES)
|
||||||
self.set_all(self.hosts)
|
self.set_all(self.hosts)
|
||||||
self.set_k8s_cluster()
|
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:
|
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:
|
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())
|
self.set_kube_node(self.hosts.keys())
|
||||||
if len(self.hosts) >= SCALE_THRESHOLD:
|
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
|
else: # Show help if no options
|
||||||
self.show_help()
|
self.show_help()
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
@ -161,6 +169,7 @@ class KubesprayInventory(object):
|
|||||||
|
|
||||||
# FIXME(mattymo): Fix condition where delete then add reuses highest id
|
# FIXME(mattymo): Fix condition where delete then add reuses highest id
|
||||||
next_host_id = highest_host_id + 1
|
next_host_id = highest_host_id + 1
|
||||||
|
next_host = ""
|
||||||
|
|
||||||
all_hosts = existing_hosts.copy()
|
all_hosts = existing_hosts.copy()
|
||||||
for host in changed_hosts:
|
for host in changed_hosts:
|
||||||
@ -185,14 +194,33 @@ class KubesprayInventory(object):
|
|||||||
self.debug("Skipping existing host {0}.".format(ip))
|
self.debug("Skipping existing host {0}.".format(ip))
|
||||||
continue
|
continue
|
||||||
|
|
||||||
next_host = "{0}{1}".format(HOST_PREFIX, next_host_id)
|
if USE_REAL_HOSTNAME:
|
||||||
next_host_id += 1
|
cmd = ("ssh -oStrictHostKeyChecking=no "
|
||||||
|
+ access_ip + " 'hostname -s'")
|
||||||
|
next_host = subprocess.check_output(cmd, shell=True)
|
||||||
|
next_host = next_host.strip().decode('ascii')
|
||||||
|
else:
|
||||||
|
next_host = "{0}{1}".format(HOST_PREFIX, next_host_id)
|
||||||
|
next_host_id += 1
|
||||||
all_hosts[next_host] = {'ansible_host': access_ip,
|
all_hosts[next_host] = {'ansible_host': access_ip,
|
||||||
'ip': ip,
|
'ip': ip,
|
||||||
'access_ip': access_ip}
|
'access_ip': access_ip}
|
||||||
elif host[0].isalpha():
|
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
|
return all_hosts
|
||||||
|
|
||||||
def range2ips(self, hosts):
|
def range2ips(self, hosts):
|
||||||
@ -202,15 +230,15 @@ class KubesprayInventory(object):
|
|||||||
try:
|
try:
|
||||||
# Python 3.x
|
# Python 3.x
|
||||||
start = int(ip_address(start_address))
|
start = int(ip_address(start_address))
|
||||||
end = int(ip_address(end_address))
|
end = int(ip_address(end_address))
|
||||||
except:
|
except Exception:
|
||||||
# Python 2.7
|
# Python 2.7
|
||||||
start = int(ip_address(unicode(start_address)))
|
start = int(ip_address(str(start_address)))
|
||||||
end = int(ip_address(unicode(end_address)))
|
end = int(ip_address(str(end_address)))
|
||||||
return [ip_address(ip).exploded for ip in range(start, end + 1)]
|
return [ip_address(ip).exploded for ip in range(start, end + 1)]
|
||||||
|
|
||||||
for host in hosts:
|
for host in hosts:
|
||||||
if '-' in host and not host.startswith('-'):
|
if '-' in host and not (host.startswith('-') or host[0].isalpha()):
|
||||||
start, end = host.strip().split('-')
|
start, end = host.strip().split('-')
|
||||||
try:
|
try:
|
||||||
reworked_hosts.extend(ips(start, end))
|
reworked_hosts.extend(ips(start, end))
|
||||||
@ -345,6 +373,8 @@ class KubesprayInventory(object):
|
|||||||
self.print_config()
|
self.print_config()
|
||||||
elif command == 'print_ips':
|
elif command == 'print_ips':
|
||||||
self.print_ips()
|
self.print_ips()
|
||||||
|
elif command == 'print_hostnames':
|
||||||
|
self.print_hostnames()
|
||||||
elif command == 'load':
|
elif command == 'load':
|
||||||
self.load_file(args)
|
self.load_file(args)
|
||||||
else:
|
else:
|
||||||
@ -358,11 +388,13 @@ Available commands:
|
|||||||
help - Display this message
|
help - Display this message
|
||||||
print_cfg - Write inventory file to stdout
|
print_cfg - Write inventory file to stdout
|
||||||
print_ips - Write a space-delimited list of IPs from "all" group
|
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:
|
Advanced usage:
|
||||||
Add another host after initial creation: inventory.py 10.10.1.5
|
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 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 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: inventory.py -10.10.1.3
|
||||||
Delete a host by id: inventory.py -node1
|
Delete a host by id: inventory.py -node1
|
||||||
|
|
||||||
@ -378,6 +410,9 @@ MASSIVE_SCALE_THRESHOLD Separate K8s master and ETCD if # of nodes >= 200
|
|||||||
def print_config(self):
|
def print_config(self):
|
||||||
yaml.dump(self.yaml_config, sys.stdout)
|
yaml.dump(self.yaml_config, sys.stdout)
|
||||||
|
|
||||||
|
def print_hostnames(self):
|
||||||
|
print(' '.join(self.yaml_config['all']['hosts'].keys()))
|
||||||
|
|
||||||
def print_ips(self):
|
def print_ips(self):
|
||||||
ips = []
|
ips = []
|
||||||
for host, opts in self.yaml_config['all']['hosts'].items():
|
for host, opts in self.yaml_config['all']['hosts'].items():
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
|
import inventory
|
||||||
import mock
|
import mock
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ path = "./contrib/inventory_builder/"
|
|||||||
if path not in sys.path:
|
if path not in sys.path:
|
||||||
sys.path.append(path)
|
sys.path.append(path)
|
||||||
|
|
||||||
import inventory
|
import inventory # noqa
|
||||||
|
|
||||||
|
|
||||||
class TestInventory(unittest.TestCase):
|
class TestInventory(unittest.TestCase):
|
||||||
@ -43,8 +44,8 @@ class TestInventory(unittest.TestCase):
|
|||||||
|
|
||||||
def test_get_ip_from_opts_invalid(self):
|
def test_get_ip_from_opts_invalid(self):
|
||||||
optstring = "notanaddr=value something random!chars:D"
|
optstring = "notanaddr=value something random!chars:D"
|
||||||
self.assertRaisesRegexp(ValueError, "IP parameter not found",
|
self.assertRaisesRegex(ValueError, "IP parameter not found",
|
||||||
self.inv.get_ip_from_opts, optstring)
|
self.inv.get_ip_from_opts, optstring)
|
||||||
|
|
||||||
def test_ensure_required_groups(self):
|
def test_ensure_required_groups(self):
|
||||||
groups = ['group1', 'group2']
|
groups = ['group1', 'group2']
|
||||||
@ -63,8 +64,8 @@ class TestInventory(unittest.TestCase):
|
|||||||
def test_get_host_id_invalid(self):
|
def test_get_host_id_invalid(self):
|
||||||
bad_hostnames = ['node', 'no99de', '01node', 'node.111111']
|
bad_hostnames = ['node', 'no99de', '01node', 'node.111111']
|
||||||
for hostname in bad_hostnames:
|
for hostname in bad_hostnames:
|
||||||
self.assertRaisesRegexp(ValueError, "Host name must end in an",
|
self.assertRaisesRegex(ValueError, "Host name must end in an",
|
||||||
self.inv.get_host_id, hostname)
|
self.inv.get_host_id, hostname)
|
||||||
|
|
||||||
def test_build_hostnames_add_one(self):
|
def test_build_hostnames_add_one(self):
|
||||||
changed_hosts = ['10.90.0.2']
|
changed_hosts = ['10.90.0.2']
|
||||||
@ -192,8 +193,8 @@ class TestInventory(unittest.TestCase):
|
|||||||
('node2', {'ansible_host': '10.90.0.3',
|
('node2', {'ansible_host': '10.90.0.3',
|
||||||
'ip': '10.90.0.3',
|
'ip': '10.90.0.3',
|
||||||
'access_ip': '10.90.0.3'})])
|
'access_ip': '10.90.0.3'})])
|
||||||
self.assertRaisesRegexp(ValueError, "Unable to find host",
|
self.assertRaisesRegex(ValueError, "Unable to find host",
|
||||||
self.inv.delete_host_by_ip, existing_hosts, ip)
|
self.inv.delete_host_by_ip, existing_hosts, ip)
|
||||||
|
|
||||||
def test_purge_invalid_hosts(self):
|
def test_purge_invalid_hosts(self):
|
||||||
proper_hostnames = ['node1', 'node2']
|
proper_hostnames = ['node1', 'node2']
|
||||||
@ -309,8 +310,8 @@ class TestInventory(unittest.TestCase):
|
|||||||
|
|
||||||
def test_range2ips_incorrect_range(self):
|
def test_range2ips_incorrect_range(self):
|
||||||
host_range = ['10.90.0.4-a.9b.c.e']
|
host_range = ['10.90.0.4-a.9b.c.e']
|
||||||
self.assertRaisesRegexp(Exception, "Range of ip_addresses isn't valid",
|
self.assertRaisesRegex(Exception, "Range of ip_addresses isn't valid",
|
||||||
self.inv.range2ips, host_range)
|
self.inv.range2ips, host_range)
|
||||||
|
|
||||||
def test_build_hostnames_different_ips_add_one(self):
|
def test_build_hostnames_different_ips_add_one(self):
|
||||||
changed_hosts = ['10.90.0.2,192.168.0.2']
|
changed_hosts = ['10.90.0.2,192.168.0.2']
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
[tox]
|
[tox]
|
||||||
minversion = 1.6
|
minversion = 1.6
|
||||||
skipsdist = True
|
skipsdist = True
|
||||||
envlist = pep8, py27
|
envlist = pep8, py33
|
||||||
|
|
||||||
[testenv]
|
[testenv]
|
||||||
whitelist_externals = py.test
|
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
|
- name: Install required packages
|
||||||
yum:
|
yum:
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
state: latest
|
state: present
|
||||||
with_items:
|
with_items:
|
||||||
- bind-utils
|
- bind-utils
|
||||||
- ntp
|
- ntp
|
||||||
@ -21,23 +15,13 @@
|
|||||||
update_cache: yes
|
update_cache: yes
|
||||||
cache_valid_time: 3600
|
cache_valid_time: 3600
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
state: latest
|
state: present
|
||||||
install_recommends: no
|
install_recommends: no
|
||||||
with_items:
|
with_items:
|
||||||
- dnsutils
|
- dnsutils
|
||||||
- ntp
|
- ntp
|
||||||
when: ansible_os_family == "Debian"
|
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
|
# Create deployment user if required
|
||||||
- include: user.yml
|
- include: user.yml
|
||||||
when: k8s_deployment_user is defined
|
when: k8s_deployment_user is defined
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
# Deploy MetalLB into Kubespray/Kubernetes
|
|
||||||
```
|
|
||||||
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.
|
|
||||||
|
|
||||||
## Install
|
|
||||||
```
|
|
||||||
ansible-playbook --ask-become -i inventory/sample/hosts.ini contrib/metallb/metallb.yml
|
|
||||||
```
|
|
@ -1 +0,0 @@
|
|||||||
../../library
|
|
@ -1,6 +0,0 @@
|
|||||||
---
|
|
||||||
- hosts: kube-master[0]
|
|
||||||
tags:
|
|
||||||
- "provision"
|
|
||||||
roles:
|
|
||||||
- { role: provision }
|
|
@ -1,8 +0,0 @@
|
|||||||
---
|
|
||||||
metallb:
|
|
||||||
ip_range: "10.5.0.50-10.5.0.99"
|
|
||||||
limits:
|
|
||||||
cpu: "100m"
|
|
||||||
memory: "100Mi"
|
|
||||||
port: "7472"
|
|
||||||
version: v0.7.3
|
|
@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
- name: "Kubernetes Apps | Lay Down MetalLB"
|
|
||||||
become: true
|
|
||||||
template: { src: "{{ item }}.j2", dest: "{{ kube_config_dir }}/{{ item }}" }
|
|
||||||
with_items: ["metallb.yml", "metallb-config.yml"]
|
|
||||||
register: "rendering"
|
|
||||||
when:
|
|
||||||
- "inventory_hostname == groups['kube-master'][0]"
|
|
||||||
- name: "Kubernetes Apps | Install and configure MetalLB"
|
|
||||||
kube:
|
|
||||||
name: "MetalLB"
|
|
||||||
kubectl: "{{bin_dir}}/kubectl"
|
|
||||||
filename: "{{ kube_config_dir }}/{{ item.item }}"
|
|
||||||
state: "{{ item.changed | ternary('latest','present') }}"
|
|
||||||
become: true
|
|
||||||
with_items: "{{ rendering.results }}"
|
|
||||||
when:
|
|
||||||
- "inventory_hostname == groups['kube-master'][0]"
|
|
@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
namespace: metallb-system
|
|
||||||
name: config
|
|
||||||
data:
|
|
||||||
config: |
|
|
||||||
address-pools:
|
|
||||||
- name: loadbalanced
|
|
||||||
protocol: layer2
|
|
||||||
addresses:
|
|
||||||
- {{ metallb.ip_range }}
|
|
@ -1,221 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: metallb-system
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
---
|
|
||||||
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
namespace: metallb-system
|
|
||||||
name: controller
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
namespace: metallb-system
|
|
||||||
name: speaker
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: metallb-system:controller
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
rules:
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services"]
|
|
||||||
verbs: ["get", "list", "watch", "update"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services/status"]
|
|
||||||
verbs: ["update"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["events"]
|
|
||||||
verbs: ["create", "patch"]
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: metallb-system:speaker
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
rules:
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["services", "endpoints", "nodes"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: Role
|
|
||||||
metadata:
|
|
||||||
namespace: metallb-system
|
|
||||||
name: config-watcher
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
rules:
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["configmaps"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources: ["events"]
|
|
||||||
verbs: ["create"]
|
|
||||||
---
|
|
||||||
|
|
||||||
## Role bindings
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
metadata:
|
|
||||||
name: metallb-system:controller
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: controller
|
|
||||||
namespace: metallb-system
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: ClusterRole
|
|
||||||
name: metallb-system:controller
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
metadata:
|
|
||||||
name: metallb-system:speaker
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: speaker
|
|
||||||
namespace: metallb-system
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: ClusterRole
|
|
||||||
name: metallb-system:speaker
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: RoleBinding
|
|
||||||
metadata:
|
|
||||||
namespace: metallb-system
|
|
||||||
name: config-watcher
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: controller
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: speaker
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: Role
|
|
||||||
name: config-watcher
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1beta2
|
|
||||||
kind: DaemonSet
|
|
||||||
metadata:
|
|
||||||
namespace: metallb-system
|
|
||||||
name: speaker
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
component: speaker
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: metallb
|
|
||||||
component: speaker
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
component: speaker
|
|
||||||
annotations:
|
|
||||||
prometheus.io/scrape: "true"
|
|
||||||
prometheus.io/port: "{{ metallb.port }}"
|
|
||||||
spec:
|
|
||||||
serviceAccountName: speaker
|
|
||||||
terminationGracePeriodSeconds: 0
|
|
||||||
hostNetwork: true
|
|
||||||
containers:
|
|
||||||
- name: speaker
|
|
||||||
image: metallb/speaker:{{ metallb.version }}
|
|
||||||
imagePullPolicy: IfNotPresent
|
|
||||||
args:
|
|
||||||
- --port={{ metallb.port }}
|
|
||||||
- --config=config
|
|
||||||
env:
|
|
||||||
- name: METALLB_NODE_NAME
|
|
||||||
valueFrom:
|
|
||||||
fieldRef:
|
|
||||||
fieldPath: spec.nodeName
|
|
||||||
ports:
|
|
||||||
- name: monitoring
|
|
||||||
containerPort: {{ metallb.port }}
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: {{ metallb.limits.cpu }}
|
|
||||||
memory: {{ metallb.limits.memory }}
|
|
||||||
securityContext:
|
|
||||||
allowPrivilegeEscalation: false
|
|
||||||
readOnlyRootFilesystem: true
|
|
||||||
capabilities:
|
|
||||||
drop:
|
|
||||||
- all
|
|
||||||
add:
|
|
||||||
- net_raw
|
|
||||||
|
|
||||||
---
|
|
||||||
apiVersion: apps/v1beta2
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
namespace: metallb-system
|
|
||||||
name: controller
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
component: controller
|
|
||||||
spec:
|
|
||||||
revisionHistoryLimit: 3
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: metallb
|
|
||||||
component: controller
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: metallb
|
|
||||||
component: controller
|
|
||||||
annotations:
|
|
||||||
prometheus.io/scrape: "true"
|
|
||||||
prometheus.io/port: "{{ metallb.port }}"
|
|
||||||
spec:
|
|
||||||
serviceAccountName: controller
|
|
||||||
terminationGracePeriodSeconds: 0
|
|
||||||
securityContext:
|
|
||||||
runAsNonRoot: true
|
|
||||||
runAsUser: 65534 # nobody
|
|
||||||
containers:
|
|
||||||
- name: controller
|
|
||||||
image: metallb/controller:{{ metallb.version }}
|
|
||||||
imagePullPolicy: IfNotPresent
|
|
||||||
args:
|
|
||||||
- --port={{ metallb.port }}
|
|
||||||
- --config=config
|
|
||||||
ports:
|
|
||||||
- name: monitoring
|
|
||||||
containerPort: {{ metallb.port }}
|
|
||||||
resources:
|
|
||||||
limits:
|
|
||||||
cpu: {{ metallb.limits.cpu }}
|
|
||||||
memory: {{ metallb.limits.memory }}
|
|
||||||
securityContext:
|
|
||||||
allowPrivilegeEscalation: false
|
|
||||||
capabilities:
|
|
||||||
drop:
|
|
||||||
- all
|
|
||||||
readOnlyRootFilesystem: true
|
|
||||||
|
|
||||||
---
|
|
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/v1
|
||||||
|
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_use: yes
|
||||||
glusterfs_ppa_version: "3.5"
|
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
|
## Dependencies
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
register: glusterfs_ppa_added
|
register: glusterfs_ppa_added
|
||||||
when: glusterfs_ppa_use
|
when: glusterfs_ppa_use
|
||||||
|
|
||||||
- name: Ensure GlusterFS client will reinstall if the PPA was just added.
|
- name: Ensure GlusterFS client will reinstall if the PPA was just added. # noqa 503
|
||||||
apt:
|
apt:
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
state: absent
|
state: absent
|
||||||
@ -18,7 +18,7 @@
|
|||||||
- name: Ensure GlusterFS client is installed.
|
- name: Ensure GlusterFS client is installed.
|
||||||
apt:
|
apt:
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
state: installed
|
state: present
|
||||||
default_release: "{{ glusterfs_default_release }}"
|
default_release: "{{ glusterfs_default_release }}"
|
||||||
with_items:
|
with_items:
|
||||||
- glusterfs-client
|
- glusterfs-client
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
- name: Include OS-specific variables.
|
- name: Include OS-specific variables.
|
||||||
include_vars: "{{ ansible_os_family }}.yml"
|
include_vars: "{{ ansible_os_family }}.yml"
|
||||||
|
|
||||||
# Instal xfs package
|
# Install xfs package
|
||||||
- name: install xfs Debian
|
- name: install xfs Debian
|
||||||
apt: name=xfsprogs state=present
|
apt: name=xfsprogs state=present
|
||||||
when: ansible_os_family == "Debian"
|
when: ansible_os_family == "Debian"
|
||||||
@ -36,7 +36,7 @@
|
|||||||
- "{{ gluster_brick_dir }}"
|
- "{{ gluster_brick_dir }}"
|
||||||
- "{{ gluster_mount_dir }}"
|
- "{{ gluster_mount_dir }}"
|
||||||
|
|
||||||
- name: Configure Gluster volume.
|
- name: Configure Gluster volume with replicas
|
||||||
gluster_volume:
|
gluster_volume:
|
||||||
state: present
|
state: present
|
||||||
name: "{{ gluster_brick_name }}"
|
name: "{{ gluster_brick_name }}"
|
||||||
@ -46,6 +46,18 @@
|
|||||||
host: "{{ inventory_hostname }}"
|
host: "{{ inventory_hostname }}"
|
||||||
force: yes
|
force: yes
|
||||||
run_once: true
|
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
|
- name: Mount glusterfs to retrieve disk size
|
||||||
mount:
|
mount:
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
register: glusterfs_ppa_added
|
register: glusterfs_ppa_added
|
||||||
when: glusterfs_ppa_use
|
when: glusterfs_ppa_use
|
||||||
|
|
||||||
- name: Ensure GlusterFS will reinstall if the PPA was just added.
|
- name: Ensure GlusterFS will reinstall if the PPA was just added. # noqa 503
|
||||||
apt:
|
apt:
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
state: absent
|
state: absent
|
||||||
@ -19,7 +19,7 @@
|
|||||||
- name: Ensure GlusterFS is installed.
|
- name: Ensure GlusterFS is installed.
|
||||||
apt:
|
apt:
|
||||||
name: "{{ item }}"
|
name: "{{ item }}"
|
||||||
state: installed
|
state: present
|
||||||
default_release: "{{ glusterfs_default_release }}"
|
default_release: "{{ glusterfs_default_release }}"
|
||||||
with_items:
|
with_items:
|
||||||
- glusterfs-server
|
- glusterfs-server
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
---
|
---
|
||||||
- name: Kubernetes Apps | Lay Down k8s GlusterFS Endpoint and PV
|
- 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:
|
with_items:
|
||||||
- { file: glusterfs-kubernetes-endpoint.json.j2, type: ep, dest: glusterfs-kubernetes-endpoint.json}
|
- { 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}
|
- { file: glusterfs-kubernetes-pv.yml.j2, type: pv, dest: glusterfs-kubernetes-pv.yml}
|
||||||
@ -12,9 +14,9 @@
|
|||||||
kube:
|
kube:
|
||||||
name: glusterfs
|
name: glusterfs
|
||||||
namespace: default
|
namespace: default
|
||||||
kubectl: "{{bin_dir}}/kubectl"
|
kubectl: "{{ bin_dir }}/kubectl"
|
||||||
resource: "{{item.item.type}}"
|
resource: "{{ item.item.type }}"
|
||||||
filename: "{{kube_config_dir}}/{{item.item.dest}}"
|
filename: "{{ kube_config_dir }}/{{ item.item.dest }}"
|
||||||
state: "{{item.changed | ternary('latest','present') }}"
|
state: "{{ item.changed | ternary('latest','present') }}"
|
||||||
with_items: "{{ gluster_pv.results }}"
|
with_items: "{{ gluster_pv.results }}"
|
||||||
when: inventory_hostname == groups['kube-master'][0] and groups['gfs-cluster'] is defined
|
when: inventory_hostname == groups['kube-master'][0] and groups['gfs-cluster'] is defined
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
{% for host in groups['gfs-cluster'] %}
|
{% for host in groups['gfs-cluster'] %}
|
||||||
{
|
{
|
||||||
"addresses": [
|
"addresses": [
|
||||||
{
|
{
|
||||||
"ip": "{{hostvars[host]['ip']|default(hostvars[host].ansible_default_ipv4['address'])}}"
|
"ip": "{{hostvars[host]['ip']|default(hostvars[host].ansible_default_ipv4['address'])}}"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: PersistentVolume
|
kind: PersistentVolume
|
||||||
metadata:
|
metadata:
|
||||||
name: glusterfs
|
name: glusterfs
|
||||||
spec:
|
spec:
|
||||||
capacity:
|
capacity:
|
||||||
storage: "{{ hostvars[groups['gfs-cluster'][0]].gluster_disk_size_gb }}Gi"
|
storage: "{{ hostvars[groups['gfs-cluster'][0]].gluster_disk_size_gb }}Gi"
|
||||||
|
@ -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
|
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"
|
register: "initial_heketi_state"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
command: "{{ bin_dir }}/kubectl get services,deployments,pods --selector=deploy-heketi --output=json"
|
command: "{{ bin_dir }}/kubectl get services,deployments,pods --selector=deploy-heketi --output=json"
|
||||||
|
|
||||||
- name: "Bootstrap heketi."
|
- name: "Bootstrap heketi."
|
||||||
when:
|
when:
|
||||||
- "(initial_heketi_state.stdout|from_json|json_query(\"items[?kind=='Service']\"))|length == 0"
|
- "(initial_heketi_state.stdout|from_json|json_query(\"items[?kind=='Service']\"))|length == 0"
|
||||||
@ -16,15 +17,20 @@
|
|||||||
register: "initial_heketi_pod"
|
register: "initial_heketi_pod"
|
||||||
command: "{{ bin_dir }}/kubectl get pods --selector=deploy-heketi=pod,glusterfs=heketi-pod,name=deploy-heketi --output=json"
|
command: "{{ bin_dir }}/kubectl get pods --selector=deploy-heketi=pod,glusterfs=heketi-pod,name=deploy-heketi --output=json"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: "Ensure heketi bootstrap pod is up."
|
- name: "Ensure heketi bootstrap pod is up."
|
||||||
assert:
|
assert:
|
||||||
that: "(initial_heketi_pod.stdout|from_json|json_query('items[*]'))|length == 1"
|
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]\") }}"
|
initial_heketi_pod_name: "{{ initial_heketi_pod.stdout|from_json|json_query(\"items[*].metadata.name|[0]\") }}"
|
||||||
|
|
||||||
- name: "Test heketi topology."
|
- name: "Test heketi topology."
|
||||||
changed_when: false
|
changed_when: false
|
||||||
register: "heketi_topology"
|
register: "heketi_topology"
|
||||||
command: "{{ bin_dir }}/kubectl exec {{ initial_heketi_pod_name }} -- heketi-cli --user admin --secret {{ heketi_admin_key }} topology info --json"
|
command: "{{ bin_dir }}/kubectl exec {{ initial_heketi_pod_name }} -- heketi-cli --user admin --secret {{ heketi_admin_key }} topology info --json"
|
||||||
|
|
||||||
- name: "Load heketi topology."
|
- name: "Load heketi topology."
|
||||||
when: "heketi_topology.stdout|from_json|json_query(\"clusters[*].nodes[*]\")|flatten|length == 0"
|
when: "heketi_topology.stdout|from_json|json_query(\"clusters[*].nodes[*]\")|flatten|length == 0"
|
||||||
include_tasks: "bootstrap/topology.yml"
|
include_tasks: "bootstrap/topology.yml"
|
||||||
@ -42,6 +48,7 @@
|
|||||||
command: "{{ bin_dir }}/kubectl get secrets,endpoints,services,jobs --output=json"
|
command: "{{ bin_dir }}/kubectl get secrets,endpoints,services,jobs --output=json"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
register: "heketi_storage_state"
|
register: "heketi_storage_state"
|
||||||
|
|
||||||
# ensure endpoints actually exist before trying to move database data to it
|
# ensure endpoints actually exist before trying to move database data to it
|
||||||
- name: "Create heketi storage."
|
- name: "Create heketi storage."
|
||||||
include_tasks: "bootstrap/storage.yml"
|
include_tasks: "bootstrap/storage.yml"
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
- name: "Kubernetes Apps | Install and configure Heketi Bootstrap"
|
- name: "Kubernetes Apps | Install and configure Heketi Bootstrap"
|
||||||
kube:
|
kube:
|
||||||
name: "GlusterFS"
|
name: "GlusterFS"
|
||||||
kubectl: "{{bin_dir}}/kubectl"
|
kubectl: "{{ bin_dir }}/kubectl"
|
||||||
filename: "{{ kube_config_dir }}/heketi-bootstrap.json"
|
filename: "{{ kube_config_dir }}/heketi-bootstrap.json"
|
||||||
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
||||||
- name: "Wait for heketi bootstrap to complete."
|
- name: "Wait for heketi bootstrap to complete."
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
- name: "Create heketi storage."
|
- name: "Create heketi storage."
|
||||||
kube:
|
kube:
|
||||||
name: "GlusterFS"
|
name: "GlusterFS"
|
||||||
kubectl: "{{bin_dir}}/kubectl"
|
kubectl: "{{ bin_dir }}/kubectl"
|
||||||
filename: "{{ kube_config_dir }}/heketi-storage-bootstrap.json"
|
filename: "{{ kube_config_dir }}/heketi-storage-bootstrap.json"
|
||||||
state: "present"
|
state: "present"
|
||||||
vars:
|
vars:
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
- name: "Delete bootstrap Heketi."
|
- name: "Delete bootstrap Heketi."
|
||||||
command: "{{ bin_dir }}/kubectl delete all,service,jobs,deployment,secret --selector=\"deploy-heketi\""
|
command: "{{ bin_dir }}/kubectl delete all,service,jobs,deployment,secret --selector=\"deploy-heketi\""
|
||||||
when: "heketi_resources.stdout|from_json|json_query('items[*]')|length > 0"
|
when: "heketi_resources.stdout|from_json|json_query('items[*]')|length > 0"
|
||||||
- name: "Ensure there is nothing left over."
|
- name: "Ensure there is nothing left over." # noqa 301
|
||||||
command: "{{ bin_dir }}/kubectl get all,service,jobs,deployment,secret --selector=\"deploy-heketi\" -o=json"
|
command: "{{ bin_dir }}/kubectl get all,service,jobs,deployment,secret --selector=\"deploy-heketi\" -o=json"
|
||||||
register: "heketi_result"
|
register: "heketi_result"
|
||||||
until: "heketi_result.stdout|from_json|json_query('items[*]')|length == 0"
|
until: "heketi_result.stdout|from_json|json_query('items[*]')|length == 0"
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
- name: "Copy topology configuration into container."
|
- name: "Copy topology configuration into container."
|
||||||
changed_when: false
|
changed_when: false
|
||||||
command: "{{ bin_dir }}/kubectl cp {{ kube_config_dir }}/topology.json {{ initial_heketi_pod_name }}:/tmp/topology.json"
|
command: "{{ bin_dir }}/kubectl cp {{ kube_config_dir }}/topology.json {{ initial_heketi_pod_name }}:/tmp/topology.json"
|
||||||
- name: "Load heketi topology."
|
- name: "Load heketi topology." # noqa 503
|
||||||
when: "render.changed"
|
when: "render.changed"
|
||||||
command: "{{ bin_dir }}/kubectl exec {{ initial_heketi_pod_name }} -- heketi-cli --user admin --secret {{ heketi_admin_key }} topology load --json=/tmp/topology.json"
|
command: "{{ bin_dir }}/kubectl exec {{ initial_heketi_pod_name }} -- heketi-cli --user admin --secret {{ heketi_admin_key }} topology load --json=/tmp/topology.json"
|
||||||
register: "load_heketi"
|
register: "load_heketi"
|
||||||
|
@ -18,7 +18,7 @@
|
|||||||
- name: "Provision database volume."
|
- name: "Provision database volume."
|
||||||
command: "{{ bin_dir }}/kubectl exec {{ initial_heketi_pod_name }} -- heketi-cli --user admin --secret {{ heketi_admin_key }} setup-openshift-heketi-storage"
|
command: "{{ bin_dir }}/kubectl exec {{ initial_heketi_pod_name }} -- heketi-cli --user admin --secret {{ heketi_admin_key }} setup-openshift-heketi-storage"
|
||||||
when: "heketi_database_volume_exists is undefined"
|
when: "heketi_database_volume_exists is undefined"
|
||||||
- name: "Copy configuration from pod."
|
- name: "Copy configuration from pod." # noqa 301
|
||||||
become: true
|
become: true
|
||||||
command: "{{ bin_dir }}/kubectl cp {{ initial_heketi_pod_name }}:/heketi-storage.json {{ kube_config_dir }}/heketi-storage-bootstrap.json"
|
command: "{{ bin_dir }}/kubectl cp {{ initial_heketi_pod_name }}:/heketi-storage.json {{ kube_config_dir }}/heketi-storage-bootstrap.json"
|
||||||
- name: "Get heketi volume ids."
|
- name: "Get heketi volume ids."
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
- name: "Kubernetes Apps | Install and configure GlusterFS daemonset"
|
- name: "Kubernetes Apps | Install and configure GlusterFS daemonset"
|
||||||
kube:
|
kube:
|
||||||
name: "GlusterFS"
|
name: "GlusterFS"
|
||||||
kubectl: "{{bin_dir}}/kubectl"
|
kubectl: "{{ bin_dir }}/kubectl"
|
||||||
filename: "{{ kube_config_dir }}/glusterfs-daemonset.json"
|
filename: "{{ kube_config_dir }}/glusterfs-daemonset.json"
|
||||||
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
||||||
- name: "Kubernetes Apps | Label GlusterFS nodes"
|
- name: "Kubernetes Apps | Label GlusterFS nodes"
|
||||||
@ -33,6 +33,6 @@
|
|||||||
- name: "Kubernetes Apps | Install and configure Heketi Service Account"
|
- name: "Kubernetes Apps | Install and configure Heketi Service Account"
|
||||||
kube:
|
kube:
|
||||||
name: "GlusterFS"
|
name: "GlusterFS"
|
||||||
kubectl: "{{bin_dir}}/kubectl"
|
kubectl: "{{ bin_dir }}/kubectl"
|
||||||
filename: "{{ kube_config_dir }}/heketi-service-account.json"
|
filename: "{{ kube_config_dir }}/heketi-service-account.json"
|
||||||
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
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"
|
command: "{{ bin_dir }}/kubectl get node --selector=storagenode=glusterfs,kubernetes.io/hostname={{ node }} --ignore-not-found=true"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: "Assign storage label"
|
- name: "Assign storage label"
|
||||||
when: "label_present.stdout_lines|length == 0"
|
when: "label_present.stdout_lines|length == 0"
|
||||||
command: "{{ bin_dir }}/kubectl label node {{ node }} storagenode=glusterfs"
|
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"
|
command: "{{ bin_dir }}/kubectl get node --selector=storagenode=glusterfs,kubernetes.io/hostname={{ node }} --ignore-not-found=true"
|
||||||
changed_when: false
|
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"
|
- name: "Kubernetes Apps | Lay Down Heketi"
|
||||||
become: true
|
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"
|
register: "rendering"
|
||||||
|
|
||||||
- name: "Kubernetes Apps | Install and configure Heketi"
|
- name: "Kubernetes Apps | Install and configure Heketi"
|
||||||
kube:
|
kube:
|
||||||
name: "GlusterFS"
|
name: "GlusterFS"
|
||||||
kubectl: "{{bin_dir}}/kubectl"
|
kubectl: "{{ bin_dir }}/kubectl"
|
||||||
filename: "{{ kube_config_dir }}/heketi-deployment.json"
|
filename: "{{ kube_config_dir }}/heketi-deployment.json"
|
||||||
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
||||||
|
|
||||||
- name: "Ensure heketi is up and running."
|
- name: "Ensure heketi is up and running."
|
||||||
changed_when: false
|
changed_when: false
|
||||||
register: "heketi_state"
|
register: "heketi_state"
|
||||||
vars:
|
vars:
|
||||||
heketi_state: { stdout: "{}" }
|
heketi_state:
|
||||||
|
stdout: "{}"
|
||||||
pods_query: "items[?kind=='Pod'].status.conditions|[0][?type=='Ready'].status|[0]"
|
pods_query: "items[?kind=='Pod'].status.conditions|[0][?type=='Ready'].status|[0]"
|
||||||
deployments_query: "items[?kind=='Deployment'].status.conditions|[0][?type=='Available'].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"
|
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'"
|
- "heketi_state.stdout|from_json|json_query(deployments_query) == 'True'"
|
||||||
retries: 60
|
retries: 60
|
||||||
delay: 5
|
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]\") }}"
|
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"
|
- name: "Kubernetes Apps | Test Heketi"
|
||||||
register: "heketi_service_state"
|
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
|
changed_when: false
|
||||||
|
|
||||||
- name: "Kubernetes Apps | Bootstrap Heketi"
|
- name: "Kubernetes Apps | Bootstrap Heketi"
|
||||||
|
@ -1,31 +1,44 @@
|
|||||||
---
|
---
|
||||||
- register: "clusterrolebinding_state"
|
- name: Get clusterrolebindings
|
||||||
command: "{{bin_dir}}/kubectl get clusterrolebinding heketi-gluster-admin -o=name --ignore-not-found=true"
|
register: "clusterrolebinding_state"
|
||||||
|
command: "{{ bin_dir }}/kubectl get clusterrolebinding heketi-gluster-admin -o=name --ignore-not-found=true"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: "Kubernetes Apps | Deploy cluster role binding."
|
- name: "Kubernetes Apps | Deploy cluster role binding."
|
||||||
when: "clusterrolebinding_state.stdout == \"\""
|
when: "clusterrolebinding_state.stdout == \"\""
|
||||||
command: "{{bin_dir}}/kubectl create clusterrolebinding heketi-gluster-admin --clusterrole=edit --serviceaccount=default:heketi-service-account"
|
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"
|
- 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
|
changed_when: false
|
||||||
- assert:
|
|
||||||
|
- name: Make sure that clusterrolebindings are present now
|
||||||
|
assert:
|
||||||
that: "clusterrolebinding_state.stdout != \"\""
|
that: "clusterrolebinding_state.stdout != \"\""
|
||||||
msg: "Cluster role binding is not present."
|
msg: "Cluster role binding is not present."
|
||||||
|
|
||||||
- register: "secret_state"
|
- name: Get the heketi-config-secret secret
|
||||||
command: "{{bin_dir}}/kubectl get secret heketi-config-secret -o=name --ignore-not-found=true"
|
register: "secret_state"
|
||||||
|
command: "{{ bin_dir }}/kubectl get secret heketi-config-secret -o=name --ignore-not-found=true"
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: "Render Heketi secret configuration."
|
- name: "Render Heketi secret configuration."
|
||||||
become: true
|
become: true
|
||||||
template:
|
template:
|
||||||
src: "heketi.json.j2"
|
src: "heketi.json.j2"
|
||||||
dest: "{{ kube_config_dir }}/heketi.json"
|
dest: "{{ kube_config_dir }}/heketi.json"
|
||||||
|
|
||||||
- name: "Deploy Heketi config secret"
|
- name: "Deploy Heketi config secret"
|
||||||
when: "secret_state.stdout == \"\""
|
when: "secret_state.stdout == \"\""
|
||||||
command: "{{bin_dir}}/kubectl create secret generic heketi-config-secret --from-file={{ kube_config_dir }}/heketi.json"
|
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"
|
- 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
|
changed_when: false
|
||||||
- assert:
|
|
||||||
|
- name: Make sure the heketi-config-secret secret exists now
|
||||||
|
assert:
|
||||||
that: "secret_state.stdout != \"\""
|
that: "secret_state.stdout != \"\""
|
||||||
msg: "Heketi config secret is not present."
|
msg: "Heketi config secret is not present."
|
||||||
|
@ -7,6 +7,6 @@
|
|||||||
- name: "Kubernetes Apps | Install and configure Heketi Storage"
|
- name: "Kubernetes Apps | Install and configure Heketi Storage"
|
||||||
kube:
|
kube:
|
||||||
name: "GlusterFS"
|
name: "GlusterFS"
|
||||||
kubectl: "{{bin_dir}}/kubectl"
|
kubectl: "{{ bin_dir }}/kubectl"
|
||||||
filename: "{{ kube_config_dir }}/heketi-storage.json"
|
filename: "{{ kube_config_dir }}/heketi-storage.json"
|
||||||
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
||||||
|
@ -20,6 +20,6 @@
|
|||||||
- name: "Kubernetes Apps | Install and configure Storace Class"
|
- name: "Kubernetes Apps | Install and configure Storace Class"
|
||||||
kube:
|
kube:
|
||||||
name: "GlusterFS"
|
name: "GlusterFS"
|
||||||
kubectl: "{{bin_dir}}/kubectl"
|
kubectl: "{{ bin_dir }}/kubectl"
|
||||||
filename: "{{ kube_config_dir }}/storageclass.yml"
|
filename: "{{ kube_config_dir }}/storageclass.yml"
|
||||||
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
state: "{{ rendering.changed | ternary('latest', 'present') }}"
|
||||||
|
@ -10,10 +10,10 @@
|
|||||||
template:
|
template:
|
||||||
src: "topology.json.j2"
|
src: "topology.json.j2"
|
||||||
dest: "{{ kube_config_dir }}/topology.json"
|
dest: "{{ kube_config_dir }}/topology.json"
|
||||||
- name: "Copy topology configuration into container."
|
- name: "Copy topology configuration into container." # noqa 503
|
||||||
when: "rendering.changed"
|
when: "rendering.changed"
|
||||||
command: "{{ bin_dir }}/kubectl cp {{ kube_config_dir }}/topology.json {{ heketi_pod_name }}:/tmp/topology.json"
|
command: "{{ bin_dir }}/kubectl cp {{ kube_config_dir }}/topology.json {{ heketi_pod_name }}:/tmp/topology.json"
|
||||||
- name: "Load heketi topology."
|
- name: "Load heketi topology." # noqa 503
|
||||||
when: "rendering.changed"
|
when: "rendering.changed"
|
||||||
command: "{{ bin_dir }}/kubectl exec {{ heketi_pod_name }} -- heketi-cli --user admin --secret {{ heketi_admin_key }} topology load --json=/tmp/topology.json"
|
command: "{{ bin_dir }}/kubectl exec {{ heketi_pod_name }} -- heketi-cli --user admin --secret {{ heketi_admin_key }} topology load --json=/tmp/topology.json"
|
||||||
- name: "Get heketi topology."
|
- name: "Get heketi topology."
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"kind": "DaemonSet",
|
"kind": "DaemonSet",
|
||||||
"apiVersion": "extensions/v1beta1",
|
"apiVersion": "apps/v1",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "glusterfs",
|
"name": "glusterfs",
|
||||||
"labels": {
|
"labels": {
|
||||||
@ -12,6 +12,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
|
"selector": {
|
||||||
|
"matchLabels": {
|
||||||
|
"glusterfs-node": "daemonset"
|
||||||
|
}
|
||||||
|
},
|
||||||
"template": {
|
"template": {
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "glusterfs",
|
"name": "glusterfs",
|
||||||
@ -69,7 +74,7 @@
|
|||||||
},
|
},
|
||||||
"readinessProbe": {
|
"readinessProbe": {
|
||||||
"timeoutSeconds": 3,
|
"timeoutSeconds": 3,
|
||||||
"initialDelaySeconds": 60,
|
"initialDelaySeconds": 3,
|
||||||
"exec": {
|
"exec": {
|
||||||
"command": [
|
"command": [
|
||||||
"/bin/bash",
|
"/bin/bash",
|
||||||
@ -80,7 +85,7 @@
|
|||||||
},
|
},
|
||||||
"livenessProbe": {
|
"livenessProbe": {
|
||||||
"timeoutSeconds": 3,
|
"timeoutSeconds": 3,
|
||||||
"initialDelaySeconds": 60,
|
"initialDelaySeconds": 10,
|
||||||
"exec": {
|
"exec": {
|
||||||
"command": [
|
"command": [
|
||||||
"/bin/bash",
|
"/bin/bash",
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"kind": "Deployment",
|
"kind": "Deployment",
|
||||||
"apiVersion": "extensions/v1beta1",
|
"apiVersion": "apps/v1",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "deploy-heketi",
|
"name": "deploy-heketi",
|
||||||
"labels": {
|
"labels": {
|
||||||
@ -42,6 +42,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
|
"selector": {
|
||||||
|
"matchLabels": {
|
||||||
|
"name": "deploy-heketi"
|
||||||
|
}
|
||||||
|
},
|
||||||
"replicas": 1,
|
"replicas": 1,
|
||||||
"template": {
|
"template": {
|
||||||
"metadata": {
|
"metadata": {
|
||||||
@ -56,7 +61,7 @@
|
|||||||
"serviceAccountName": "heketi-service-account",
|
"serviceAccountName": "heketi-service-account",
|
||||||
"containers": [
|
"containers": [
|
||||||
{
|
{
|
||||||
"image": "heketi/heketi:7",
|
"image": "heketi/heketi:9",
|
||||||
"imagePullPolicy": "Always",
|
"imagePullPolicy": "Always",
|
||||||
"name": "deploy-heketi",
|
"name": "deploy-heketi",
|
||||||
"env": [
|
"env": [
|
||||||
@ -106,7 +111,7 @@
|
|||||||
},
|
},
|
||||||
"livenessProbe": {
|
"livenessProbe": {
|
||||||
"timeoutSeconds": 3,
|
"timeoutSeconds": 3,
|
||||||
"initialDelaySeconds": 30,
|
"initialDelaySeconds": 10,
|
||||||
"httpGet": {
|
"httpGet": {
|
||||||
"path": "/hello",
|
"path": "/hello",
|
||||||
"port": 8080
|
"port": 8080
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"kind": "Deployment",
|
"kind": "Deployment",
|
||||||
"apiVersion": "extensions/v1beta1",
|
"apiVersion": "apps/v1",
|
||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "heketi",
|
"name": "heketi",
|
||||||
"labels": {
|
"labels": {
|
||||||
@ -55,6 +55,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
|
"selector": {
|
||||||
|
"matchLabels": {
|
||||||
|
"name": "heketi"
|
||||||
|
}
|
||||||
|
},
|
||||||
"replicas": 1,
|
"replicas": 1,
|
||||||
"template": {
|
"template": {
|
||||||
"metadata": {
|
"metadata": {
|
||||||
@ -68,7 +73,7 @@
|
|||||||
"serviceAccountName": "heketi-service-account",
|
"serviceAccountName": "heketi-service-account",
|
||||||
"containers": [
|
"containers": [
|
||||||
{
|
{
|
||||||
"image": "heketi/heketi:7",
|
"image": "heketi/heketi:9",
|
||||||
"imagePullPolicy": "Always",
|
"imagePullPolicy": "Always",
|
||||||
"name": "heketi",
|
"name": "heketi",
|
||||||
"env": [
|
"env": [
|
||||||
@ -122,7 +127,7 @@
|
|||||||
},
|
},
|
||||||
"livenessProbe": {
|
"livenessProbe": {
|
||||||
"timeoutSeconds": 3,
|
"timeoutSeconds": 3,
|
||||||
"initialDelaySeconds": 30,
|
"initialDelaySeconds": 10,
|
||||||
"httpGet": {
|
"httpGet": {
|
||||||
"path": "/hello",
|
"path": "/hello",
|
||||||
"port": 8080
|
"port": 8080
|
||||||
|
@ -16,7 +16,7 @@
|
|||||||
{
|
{
|
||||||
"addresses": [
|
"addresses": [
|
||||||
{
|
{
|
||||||
"ip": "{{ hostvars[node]['ansible_facts']['default_ipv4']['address'] }}"
|
"ip": "{{ hostvars[node].ip }}"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"ports": [
|
"ports": [
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
"{{ node }}"
|
"{{ node }}"
|
||||||
],
|
],
|
||||||
"storage": [
|
"storage": [
|
||||||
"{{ hostvars[node]['ansible_facts']['default_ipv4']['address'] }}"
|
"{{ hostvars[node].ip }}"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"zone": 1
|
"zone": 1
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
---
|
||||||
|
heketi_remove_lvm: false
|
@ -14,19 +14,25 @@
|
|||||||
when: "ansible_os_family == 'Debian'"
|
when: "ansible_os_family == 'Debian'"
|
||||||
|
|
||||||
- name: "Get volume group information."
|
- name: "Get volume group information."
|
||||||
|
environment:
|
||||||
|
PATH: "{{ ansible_env.PATH }}:/sbin" # Make sure we can workaround RH / CentOS conservative path management
|
||||||
become: true
|
become: true
|
||||||
shell: "pvs {{ disk_volume_device_1 }} --option vg_name | tail -n+2"
|
shell: "pvs {{ disk_volume_device_1 }} --option vg_name | tail -n+2"
|
||||||
register: "volume_groups"
|
register: "volume_groups"
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
changed_when: false
|
changed_when: false
|
||||||
|
|
||||||
- name: "Remove volume groups."
|
- name: "Remove volume groups." # noqa 301
|
||||||
|
environment:
|
||||||
|
PATH: "{{ ansible_env.PATH }}:/sbin" # Make sure we can workaround RH / CentOS conservative path management
|
||||||
become: true
|
become: true
|
||||||
command: "vgremove {{ volume_group }} --yes"
|
command: "vgremove {{ volume_group }} --yes"
|
||||||
with_items: "{{ volume_groups.stdout_lines }}"
|
with_items: "{{ volume_groups.stdout_lines }}"
|
||||||
loop_control: { loop_var: "volume_group" }
|
loop_control: { loop_var: "volume_group" }
|
||||||
|
|
||||||
- name: "Remove physical volume from cluster disks."
|
- name: "Remove physical volume from cluster disks." # noqa 301
|
||||||
|
environment:
|
||||||
|
PATH: "{{ ansible_env.PATH }}:/sbin" # Make sure we can workaround RH / CentOS conservative path management
|
||||||
become: true
|
become: true
|
||||||
command: "pvremove {{ disk_volume_device_1 }} --yes"
|
command: "pvremove {{ disk_volume_device_1 }} --yes"
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
@ -36,11 +42,11 @@
|
|||||||
yum:
|
yum:
|
||||||
name: "lvm2"
|
name: "lvm2"
|
||||||
state: "absent"
|
state: "absent"
|
||||||
when: "ansible_os_family == 'RedHat'"
|
when: "ansible_os_family == 'RedHat' and heketi_remove_lvm"
|
||||||
|
|
||||||
- name: "Remove lvm utils (Debian)"
|
- name: "Remove lvm utils (Debian)"
|
||||||
become: true
|
become: true
|
||||||
apt:
|
apt:
|
||||||
name: "lvm2"
|
name: "lvm2"
|
||||||
state: "absent"
|
state: "absent"
|
||||||
when: "ansible_os_family == 'Debian'"
|
when: "ansible_os_family == 'Debian' and heketi_remove_lvm"
|
||||||
|
@ -1,43 +1,43 @@
|
|||||||
---
|
---
|
||||||
- name: "Remove storage class."
|
- name: "Remove storage class." # noqa 301
|
||||||
command: "{{ bin_dir }}/kubectl delete storageclass gluster"
|
command: "{{ bin_dir }}/kubectl delete storageclass gluster"
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
- name: "Tear down heketi."
|
- name: "Tear down heketi." # noqa 301
|
||||||
command: "{{ bin_dir }}/kubectl delete all,service,jobs,deployment,secret --selector=\"glusterfs=heketi-pod\""
|
command: "{{ bin_dir }}/kubectl delete all,service,jobs,deployment,secret --selector=\"glusterfs=heketi-pod\""
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
- name: "Tear down heketi."
|
- name: "Tear down heketi." # noqa 301
|
||||||
command: "{{ bin_dir }}/kubectl delete all,service,jobs,deployment,secret --selector=\"glusterfs=heketi-deployment\""
|
command: "{{ bin_dir }}/kubectl delete all,service,jobs,deployment,secret --selector=\"glusterfs=heketi-deployment\""
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
- name: "Tear down bootstrap."
|
- name: "Tear down bootstrap."
|
||||||
include_tasks: "../provision/tasks/bootstrap/tear-down.yml"
|
include_tasks: "../../provision/tasks/bootstrap/tear-down.yml"
|
||||||
- name: "Ensure there is nothing left over."
|
- name: "Ensure there is nothing left over." # noqa 301
|
||||||
command: "{{ bin_dir }}/kubectl get all,service,jobs,deployment,secret --selector=\"glusterfs=heketi-pod\" -o=json"
|
command: "{{ bin_dir }}/kubectl get all,service,jobs,deployment,secret --selector=\"glusterfs=heketi-pod\" -o=json"
|
||||||
register: "heketi_result"
|
register: "heketi_result"
|
||||||
until: "heketi_result.stdout|from_json|json_query('items[*]')|length == 0"
|
until: "heketi_result.stdout|from_json|json_query('items[*]')|length == 0"
|
||||||
retries: 60
|
retries: 60
|
||||||
delay: 5
|
delay: 5
|
||||||
- name: "Ensure there is nothing left over."
|
- name: "Ensure there is nothing left over." # noqa 301
|
||||||
command: "{{ bin_dir }}/kubectl get all,service,jobs,deployment,secret --selector=\"glusterfs=heketi-deployment\" -o=json"
|
command: "{{ bin_dir }}/kubectl get all,service,jobs,deployment,secret --selector=\"glusterfs=heketi-deployment\" -o=json"
|
||||||
register: "heketi_result"
|
register: "heketi_result"
|
||||||
until: "heketi_result.stdout|from_json|json_query('items[*]')|length == 0"
|
until: "heketi_result.stdout|from_json|json_query('items[*]')|length == 0"
|
||||||
retries: 60
|
retries: 60
|
||||||
delay: 5
|
delay: 5
|
||||||
- name: "Tear down glusterfs."
|
- name: "Tear down glusterfs." # noqa 301
|
||||||
command: "{{ bin_dir }}/kubectl delete daemonset.extensions/glusterfs"
|
command: "{{ bin_dir }}/kubectl delete daemonset.extensions/glusterfs"
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
- name: "Remove heketi storage service."
|
- name: "Remove heketi storage service." # noqa 301
|
||||||
command: "{{ bin_dir }}/kubectl delete service heketi-storage-endpoints"
|
command: "{{ bin_dir }}/kubectl delete service heketi-storage-endpoints"
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
- name: "Remove heketi gluster role binding"
|
- name: "Remove heketi gluster role binding" # noqa 301
|
||||||
command: "{{ bin_dir }}/kubectl delete clusterrolebinding heketi-gluster-admin"
|
command: "{{ bin_dir }}/kubectl delete clusterrolebinding heketi-gluster-admin"
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
- name: "Remove heketi config secret"
|
- name: "Remove heketi config secret" # noqa 301
|
||||||
command: "{{ bin_dir }}/kubectl delete secret heketi-config-secret"
|
command: "{{ bin_dir }}/kubectl delete secret heketi-config-secret"
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
- name: "Remove heketi db backup"
|
- name: "Remove heketi db backup" # noqa 301
|
||||||
command: "{{ bin_dir }}/kubectl delete secret heketi-db-backup"
|
command: "{{ bin_dir }}/kubectl delete secret heketi-db-backup"
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
- name: "Remove heketi service account"
|
- name: "Remove heketi service account" # noqa 301
|
||||||
command: "{{ bin_dir }}/kubectl delete serviceaccount heketi-service-account"
|
command: "{{ bin_dir }}/kubectl delete serviceaccount heketi-service-account"
|
||||||
ignore_errors: true
|
ignore_errors: true
|
||||||
- name: "Get secrets"
|
- name: "Get secrets"
|
||||||
|
@ -10,7 +10,7 @@ This project will create:
|
|||||||
* AWS ELB in the Public Subnet for accessing the Kubernetes API from the internet
|
* AWS ELB in the Public Subnet for accessing the Kubernetes API from the internet
|
||||||
|
|
||||||
**Requirements**
|
**Requirements**
|
||||||
- Terraform 0.8.7 or newer
|
- Terraform 0.12.0 or newer
|
||||||
|
|
||||||
**How to Use:**
|
**How to Use:**
|
||||||
|
|
||||||
@ -22,7 +22,7 @@ export TF_VAR_AWS_SECRET_ACCESS_KEY ="xxx"
|
|||||||
export TF_VAR_AWS_SSH_KEY_NAME="yyy"
|
export TF_VAR_AWS_SSH_KEY_NAME="yyy"
|
||||||
export TF_VAR_AWS_DEFAULT_REGION="zzz"
|
export TF_VAR_AWS_DEFAULT_REGION="zzz"
|
||||||
```
|
```
|
||||||
- Update `contrib/terraform/aws/terraform.tfvars` with your data. By default, the Terraform scripts use CoreOS as base image. If you want to change this behaviour, see note "Using other distrib than CoreOs" below.
|
- Update `contrib/terraform/aws/terraform.tfvars` with your data. By default, the Terraform scripts use Ubuntu 18.04 LTS (Bionic) as base image. If you want to change this behaviour, see note "Using other distrib than Ubuntu" below.
|
||||||
- Create an AWS EC2 SSH Key
|
- Create an AWS EC2 SSH Key
|
||||||
- Run with `terraform apply --var-file="credentials.tfvars"` or `terraform apply` depending if you exported your AWS credentials
|
- Run with `terraform apply --var-file="credentials.tfvars"` or `terraform apply` depending if you exported your AWS credentials
|
||||||
|
|
||||||
@ -41,12 +41,12 @@ ssh -F ./ssh-bastion.conf user@$ip
|
|||||||
|
|
||||||
- Once the infrastructure is created, you can run the kubespray playbooks and supply inventory/hosts with the `-i` flag.
|
- Once the infrastructure is created, you can run the kubespray playbooks and supply inventory/hosts with the `-i` flag.
|
||||||
|
|
||||||
Example (this one assumes you are using CoreOS)
|
Example (this one assumes you are using Ubuntu)
|
||||||
```commandline
|
```commandline
|
||||||
ansible-playbook -i ./inventory/hosts ./cluster.yml -e ansible_user=core -b --become-user=root --flush-cache
|
ansible-playbook -i ./inventory/hosts ./cluster.yml -e ansible_user=ubuntu -b --become-user=root --flush-cache
|
||||||
```
|
```
|
||||||
***Using other distrib than CoreOs***
|
***Using other distrib than Ubuntu***
|
||||||
If you want to use another distribution than CoreOS, you can modify the search filters of the 'data "aws_ami" "distro"' in variables.tf.
|
If you want to use another distribution than Ubuntu 18.04 (Bionic) LTS, you can modify the search filters of the 'data "aws_ami" "distro"' in variables.tf.
|
||||||
|
|
||||||
For example, to use:
|
For example, to use:
|
||||||
- Debian Jessie, replace 'data "aws_ami" "distro"' in variables.tf with
|
- Debian Jessie, replace 'data "aws_ami" "distro"' in variables.tf with
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
terraform {
|
terraform {
|
||||||
required_version = ">= 0.8.7"
|
required_version = ">= 0.12.0"
|
||||||
}
|
}
|
||||||
|
|
||||||
provider "aws" {
|
provider "aws" {
|
||||||
access_key = "${var.AWS_ACCESS_KEY_ID}"
|
access_key = var.AWS_ACCESS_KEY_ID
|
||||||
secret_key = "${var.AWS_SECRET_ACCESS_KEY}"
|
secret_key = var.AWS_SECRET_ACCESS_KEY
|
||||||
region = "${var.AWS_DEFAULT_REGION}"
|
region = var.AWS_DEFAULT_REGION
|
||||||
}
|
}
|
||||||
|
|
||||||
data "aws_availability_zones" "available" {}
|
data "aws_availability_zones" "available" {}
|
||||||
@ -16,32 +16,32 @@ data "aws_availability_zones" "available" {}
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
module "aws-vpc" {
|
module "aws-vpc" {
|
||||||
source = "modules/vpc"
|
source = "./modules/vpc"
|
||||||
|
|
||||||
aws_cluster_name = "${var.aws_cluster_name}"
|
aws_cluster_name = var.aws_cluster_name
|
||||||
aws_vpc_cidr_block = "${var.aws_vpc_cidr_block}"
|
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_private = var.aws_cidr_subnets_private
|
||||||
aws_cidr_subnets_public = "${var.aws_cidr_subnets_public}"
|
aws_cidr_subnets_public = var.aws_cidr_subnets_public
|
||||||
default_tags = "${var.default_tags}"
|
default_tags = var.default_tags
|
||||||
}
|
}
|
||||||
|
|
||||||
module "aws-elb" {
|
module "aws-elb" {
|
||||||
source = "modules/elb"
|
source = "./modules/elb"
|
||||||
|
|
||||||
aws_cluster_name = "${var.aws_cluster_name}"
|
aws_cluster_name = var.aws_cluster_name
|
||||||
aws_vpc_id = "${module.aws-vpc.aws_vpc_id}"
|
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_subnet_ids_public = module.aws-vpc.aws_subnet_ids_public
|
||||||
aws_elb_api_port = "${var.aws_elb_api_port}"
|
aws_elb_api_port = var.aws_elb_api_port
|
||||||
k8s_secure_api_port = "${var.k8s_secure_api_port}"
|
k8s_secure_api_port = var.k8s_secure_api_port
|
||||||
default_tags = "${var.default_tags}"
|
default_tags = var.default_tags
|
||||||
}
|
}
|
||||||
|
|
||||||
module "aws-iam" {
|
module "aws-iam" {
|
||||||
source = "modules/iam"
|
source = "./modules/iam"
|
||||||
|
|
||||||
aws_cluster_name = "${var.aws_cluster_name}"
|
aws_cluster_name = var.aws_cluster_name
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -50,22 +50,22 @@ module "aws-iam" {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
resource "aws_instance" "bastion-server" {
|
resource "aws_instance" "bastion-server" {
|
||||||
ami = "${data.aws_ami.distro.id}"
|
ami = data.aws_ami.distro.id
|
||||||
instance_type = "${var.aws_bastion_size}"
|
instance_type = var.aws_bastion_size
|
||||||
count = "${length(var.aws_cidr_subnets_public)}"
|
count = length(var.aws_cidr_subnets_public)
|
||||||
associate_public_ip_address = true
|
associate_public_ip_address = true
|
||||||
availability_zone = "${element(slice(data.aws_availability_zones.available.names,0,2),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)}"
|
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}"
|
key_name = var.AWS_SSH_KEY_NAME
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-bastion-${count.index}",
|
"Name", "kubernetes-${var.aws_cluster_name}-bastion-${count.index}",
|
||||||
"Cluster", "${var.aws_cluster_name}",
|
"Cluster", "${var.aws_cluster_name}",
|
||||||
"Role", "bastion-${var.aws_cluster_name}-${count.index}"
|
"Role", "bastion-${var.aws_cluster_name}-${count.index}"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -74,71 +74,71 @@ resource "aws_instance" "bastion-server" {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
resource "aws_instance" "k8s-master" {
|
resource "aws_instance" "k8s-master" {
|
||||||
ami = "${data.aws_ami.distro.id}"
|
ami = data.aws_ami.distro.id
|
||||||
instance_type = "${var.aws_kube_master_size}"
|
instance_type = var.aws_kube_master_size
|
||||||
|
|
||||||
count = "${var.aws_kube_master_num}"
|
count = var.aws_kube_master_num
|
||||||
|
|
||||||
availability_zone = "${element(slice(data.aws_availability_zones.available.names,0,2),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)}"
|
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}"
|
iam_instance_profile = module.aws-iam.kube-master-profile
|
||||||
key_name = "${var.AWS_SSH_KEY_NAME}"
|
key_name = var.AWS_SSH_KEY_NAME
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-master${count.index}",
|
"Name", "kubernetes-${var.aws_cluster_name}-master${count.index}",
|
||||||
"kubernetes.io/cluster/${var.aws_cluster_name}", "member",
|
"kubernetes.io/cluster/${var.aws_cluster_name}", "member",
|
||||||
"Role", "master"
|
"Role", "master"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_elb_attachment" "attach_master_nodes" {
|
resource "aws_elb_attachment" "attach_master_nodes" {
|
||||||
count = "${var.aws_kube_master_num}"
|
count = var.aws_kube_master_num
|
||||||
elb = "${module.aws-elb.aws_elb_api_id}"
|
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" {
|
resource "aws_instance" "k8s-etcd" {
|
||||||
ami = "${data.aws_ami.distro.id}"
|
ami = data.aws_ami.distro.id
|
||||||
instance_type = "${var.aws_etcd_size}"
|
instance_type = var.aws_etcd_size
|
||||||
|
|
||||||
count = "${var.aws_etcd_num}"
|
count = var.aws_etcd_num
|
||||||
|
|
||||||
availability_zone = "${element(slice(data.aws_availability_zones.available.names,0,2),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)}"
|
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}"
|
key_name = var.AWS_SSH_KEY_NAME
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-etcd${count.index}",
|
"Name", "kubernetes-${var.aws_cluster_name}-etcd${count.index}",
|
||||||
"kubernetes.io/cluster/${var.aws_cluster_name}", "member",
|
"kubernetes.io/cluster/${var.aws_cluster_name}", "member",
|
||||||
"Role", "etcd"
|
"Role", "etcd"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_instance" "k8s-worker" {
|
resource "aws_instance" "k8s-worker" {
|
||||||
ami = "${data.aws_ami.distro.id}"
|
ami = data.aws_ami.distro.id
|
||||||
instance_type = "${var.aws_kube_worker_size}"
|
instance_type = var.aws_kube_worker_size
|
||||||
|
|
||||||
count = "${var.aws_kube_worker_num}"
|
count = var.aws_kube_worker_num
|
||||||
|
|
||||||
availability_zone = "${element(slice(data.aws_availability_zones.available.names,0,2),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)}"
|
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}"
|
iam_instance_profile = module.aws-iam.kube-worker-profile
|
||||||
key_name = "${var.AWS_SSH_KEY_NAME}"
|
key_name = var.AWS_SSH_KEY_NAME
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-worker${count.index}",
|
"Name", "kubernetes-${var.aws_cluster_name}-worker${count.index}",
|
||||||
"kubernetes.io/cluster/${var.aws_cluster_name}", "member",
|
"kubernetes.io/cluster/${var.aws_cluster_name}", "member",
|
||||||
"Role", "worker"
|
"Role", "worker"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -146,16 +146,16 @@ resource "aws_instance" "k8s-worker" {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
data "template_file" "inventory" {
|
data "template_file" "inventory" {
|
||||||
template = "${file("${path.module}/templates/inventory.tpl")}"
|
template = file("${path.module}/templates/inventory.tpl")
|
||||||
|
|
||||||
vars {
|
vars = {
|
||||||
public_ip_address_bastion = "${join("\n",formatlist("bastion ansible_host=%s" , aws_instance.bastion-server.*.public_ip))}"
|
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_master = join("\n", formatlist("%s ansible_host=%s", aws_instance.k8s-master.*.private_dns, 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_node = join("\n", formatlist("%s ansible_host=%s", aws_instance.k8s-worker.*.private_dns, 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))}"
|
connection_strings_etcd = join("\n", formatlist("%s ansible_host=%s", aws_instance.k8s-etcd.*.private_dns, aws_instance.k8s-etcd.*.private_ip))
|
||||||
list_master = "${join("\n",aws_instance.k8s-master.*.tags.Name)}"
|
list_master = join("\n", aws_instance.k8s-master.*.private_dns)
|
||||||
list_node = "${join("\n",aws_instance.k8s-worker.*.tags.Name)}"
|
list_node = join("\n", aws_instance.k8s-worker.*.private_dns)
|
||||||
list_etcd = "${join("\n",aws_instance.k8s-etcd.*.tags.Name)}"
|
list_etcd = join("\n", aws_instance.k8s-etcd.*.private_dns)
|
||||||
elb_api_fqdn = "apiserver_loadbalancer_domain_name=\"${module.aws-elb.aws_elb_api_fqdn}\""
|
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}"
|
command = "echo '${data.template_file.inventory.rendered}' > ${var.inventory_file}"
|
||||||
}
|
}
|
||||||
|
|
||||||
triggers {
|
triggers = {
|
||||||
template = "${data.template_file.inventory.rendered}"
|
template = data.template_file.inventory.rendered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
resource "aws_security_group" "aws-elb" {
|
resource "aws_security_group" "aws-elb" {
|
||||||
name = "kubernetes-${var.aws_cluster_name}-securitygroup-elb"
|
name = "kubernetes-${var.aws_cluster_name}-securitygroup-elb"
|
||||||
vpc_id = "${var.aws_vpc_id}"
|
vpc_id = var.aws_vpc_id
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-securitygroup-elb"
|
"Name", "kubernetes-${var.aws_cluster_name}-securitygroup-elb"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_security_group_rule" "aws-allow-api-access" {
|
resource "aws_security_group_rule" "aws-allow-api-access" {
|
||||||
type = "ingress"
|
type = "ingress"
|
||||||
from_port = "${var.aws_elb_api_port}"
|
from_port = var.aws_elb_api_port
|
||||||
to_port = "${var.k8s_secure_api_port}"
|
to_port = var.k8s_secure_api_port
|
||||||
protocol = "TCP"
|
protocol = "TCP"
|
||||||
cidr_blocks = ["0.0.0.0/0"]
|
cidr_blocks = ["0.0.0.0/0"]
|
||||||
security_group_id = "${aws_security_group.aws-elb.id}"
|
security_group_id = aws_security_group.aws-elb.id
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_security_group_rule" "aws-allow-api-egress" {
|
resource "aws_security_group_rule" "aws-allow-api-egress" {
|
||||||
@ -22,19 +22,19 @@ resource "aws_security_group_rule" "aws-allow-api-egress" {
|
|||||||
to_port = 65535
|
to_port = 65535
|
||||||
protocol = "TCP"
|
protocol = "TCP"
|
||||||
cidr_blocks = ["0.0.0.0/0"]
|
cidr_blocks = ["0.0.0.0/0"]
|
||||||
security_group_id = "${aws_security_group.aws-elb.id}"
|
security_group_id = aws_security_group.aws-elb.id
|
||||||
}
|
}
|
||||||
|
|
||||||
# Create a new AWS ELB for K8S API
|
# Create a new AWS ELB for K8S API
|
||||||
resource "aws_elb" "aws-elb-api" {
|
resource "aws_elb" "aws-elb-api" {
|
||||||
name = "kubernetes-elb-${var.aws_cluster_name}"
|
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}"]
|
security_groups = [aws_security_group.aws-elb.id]
|
||||||
|
|
||||||
listener {
|
listener {
|
||||||
instance_port = "${var.k8s_secure_api_port}"
|
instance_port = var.k8s_secure_api_port
|
||||||
instance_protocol = "tcp"
|
instance_protocol = "tcp"
|
||||||
lb_port = "${var.aws_elb_api_port}"
|
lb_port = var.aws_elb_api_port
|
||||||
lb_protocol = "tcp"
|
lb_protocol = "tcp"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ resource "aws_elb" "aws-elb-api" {
|
|||||||
connection_draining = true
|
connection_draining = true
|
||||||
connection_draining_timeout = 400
|
connection_draining_timeout = 400
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-elb-api"
|
"Name", "kubernetes-${var.aws_cluster_name}-elb-api"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
output "aws_elb_api_id" {
|
output "aws_elb_api_id" {
|
||||||
value = "${aws_elb.aws-elb-api.id}"
|
value = aws_elb.aws-elb-api.id
|
||||||
}
|
}
|
||||||
|
|
||||||
output "aws_elb_api_fqdn" {
|
output "aws_elb_api_fqdn" {
|
||||||
value = "${aws_elb.aws-elb-api.dns_name}"
|
value = aws_elb.aws-elb-api.dns_name
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ EOF
|
|||||||
|
|
||||||
resource "aws_iam_role_policy" "kube-master" {
|
resource "aws_iam_role_policy" "kube-master" {
|
||||||
name = "kubernetes-${var.aws_cluster_name}-master"
|
name = "kubernetes-${var.aws_cluster_name}-master"
|
||||||
role = "${aws_iam_role.kube-master.id}"
|
role = aws_iam_role.kube-master.id
|
||||||
|
|
||||||
policy = <<EOF
|
policy = <<EOF
|
||||||
{
|
{
|
||||||
@ -77,7 +77,7 @@ EOF
|
|||||||
|
|
||||||
resource "aws_iam_role_policy" "kube-worker" {
|
resource "aws_iam_role_policy" "kube-worker" {
|
||||||
name = "kubernetes-${var.aws_cluster_name}-node"
|
name = "kubernetes-${var.aws_cluster_name}-node"
|
||||||
role = "${aws_iam_role.kube-worker.id}"
|
role = aws_iam_role.kube-worker.id
|
||||||
|
|
||||||
policy = <<EOF
|
policy = <<EOF
|
||||||
{
|
{
|
||||||
@ -132,10 +132,10 @@ EOF
|
|||||||
|
|
||||||
resource "aws_iam_instance_profile" "kube-master" {
|
resource "aws_iam_instance_profile" "kube-master" {
|
||||||
name = "kube_${var.aws_cluster_name}_master_profile"
|
name = "kube_${var.aws_cluster_name}_master_profile"
|
||||||
role = "${aws_iam_role.kube-master.name}"
|
role = aws_iam_role.kube-master.name
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_iam_instance_profile" "kube-worker" {
|
resource "aws_iam_instance_profile" "kube-worker" {
|
||||||
name = "kube_${var.aws_cluster_name}_node_profile"
|
name = "kube_${var.aws_cluster_name}_node_profile"
|
||||||
role = "${aws_iam_role.kube-worker.name}"
|
role = aws_iam_role.kube-worker.name
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
output "kube-master-profile" {
|
output "kube-master-profile" {
|
||||||
value = "${aws_iam_instance_profile.kube-master.name }"
|
value = aws_iam_instance_profile.kube-master.name
|
||||||
}
|
}
|
||||||
|
|
||||||
output "kube-worker-profile" {
|
output "kube-worker-profile" {
|
||||||
value = "${aws_iam_instance_profile.kube-worker.name }"
|
value = aws_iam_instance_profile.kube-worker.name
|
||||||
}
|
}
|
||||||
|
@ -1,55 +1,55 @@
|
|||||||
resource "aws_vpc" "cluster-vpc" {
|
resource "aws_vpc" "cluster-vpc" {
|
||||||
cidr_block = "${var.aws_vpc_cidr_block}"
|
cidr_block = var.aws_vpc_cidr_block
|
||||||
|
|
||||||
#DNS Related Entries
|
#DNS Related Entries
|
||||||
enable_dns_support = true
|
enable_dns_support = true
|
||||||
enable_dns_hostnames = true
|
enable_dns_hostnames = true
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-vpc"
|
"Name", "kubernetes-${var.aws_cluster_name}-vpc"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_eip" "cluster-nat-eip" {
|
resource "aws_eip" "cluster-nat-eip" {
|
||||||
count = "${length(var.aws_cidr_subnets_public)}"
|
count = length(var.aws_cidr_subnets_public)
|
||||||
vpc = true
|
vpc = true
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_internet_gateway" "cluster-vpc-internetgw" {
|
resource "aws_internet_gateway" "cluster-vpc-internetgw" {
|
||||||
vpc_id = "${aws_vpc.cluster-vpc.id}"
|
vpc_id = aws_vpc.cluster-vpc.id
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-internetgw"
|
"Name", "kubernetes-${var.aws_cluster_name}-internetgw"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_subnet" "cluster-vpc-subnets-public" {
|
resource "aws_subnet" "cluster-vpc-subnets-public" {
|
||||||
vpc_id = "${aws_vpc.cluster-vpc.id}"
|
vpc_id = aws_vpc.cluster-vpc.id
|
||||||
count = "${length(var.aws_avail_zones)}"
|
count = length(var.aws_avail_zones)
|
||||||
availability_zone = "${element(var.aws_avail_zones, count.index)}"
|
availability_zone = element(var.aws_avail_zones, count.index)
|
||||||
cidr_block = "${element(var.aws_cidr_subnets_public, count.index)}"
|
cidr_block = element(var.aws_cidr_subnets_public, count.index)
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-${element(var.aws_avail_zones, count.index)}-public",
|
"Name", "kubernetes-${var.aws_cluster_name}-${element(var.aws_avail_zones, count.index)}-public",
|
||||||
"kubernetes.io/cluster/${var.aws_cluster_name}", "member"
|
"kubernetes.io/cluster/${var.aws_cluster_name}", "member"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_nat_gateway" "cluster-nat-gateway" {
|
resource "aws_nat_gateway" "cluster-nat-gateway" {
|
||||||
count = "${length(var.aws_cidr_subnets_public)}"
|
count = length(var.aws_cidr_subnets_public)
|
||||||
allocation_id = "${element(aws_eip.cluster-nat-eip.*.id, count.index)}"
|
allocation_id = element(aws_eip.cluster-nat-eip.*.id, count.index)
|
||||||
subnet_id = "${element(aws_subnet.cluster-vpc-subnets-public.*.id, count.index)}"
|
subnet_id = element(aws_subnet.cluster-vpc-subnets-public.*.id, count.index)
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_subnet" "cluster-vpc-subnets-private" {
|
resource "aws_subnet" "cluster-vpc-subnets-private" {
|
||||||
vpc_id = "${aws_vpc.cluster-vpc.id}"
|
vpc_id = aws_vpc.cluster-vpc.id
|
||||||
count = "${length(var.aws_avail_zones)}"
|
count = length(var.aws_avail_zones)
|
||||||
availability_zone = "${element(var.aws_avail_zones, count.index)}"
|
availability_zone = element(var.aws_avail_zones, count.index)
|
||||||
cidr_block = "${element(var.aws_cidr_subnets_private, count.index)}"
|
cidr_block = element(var.aws_cidr_subnets_private, count.index)
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-${element(var.aws_avail_zones, count.index)}-private"
|
"Name", "kubernetes-${var.aws_cluster_name}-${element(var.aws_avail_zones, count.index)}-private"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#Routing in VPC
|
#Routing in VPC
|
||||||
@ -57,53 +57,53 @@ resource "aws_subnet" "cluster-vpc-subnets-private" {
|
|||||||
#TODO: Do we need two routing tables for each subnet for redundancy or is one enough?
|
#TODO: Do we need two routing tables for each subnet for redundancy or is one enough?
|
||||||
|
|
||||||
resource "aws_route_table" "kubernetes-public" {
|
resource "aws_route_table" "kubernetes-public" {
|
||||||
vpc_id = "${aws_vpc.cluster-vpc.id}"
|
vpc_id = aws_vpc.cluster-vpc.id
|
||||||
|
|
||||||
route {
|
route {
|
||||||
cidr_block = "0.0.0.0/0"
|
cidr_block = "0.0.0.0/0"
|
||||||
gateway_id = "${aws_internet_gateway.cluster-vpc-internetgw.id}"
|
gateway_id = aws_internet_gateway.cluster-vpc-internetgw.id
|
||||||
}
|
}
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-routetable-public"
|
"Name", "kubernetes-${var.aws_cluster_name}-routetable-public"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_route_table" "kubernetes-private" {
|
resource "aws_route_table" "kubernetes-private" {
|
||||||
count = "${length(var.aws_cidr_subnets_private)}"
|
count = length(var.aws_cidr_subnets_private)
|
||||||
vpc_id = "${aws_vpc.cluster-vpc.id}"
|
vpc_id = aws_vpc.cluster-vpc.id
|
||||||
|
|
||||||
route {
|
route {
|
||||||
cidr_block = "0.0.0.0/0"
|
cidr_block = "0.0.0.0/0"
|
||||||
nat_gateway_id = "${element(aws_nat_gateway.cluster-nat-gateway.*.id, count.index)}"
|
nat_gateway_id = element(aws_nat_gateway.cluster-nat-gateway.*.id, count.index)
|
||||||
}
|
}
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-routetable-private-${count.index}"
|
"Name", "kubernetes-${var.aws_cluster_name}-routetable-private-${count.index}"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_route_table_association" "kubernetes-public" {
|
resource "aws_route_table_association" "kubernetes-public" {
|
||||||
count = "${length(var.aws_cidr_subnets_public)}"
|
count = length(var.aws_cidr_subnets_public)
|
||||||
subnet_id = "${element(aws_subnet.cluster-vpc-subnets-public.*.id,count.index)}"
|
subnet_id = element(aws_subnet.cluster-vpc-subnets-public.*.id, count.index)
|
||||||
route_table_id = "${aws_route_table.kubernetes-public.id}"
|
route_table_id = aws_route_table.kubernetes-public.id
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_route_table_association" "kubernetes-private" {
|
resource "aws_route_table_association" "kubernetes-private" {
|
||||||
count = "${length(var.aws_cidr_subnets_private)}"
|
count = length(var.aws_cidr_subnets_private)
|
||||||
subnet_id = "${element(aws_subnet.cluster-vpc-subnets-private.*.id,count.index)}"
|
subnet_id = element(aws_subnet.cluster-vpc-subnets-private.*.id, count.index)
|
||||||
route_table_id = "${element(aws_route_table.kubernetes-private.*.id,count.index)}"
|
route_table_id = element(aws_route_table.kubernetes-private.*.id, count.index)
|
||||||
}
|
}
|
||||||
|
|
||||||
#Kubernetes Security Groups
|
#Kubernetes Security Groups
|
||||||
|
|
||||||
resource "aws_security_group" "kubernetes" {
|
resource "aws_security_group" "kubernetes" {
|
||||||
name = "kubernetes-${var.aws_cluster_name}-securitygroup"
|
name = "kubernetes-${var.aws_cluster_name}-securitygroup"
|
||||||
vpc_id = "${aws_vpc.cluster-vpc.id}"
|
vpc_id = aws_vpc.cluster-vpc.id
|
||||||
|
|
||||||
tags = "${merge(var.default_tags, map(
|
tags = merge(var.default_tags, map(
|
||||||
"Name", "kubernetes-${var.aws_cluster_name}-securitygroup"
|
"Name", "kubernetes-${var.aws_cluster_name}-securitygroup"
|
||||||
))}"
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_security_group_rule" "allow-all-ingress" {
|
resource "aws_security_group_rule" "allow-all-ingress" {
|
||||||
@ -111,8 +111,8 @@ resource "aws_security_group_rule" "allow-all-ingress" {
|
|||||||
from_port = 0
|
from_port = 0
|
||||||
to_port = 65535
|
to_port = 65535
|
||||||
protocol = "-1"
|
protocol = "-1"
|
||||||
cidr_blocks = ["${var.aws_vpc_cidr_block}"]
|
cidr_blocks = [var.aws_vpc_cidr_block]
|
||||||
security_group_id = "${aws_security_group.kubernetes.id}"
|
security_group_id = aws_security_group.kubernetes.id
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_security_group_rule" "allow-all-egress" {
|
resource "aws_security_group_rule" "allow-all-egress" {
|
||||||
@ -121,7 +121,7 @@ resource "aws_security_group_rule" "allow-all-egress" {
|
|||||||
to_port = 65535
|
to_port = 65535
|
||||||
protocol = "-1"
|
protocol = "-1"
|
||||||
cidr_blocks = ["0.0.0.0/0"]
|
cidr_blocks = ["0.0.0.0/0"]
|
||||||
security_group_id = "${aws_security_group.kubernetes.id}"
|
security_group_id = aws_security_group.kubernetes.id
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "aws_security_group_rule" "allow-ssh-connections" {
|
resource "aws_security_group_rule" "allow-ssh-connections" {
|
||||||
@ -130,5 +130,5 @@ resource "aws_security_group_rule" "allow-ssh-connections" {
|
|||||||
to_port = 22
|
to_port = 22
|
||||||
protocol = "TCP"
|
protocol = "TCP"
|
||||||
cidr_blocks = ["0.0.0.0/0"]
|
cidr_blocks = ["0.0.0.0/0"]
|
||||||
security_group_id = "${aws_security_group.kubernetes.id}"
|
security_group_id = aws_security_group.kubernetes.id
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
output "aws_vpc_id" {
|
output "aws_vpc_id" {
|
||||||
value = "${aws_vpc.cluster-vpc.id}"
|
value = aws_vpc.cluster-vpc.id
|
||||||
}
|
}
|
||||||
|
|
||||||
output "aws_subnet_ids_private" {
|
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" {
|
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" {
|
output "aws_security_group" {
|
||||||
value = ["${aws_security_group.kubernetes.*.id}"]
|
value = aws_security_group.kubernetes.*.id
|
||||||
}
|
}
|
||||||
|
|
||||||
output "default_tags" {
|
output "default_tags" {
|
||||||
value = "${var.default_tags}"
|
value = var.default_tags
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
output "bastion_ip" {
|
output "bastion_ip" {
|
||||||
value = "${join("\n", aws_instance.bastion-server.*.public_ip)}"
|
value = join("\n", aws_instance.bastion-server.*.public_ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
output "masters" {
|
output "masters" {
|
||||||
value = "${join("\n", aws_instance.k8s-master.*.private_ip)}"
|
value = join("\n", aws_instance.k8s-master.*.private_ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
output "workers" {
|
output "workers" {
|
||||||
value = "${join("\n", aws_instance.k8s-worker.*.private_ip)}"
|
value = join("\n", aws_instance.k8s-worker.*.private_ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
output "etcd" {
|
output "etcd" {
|
||||||
value = "${join("\n", aws_instance.k8s-etcd.*.private_ip)}"
|
value = join("\n", aws_instance.k8s-etcd.*.private_ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
output "aws_elb_api_fqdn" {
|
output "aws_elb_api_fqdn" {
|
||||||
@ -19,9 +19,9 @@ output "aws_elb_api_fqdn" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
output "inventory" {
|
output "inventory" {
|
||||||
value = "${data.template_file.inventory.rendered}"
|
value = data.template_file.inventory.rendered
|
||||||
}
|
}
|
||||||
|
|
||||||
output "default_tags" {
|
output "default_tags" {
|
||||||
value = "${var.default_tags}"
|
value = var.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"
|
aws_cluster_name = "devtest"
|
||||||
|
|
||||||
#VPC Vars
|
#VPC Vars
|
||||||
aws_vpc_cidr_block = "10.250.192.0/18"
|
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_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_cidr_subnets_public = ["10.250.224.0/20", "10.250.240.0/20"]
|
||||||
|
|
||||||
#Bastion Host
|
#Bastion Host
|
||||||
aws_bastion_size = "t2.medium"
|
aws_bastion_size = "t2.medium"
|
||||||
@ -12,24 +12,24 @@ aws_bastion_size = "t2.medium"
|
|||||||
|
|
||||||
#Kubernetes Cluster
|
#Kubernetes Cluster
|
||||||
|
|
||||||
aws_kube_master_num = 3
|
aws_kube_master_num = 3
|
||||||
aws_kube_master_size = "t2.medium"
|
aws_kube_master_size = "t2.medium"
|
||||||
|
|
||||||
aws_etcd_num = 3
|
aws_etcd_num = 3
|
||||||
aws_etcd_size = "t2.medium"
|
aws_etcd_size = "t2.medium"
|
||||||
|
|
||||||
aws_kube_worker_num = 4
|
aws_kube_worker_num = 4
|
||||||
aws_kube_worker_size = "t2.medium"
|
aws_kube_worker_size = "t2.medium"
|
||||||
|
|
||||||
#Settings AWS ELB
|
#Settings AWS ELB
|
||||||
|
|
||||||
aws_elb_api_port = 6443
|
aws_elb_api_port = 6443
|
||||||
k8s_secure_api_port = 6443
|
k8s_secure_api_port = 6443
|
||||||
kube_insecure_apiserver_address = "0.0.0.0"
|
kube_insecure_apiserver_address = "0.0.0.0"
|
||||||
|
|
||||||
default_tags = {
|
default_tags = {
|
||||||
# Env = "devtest"
|
# Env = "devtest"
|
||||||
# Product = "kubernetes"
|
# Product = "kubernetes"
|
||||||
}
|
}
|
||||||
|
|
||||||
inventory_file = "../../../inventory/hosts"
|
inventory_file = "../../../inventory/hosts"
|
||||||
|
@ -25,7 +25,7 @@ data "aws_ami" "distro" {
|
|||||||
|
|
||||||
filter {
|
filter {
|
||||||
name = "name"
|
name = "name"
|
||||||
values = ["CoreOS-stable-*"]
|
values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
|
||||||
}
|
}
|
||||||
|
|
||||||
filter {
|
filter {
|
||||||
@ -33,7 +33,7 @@ data "aws_ami" "distro" {
|
|||||||
values = ["hvm"]
|
values = ["hvm"]
|
||||||
}
|
}
|
||||||
|
|
||||||
owners = ["595879546273"] #CoreOS
|
owners = ["099720109477"] # Canonical
|
||||||
}
|
}
|
||||||
|
|
||||||
//AWS VPC Variables
|
//AWS VPC Variables
|
||||||
|
1
contrib/terraform/openstack/.gitignore
vendored
1
contrib/terraform/openstack/.gitignore
vendored
@ -1,4 +1,5 @@
|
|||||||
.terraform
|
.terraform
|
||||||
*.tfvars
|
*.tfvars
|
||||||
|
!sample-inventory\/cluster.tfvars
|
||||||
*.tfstate
|
*.tfstate
|
||||||
*.tfstate.backup
|
*.tfstate.backup
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
# Kubernetes on Openstack with Terraform
|
# Kubernetes on OpenStack with Terraform
|
||||||
|
|
||||||
Provision a Kubernetes cluster with [Terraform](https://www.terraform.io) on
|
Provision a Kubernetes cluster with [Terraform](https://www.terraform.io) on
|
||||||
Openstack.
|
OpenStack.
|
||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
This will install a Kubernetes cluster on an Openstack Cloud. It should work on
|
This will install a Kubernetes cluster on an OpenStack Cloud. It should work on
|
||||||
most modern installs of OpenStack that support the basic services.
|
most modern installs of OpenStack that support the basic services.
|
||||||
|
|
||||||
### Known compatible public clouds
|
### Known compatible public clouds
|
||||||
@ -16,14 +16,13 @@ most modern installs of OpenStack that support the basic services.
|
|||||||
- [ELASTX](https://elastx.se/)
|
- [ELASTX](https://elastx.se/)
|
||||||
- [EnterCloudSuite](https://www.entercloudsuite.com/)
|
- [EnterCloudSuite](https://www.entercloudsuite.com/)
|
||||||
- [FugaCloud](https://fuga.cloud/)
|
- [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/)
|
- [OVH](https://www.ovh.com/)
|
||||||
- [Rackspace](https://www.rackspace.com/)
|
- [Rackspace](https://www.rackspace.com/)
|
||||||
- [Ultimum](https://ultimum.io/)
|
- [Ultimum](https://ultimum.io/)
|
||||||
- [VexxHost](https://vexxhost.com/)
|
- [VexxHost](https://vexxhost.com/)
|
||||||
- [Zetta](https://www.zetta.io/)
|
- [Zetta](https://www.zetta.io/)
|
||||||
|
|
||||||
### Known incompatible public clouds
|
|
||||||
- T-Systems / Open Telekom Cloud: requires `wait_until_associated`
|
|
||||||
|
|
||||||
## Approach
|
## Approach
|
||||||
The terraform configuration inspects variables found in
|
The terraform configuration inspects variables found in
|
||||||
@ -39,6 +38,16 @@ hosts where that makes sense. You have the option of creating bastion hosts
|
|||||||
inside the private subnet to access the nodes there. Alternatively, a node with
|
inside the private subnet to access the nodes there. Alternatively, a node with
|
||||||
a floating IP can be used as a jump host to nodes without.
|
a floating IP can be used as a jump host to nodes without.
|
||||||
|
|
||||||
|
#### Using an existing router
|
||||||
|
It is possible to use an existing router instead of creating one. To use an
|
||||||
|
existing router set the router\_id variable to the uuid of the router you wish
|
||||||
|
to use.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
```
|
||||||
|
router_id = "00c542e7-6f46-4535-ae95-984c7f0391a3"
|
||||||
|
```
|
||||||
|
|
||||||
### Kubernetes Nodes
|
### Kubernetes Nodes
|
||||||
You can create many different kubernetes topologies by setting the number of
|
You can create many different kubernetes topologies by setting the number of
|
||||||
different classes of hosts. For each class there are options for allocating
|
different classes of hosts. For each class there are options for allocating
|
||||||
@ -63,14 +72,14 @@ specify:
|
|||||||
- Size of the non-ephemeral volumes to be attached to store the GlusterFS bricks
|
- Size of the non-ephemeral volumes to be attached to store the GlusterFS bricks
|
||||||
- Other properties related to provisioning the hosts
|
- Other properties related to provisioning the hosts
|
||||||
|
|
||||||
Even if you are using Container Linux by CoreOS for your cluster, you will still
|
Even if you are using Flatcar Container Linux by Kinvolk for your cluster, you will still
|
||||||
need the GlusterFS VMs to be based on either Debian or RedHat based images.
|
need the GlusterFS VMs to be based on either Debian or RedHat based images.
|
||||||
Container Linux by CoreOS cannot serve GlusterFS, but can connect to it through
|
Flatcar Container Linux by Kinvolk cannot serve GlusterFS, but can connect to it through
|
||||||
binaries available on hyperkube v1.4.3_coreos.0 or higher.
|
binaries available on hyperkube v1.4.3_coreos.0 or higher.
|
||||||
|
|
||||||
## Requirements
|
## 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)
|
- [Install Ansible](http://docs.ansible.com/ansible/latest/intro_installation.html)
|
||||||
- you already have a suitable OS image in Glance
|
- you already have a suitable OS image in Glance
|
||||||
- you already have a floating IP pool created
|
- you already have a floating IP pool created
|
||||||
@ -220,12 +229,14 @@ set OS_PROJECT_DOMAIN_NAME=Default
|
|||||||
The construction of the cluster is driven by values found in
|
The construction of the cluster is driven by values found in
|
||||||
[variables.tf](variables.tf).
|
[variables.tf](variables.tf).
|
||||||
|
|
||||||
For your cluster, edit `inventory/$CLUSTER/cluster.tf`.
|
For your cluster, edit `inventory/$CLUSTER/cluster.tfvars`.
|
||||||
|
|
||||||
|Variable | Description |
|
|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`. |
|
|`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_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. |
|
|`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 |
|
|`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 |
|
|`external_net` | UUID of the external network that will be routed to |
|
||||||
@ -243,7 +254,117 @@ 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_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. |
|
|`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 |
|
|`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 |
|
|`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 |
|
||||||
|
|`k8s_nodes` | Map containing worker node definition, see explanation below |
|
||||||
|
|
||||||
|
##### k8s_nodes
|
||||||
|
Allows a custom defintion of worker nodes giving the operator full control over individual node flavor and
|
||||||
|
availability zone placement. To enable the use of this mode set the `number_of_k8s_nodes` and
|
||||||
|
`number_of_k8s_nodes_no_floating_ip` variables to 0. Then define your desired worker node configuration
|
||||||
|
using the `k8s_nodes` variable.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
```
|
||||||
|
k8s_nodes = {
|
||||||
|
"1" = {
|
||||||
|
"az" = "sto1"
|
||||||
|
"flavor" = "83d8b44a-26a0-4f02-a981-079446926445"
|
||||||
|
"floating_ip" = true
|
||||||
|
},
|
||||||
|
"2" = {
|
||||||
|
"az" = "sto2"
|
||||||
|
"flavor" = "83d8b44a-26a0-4f02-a981-079446926445"
|
||||||
|
"floating_ip" = true
|
||||||
|
},
|
||||||
|
"3" = {
|
||||||
|
"az" = "sto3"
|
||||||
|
"flavor" = "83d8b44a-26a0-4f02-a981-079446926445"
|
||||||
|
"floating_ip" = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Would result in the same configuration as:
|
||||||
|
```
|
||||||
|
number_of_k8s_nodes = 3
|
||||||
|
flavor_k8s_node = "83d8b44a-26a0-4f02-a981-079446926445"
|
||||||
|
az_list = ["sto1", "sto2", "sto3"]
|
||||||
|
```
|
||||||
|
|
||||||
|
And:
|
||||||
|
```
|
||||||
|
k8s_nodes = {
|
||||||
|
"ing-1" = {
|
||||||
|
"az" = "sto1"
|
||||||
|
"flavor" = "83d8b44a-26a0-4f02-a981-079446926445"
|
||||||
|
"floating_ip" = true
|
||||||
|
},
|
||||||
|
"ing-2" = {
|
||||||
|
"az" = "sto2"
|
||||||
|
"flavor" = "83d8b44a-26a0-4f02-a981-079446926445"
|
||||||
|
"floating_ip" = true
|
||||||
|
},
|
||||||
|
"ing-3" = {
|
||||||
|
"az" = "sto3"
|
||||||
|
"flavor" = "83d8b44a-26a0-4f02-a981-079446926445"
|
||||||
|
"floating_ip" = true
|
||||||
|
},
|
||||||
|
"big-1" = {
|
||||||
|
"az" = "sto1"
|
||||||
|
"flavor" = "3f73fc93-ec61-4808-88df-2580d94c1a9b"
|
||||||
|
"floating_ip" = false
|
||||||
|
},
|
||||||
|
"big-2" = {
|
||||||
|
"az" = "sto2"
|
||||||
|
"flavor" = "3f73fc93-ec61-4808-88df-2580d94c1a9b"
|
||||||
|
"floating_ip" = false
|
||||||
|
},
|
||||||
|
"big-3" = {
|
||||||
|
"az" = "sto3"
|
||||||
|
"flavor" = "3f73fc93-ec61-4808-88df-2580d94c1a9b"
|
||||||
|
"floating_ip" = false
|
||||||
|
},
|
||||||
|
"small-1" = {
|
||||||
|
"az" = "sto1"
|
||||||
|
"flavor" = "7a6a998f-ac7f-4fb8-a534-2175b254f75e"
|
||||||
|
"floating_ip" = false
|
||||||
|
},
|
||||||
|
"small-2" = {
|
||||||
|
"az" = "sto2"
|
||||||
|
"flavor" = "7a6a998f-ac7f-4fb8-a534-2175b254f75e"
|
||||||
|
"floating_ip" = false
|
||||||
|
},
|
||||||
|
"small-3" = {
|
||||||
|
"az" = "sto3"
|
||||||
|
"flavor" = "7a6a998f-ac7f-4fb8-a534-2175b254f75e"
|
||||||
|
"floating_ip" = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Would result in three nodes in each availability zone each with their own separate naming,
|
||||||
|
flavor and floating ip configuration.
|
||||||
|
|
||||||
|
The "schema":
|
||||||
|
```
|
||||||
|
k8s_nodes = {
|
||||||
|
"key | node name suffix, must be unique" = {
|
||||||
|
"az" = string
|
||||||
|
"flavor" = string
|
||||||
|
"floating_ip" = bool
|
||||||
|
},
|
||||||
|
}
|
||||||
|
```
|
||||||
|
All values are required.
|
||||||
|
|
||||||
#### Terraform state files
|
#### Terraform state files
|
||||||
|
|
||||||
@ -274,7 +395,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
|
You can apply the Terraform configuration to your cluster with the following command
|
||||||
issued from your cluster's inventory directory (`inventory/$CLUSTER`):
|
issued from your cluster's inventory directory (`inventory/$CLUSTER`):
|
||||||
```ShellSession
|
```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
|
if you chose to create a bastion host, this script will create
|
||||||
@ -288,7 +409,7 @@ pick it up automatically.
|
|||||||
You can destroy your new cluster with the following command issued from the cluster's inventory directory:
|
You can destroy your new cluster with the following command issued from the cluster's inventory directory:
|
||||||
|
|
||||||
```ShellSession
|
```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:
|
If you've started the Ansible run, it may also be a good idea to do some manual cleanup:
|
||||||
@ -323,6 +444,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`).
|
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 host
|
||||||
|
|
||||||
Bastion access will be determined by:
|
Bastion access will be determined by:
|
||||||
@ -337,7 +482,7 @@ So, either a bastion host, or at least master/node with a floating IP are requir
|
|||||||
|
|
||||||
#### Test access
|
#### Test access
|
||||||
|
|
||||||
Make sure you can connect to the hosts. Note that Container Linux by CoreOS will have a state `FAILED` due to Python not being present. This is okay, because Python will be installed during bootstrapping, so long as the hosts are not `UNREACHABLE`.
|
Make sure you can connect to the hosts. Note that Flatcar Container Linux by Kinvolk will have a state `FAILED` due to Python not being present. This is okay, because Python will be installed during bootstrapping, so long as the hosts are not `UNREACHABLE`.
|
||||||
|
|
||||||
```
|
```
|
||||||
$ ansible -i inventory/$CLUSTER/hosts -m ping all
|
$ ansible -i inventory/$CLUSTER/hosts -m ping all
|
||||||
@ -365,7 +510,7 @@ Edit `inventory/$CLUSTER/group_vars/all/all.yml`:
|
|||||||
# Directory where the binaries will be installed
|
# Directory where the binaries will be installed
|
||||||
# Default:
|
# Default:
|
||||||
# bin_dir: /usr/local/bin
|
# bin_dir: /usr/local/bin
|
||||||
# For Container Linux by CoreOS:
|
# For Flatcar Container Linux by Kinvolk:
|
||||||
bin_dir: /opt/bin
|
bin_dir: /opt/bin
|
||||||
```
|
```
|
||||||
- and **cloud_provider**:
|
- and **cloud_provider**:
|
||||||
@ -386,9 +531,17 @@ kube_network_plugin: flannel
|
|||||||
# Can be docker_dns, host_resolvconf or none
|
# Can be docker_dns, host_resolvconf or none
|
||||||
# Default:
|
# Default:
|
||||||
# resolvconf_mode: docker_dns
|
# resolvconf_mode: docker_dns
|
||||||
# For Container Linux by CoreOS:
|
# For Flatcar Container Linux by Kinvolk:
|
||||||
resolvconf_mode: host_resolvconf
|
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
|
### Deploy Kubernetes
|
||||||
|
|
||||||
@ -452,3 +605,81 @@ $ ansible-playbook --become -i inventory/$CLUSTER/hosts ./contrib/network-storag
|
|||||||
## What's next
|
## What's next
|
||||||
|
|
||||||
Try out your new Kubernetes cluster with the [Hello Kubernetes service](https://kubernetes.io/docs/tasks/access-application-cluster/service-access-application-cluster/).
|
Try out your new Kubernetes cluster with the [Hello Kubernetes service](https://kubernetes.io/docs/tasks/access-application-cluster/service-access-application-cluster/).
|
||||||
|
|
||||||
|
## Appendix
|
||||||
|
|
||||||
|
### Migration from `number_of_k8s_nodes*` to `k8s_nodes`
|
||||||
|
If you currently have a cluster defined using the `number_of_k8s_nodes*` variables and wish
|
||||||
|
to migrate to the `k8s_nodes` style you can do it like so:
|
||||||
|
|
||||||
|
```ShellSession
|
||||||
|
$ terraform state list
|
||||||
|
module.compute.data.openstack_images_image_v2.gfs_image
|
||||||
|
module.compute.data.openstack_images_image_v2.vm_image
|
||||||
|
module.compute.openstack_compute_floatingip_associate_v2.k8s_master[0]
|
||||||
|
module.compute.openstack_compute_floatingip_associate_v2.k8s_node[0]
|
||||||
|
module.compute.openstack_compute_floatingip_associate_v2.k8s_node[1]
|
||||||
|
module.compute.openstack_compute_floatingip_associate_v2.k8s_node[2]
|
||||||
|
module.compute.openstack_compute_instance_v2.k8s_master[0]
|
||||||
|
module.compute.openstack_compute_instance_v2.k8s_node[0]
|
||||||
|
module.compute.openstack_compute_instance_v2.k8s_node[1]
|
||||||
|
module.compute.openstack_compute_instance_v2.k8s_node[2]
|
||||||
|
module.compute.openstack_compute_keypair_v2.k8s
|
||||||
|
module.compute.openstack_compute_servergroup_v2.k8s_etcd[0]
|
||||||
|
module.compute.openstack_compute_servergroup_v2.k8s_master[0]
|
||||||
|
module.compute.openstack_compute_servergroup_v2.k8s_node[0]
|
||||||
|
module.compute.openstack_networking_secgroup_rule_v2.bastion[0]
|
||||||
|
module.compute.openstack_networking_secgroup_rule_v2.egress[0]
|
||||||
|
module.compute.openstack_networking_secgroup_rule_v2.k8s
|
||||||
|
module.compute.openstack_networking_secgroup_rule_v2.k8s_allowed_remote_ips[0]
|
||||||
|
module.compute.openstack_networking_secgroup_rule_v2.k8s_allowed_remote_ips[1]
|
||||||
|
module.compute.openstack_networking_secgroup_rule_v2.k8s_allowed_remote_ips[2]
|
||||||
|
module.compute.openstack_networking_secgroup_rule_v2.k8s_master[0]
|
||||||
|
module.compute.openstack_networking_secgroup_rule_v2.worker[0]
|
||||||
|
module.compute.openstack_networking_secgroup_rule_v2.worker[1]
|
||||||
|
module.compute.openstack_networking_secgroup_rule_v2.worker[2]
|
||||||
|
module.compute.openstack_networking_secgroup_rule_v2.worker[3]
|
||||||
|
module.compute.openstack_networking_secgroup_rule_v2.worker[4]
|
||||||
|
module.compute.openstack_networking_secgroup_v2.bastion[0]
|
||||||
|
module.compute.openstack_networking_secgroup_v2.k8s
|
||||||
|
module.compute.openstack_networking_secgroup_v2.k8s_master
|
||||||
|
module.compute.openstack_networking_secgroup_v2.worker
|
||||||
|
module.ips.null_resource.dummy_dependency
|
||||||
|
module.ips.openstack_networking_floatingip_v2.k8s_master[0]
|
||||||
|
module.ips.openstack_networking_floatingip_v2.k8s_node[0]
|
||||||
|
module.ips.openstack_networking_floatingip_v2.k8s_node[1]
|
||||||
|
module.ips.openstack_networking_floatingip_v2.k8s_node[2]
|
||||||
|
module.network.openstack_networking_network_v2.k8s[0]
|
||||||
|
module.network.openstack_networking_router_interface_v2.k8s[0]
|
||||||
|
module.network.openstack_networking_router_v2.k8s[0]
|
||||||
|
module.network.openstack_networking_subnet_v2.k8s[0]
|
||||||
|
$ terraform state mv 'module.compute.openstack_compute_floatingip_associate_v2.k8s_node[0]' 'module.compute.openstack_compute_floatingip_associate_v2.k8s_nodes["1"]'
|
||||||
|
Move "module.compute.openstack_compute_floatingip_associate_v2.k8s_node[0]" to "module.compute.openstack_compute_floatingip_associate_v2.k8s_nodes[\"1\"]"
|
||||||
|
Successfully moved 1 object(s).
|
||||||
|
$ terraform state mv 'module.compute.openstack_compute_floatingip_associate_v2.k8s_node[1]' 'module.compute.openstack_compute_floatingip_associate_v2.k8s_nodes["2"]'
|
||||||
|
Move "module.compute.openstack_compute_floatingip_associate_v2.k8s_node[1]" to "module.compute.openstack_compute_floatingip_associate_v2.k8s_nodes[\"2\"]"
|
||||||
|
Successfully moved 1 object(s).
|
||||||
|
$ terraform state mv 'module.compute.openstack_compute_floatingip_associate_v2.k8s_node[2]' 'module.compute.openstack_compute_floatingip_associate_v2.k8s_nodes["3"]'
|
||||||
|
Move "module.compute.openstack_compute_floatingip_associate_v2.k8s_node[2]" to "module.compute.openstack_compute_floatingip_associate_v2.k8s_nodes[\"3\"]"
|
||||||
|
Successfully moved 1 object(s).
|
||||||
|
$ terraform state mv 'module.compute.openstack_compute_instance_v2.k8s_node[0]' 'module.compute.openstack_compute_instance_v2.k8s_node["1"]'
|
||||||
|
Move "module.compute.openstack_compute_instance_v2.k8s_node[0]" to "module.compute.openstack_compute_instance_v2.k8s_node[\"1\"]"
|
||||||
|
Successfully moved 1 object(s).
|
||||||
|
$ terraform state mv 'module.compute.openstack_compute_instance_v2.k8s_node[1]' 'module.compute.openstack_compute_instance_v2.k8s_node["2"]'
|
||||||
|
Move "module.compute.openstack_compute_instance_v2.k8s_node[1]" to "module.compute.openstack_compute_instance_v2.k8s_node[\"2\"]"
|
||||||
|
Successfully moved 1 object(s).
|
||||||
|
$ terraform state mv 'module.compute.openstack_compute_instance_v2.k8s_node[2]' 'module.compute.openstack_compute_instance_v2.k8s_node["3"]'
|
||||||
|
Move "module.compute.openstack_compute_instance_v2.k8s_node[2]" to "module.compute.openstack_compute_instance_v2.k8s_node[\"3\"]"
|
||||||
|
Successfully moved 1 object(s).
|
||||||
|
$ terraform state mv 'module.ips.openstack_networking_floatingip_v2.k8s_node[0]' 'module.ips.openstack_networking_floatingip_v2.k8s_node["1"]'
|
||||||
|
Move "module.ips.openstack_networking_floatingip_v2.k8s_node[0]" to "module.ips.openstack_networking_floatingip_v2.k8s_node[\"1\"]"
|
||||||
|
Successfully moved 1 object(s).
|
||||||
|
$ terraform state mv 'module.ips.openstack_networking_floatingip_v2.k8s_node[1]' 'module.ips.openstack_networking_floatingip_v2.k8s_node["2"]'
|
||||||
|
Move "module.ips.openstack_networking_floatingip_v2.k8s_node[1]" to "module.ips.openstack_networking_floatingip_v2.k8s_node[\"2\"]"
|
||||||
|
Successfully moved 1 object(s).
|
||||||
|
$ terraform state mv 'module.ips.openstack_networking_floatingip_v2.k8s_node[2]' 'module.ips.openstack_networking_floatingip_v2.k8s_node["3"]'
|
||||||
|
Move "module.ips.openstack_networking_floatingip_v2.k8s_node[2]" to "module.ips.openstack_networking_floatingip_v2.k8s_node[\"3\"]"
|
||||||
|
Successfully moved 1 object(s).
|
||||||
|
```
|
||||||
|
|
||||||
|
Of course for nodes without floating ips those steps can be omitted.
|
||||||
|
@ -1,84 +1,108 @@
|
|||||||
module "network" {
|
provider "openstack" {
|
||||||
source = "modules/network"
|
version = "~> 1.17"
|
||||||
|
}
|
||||||
|
|
||||||
external_net = "${var.external_net}"
|
module "network" {
|
||||||
network_name = "${var.network_name}"
|
source = "./modules/network"
|
||||||
subnet_cidr = "${var.subnet_cidr}"
|
|
||||||
cluster_name = "${var.cluster_name}"
|
external_net = var.external_net
|
||||||
dns_nameservers = "${var.dns_nameservers}"
|
network_name = var.network_name
|
||||||
use_neutron = "${var.use_neutron}"
|
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
|
||||||
|
router_id = var.router_id
|
||||||
}
|
}
|
||||||
|
|
||||||
module "ips" {
|
module "ips" {
|
||||||
source = "modules/ips"
|
source = "./modules/ips"
|
||||||
|
|
||||||
number_of_k8s_masters = "${var.number_of_k8s_masters}"
|
number_of_k8s_masters = var.number_of_k8s_masters
|
||||||
number_of_k8s_masters_no_etcd = "${var.number_of_k8s_masters_no_etcd}"
|
number_of_k8s_masters_no_etcd = var.number_of_k8s_masters_no_etcd
|
||||||
number_of_k8s_nodes = "${var.number_of_k8s_nodes}"
|
number_of_k8s_nodes = var.number_of_k8s_nodes
|
||||||
floatingip_pool = "${var.floatingip_pool}"
|
floatingip_pool = var.floatingip_pool
|
||||||
number_of_bastions = "${var.number_of_bastions}"
|
number_of_bastions = var.number_of_bastions
|
||||||
external_net = "${var.external_net}"
|
external_net = var.external_net
|
||||||
network_name = "${var.network_name}"
|
network_name = var.network_name
|
||||||
router_id = "${module.network.router_id}"
|
router_id = module.network.router_id
|
||||||
|
k8s_nodes = var.k8s_nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
module "compute" {
|
module "compute" {
|
||||||
source = "modules/compute"
|
source = "./modules/compute"
|
||||||
|
|
||||||
cluster_name = "${var.cluster_name}"
|
cluster_name = var.cluster_name
|
||||||
az_list = "${var.az_list}"
|
az_list = var.az_list
|
||||||
number_of_k8s_masters = "${var.number_of_k8s_masters}"
|
az_list_node = var.az_list_node
|
||||||
number_of_k8s_masters_no_etcd = "${var.number_of_k8s_masters_no_etcd}"
|
number_of_k8s_masters = var.number_of_k8s_masters
|
||||||
number_of_etcd = "${var.number_of_etcd}"
|
number_of_k8s_masters_no_etcd = var.number_of_k8s_masters_no_etcd
|
||||||
number_of_k8s_masters_no_floating_ip = "${var.number_of_k8s_masters_no_floating_ip}"
|
number_of_etcd = var.number_of_etcd
|
||||||
number_of_k8s_masters_no_floating_ip_no_etcd = "${var.number_of_k8s_masters_no_floating_ip_no_etcd}"
|
number_of_k8s_masters_no_floating_ip = var.number_of_k8s_masters_no_floating_ip
|
||||||
number_of_k8s_nodes = "${var.number_of_k8s_nodes}"
|
number_of_k8s_masters_no_floating_ip_no_etcd = var.number_of_k8s_masters_no_floating_ip_no_etcd
|
||||||
number_of_bastions = "${var.number_of_bastions}"
|
number_of_k8s_nodes = var.number_of_k8s_nodes
|
||||||
number_of_k8s_nodes_no_floating_ip = "${var.number_of_k8s_nodes_no_floating_ip}"
|
number_of_bastions = var.number_of_bastions
|
||||||
number_of_gfs_nodes_no_floating_ip = "${var.number_of_gfs_nodes_no_floating_ip}"
|
number_of_k8s_nodes_no_floating_ip = var.number_of_k8s_nodes_no_floating_ip
|
||||||
gfs_volume_size_in_gb = "${var.gfs_volume_size_in_gb}"
|
number_of_gfs_nodes_no_floating_ip = var.number_of_gfs_nodes_no_floating_ip
|
||||||
public_key_path = "${var.public_key_path}"
|
k8s_nodes = var.k8s_nodes
|
||||||
image = "${var.image}"
|
bastion_root_volume_size_in_gb = var.bastion_root_volume_size_in_gb
|
||||||
image_gfs = "${var.image_gfs}"
|
etcd_root_volume_size_in_gb = var.etcd_root_volume_size_in_gb
|
||||||
ssh_user = "${var.ssh_user}"
|
master_root_volume_size_in_gb = var.master_root_volume_size_in_gb
|
||||||
ssh_user_gfs = "${var.ssh_user_gfs}"
|
node_root_volume_size_in_gb = var.node_root_volume_size_in_gb
|
||||||
flavor_k8s_master = "${var.flavor_k8s_master}"
|
gfs_root_volume_size_in_gb = var.gfs_root_volume_size_in_gb
|
||||||
flavor_k8s_node = "${var.flavor_k8s_node}"
|
gfs_volume_size_in_gb = var.gfs_volume_size_in_gb
|
||||||
flavor_etcd = "${var.flavor_etcd}"
|
master_volume_type = var.master_volume_type
|
||||||
flavor_gfs_node = "${var.flavor_gfs_node}"
|
public_key_path = var.public_key_path
|
||||||
network_name = "${var.network_name}"
|
image = var.image
|
||||||
flavor_bastion = "${var.flavor_bastion}"
|
image_gfs = var.image_gfs
|
||||||
k8s_master_fips = "${module.ips.k8s_master_fips}"
|
ssh_user = var.ssh_user
|
||||||
k8s_node_fips = "${module.ips.k8s_node_fips}"
|
ssh_user_gfs = var.ssh_user_gfs
|
||||||
bastion_fips = "${module.ips.bastion_fips}"
|
flavor_k8s_master = var.flavor_k8s_master
|
||||||
bastion_allowed_remote_ips = "${var.bastion_allowed_remote_ips}"
|
flavor_k8s_node = var.flavor_k8s_node
|
||||||
supplementary_master_groups = "${var.supplementary_master_groups}"
|
flavor_etcd = var.flavor_etcd
|
||||||
supplementary_node_groups = "${var.supplementary_node_groups}"
|
flavor_gfs_node = var.flavor_gfs_node
|
||||||
worker_allowed_ports = "${var.worker_allowed_ports}"
|
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
|
||||||
|
k8s_nodes_fips = module.ips.k8s_nodes_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
|
||||||
|
master_allowed_ports = var.master_allowed_ports
|
||||||
|
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}"
|
network_id = module.network.router_id
|
||||||
}
|
}
|
||||||
|
|
||||||
output "private_subnet_id" {
|
output "private_subnet_id" {
|
||||||
value = "${module.network.subnet_id}"
|
value = module.network.subnet_id
|
||||||
}
|
}
|
||||||
|
|
||||||
output "floating_network_id" {
|
output "floating_network_id" {
|
||||||
value = "${var.external_net}"
|
value = var.external_net
|
||||||
}
|
}
|
||||||
|
|
||||||
output "router_id" {
|
output "router_id" {
|
||||||
value = "${module.network.router_id}"
|
value = module.network.router_id
|
||||||
}
|
}
|
||||||
|
|
||||||
output "k8s_master_fips" {
|
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" {
|
output "k8s_node_fips" {
|
||||||
value = "${module.ips.k8s_node_fips}"
|
value = var.number_of_k8s_nodes > 0 ? module.ips.k8s_node_fips : [for key, value in module.ips.k8s_nodes_fips : value.address]
|
||||||
}
|
}
|
||||||
|
|
||||||
output "bastion_fips" {
|
output "bastion_fips" {
|
||||||
value = "${module.ips.bastion_fips}"
|
value = module.ips.bastion_fips
|
||||||
}
|
}
|
||||||
|
@ -1,327 +1,617 @@
|
|||||||
|
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" {
|
resource "openstack_compute_keypair_v2" "k8s" {
|
||||||
name = "kubernetes-${var.cluster_name}"
|
name = "kubernetes-${var.cluster_name}"
|
||||||
public_key = "${chomp(file(var.public_key_path))}"
|
public_key = chomp(file(var.public_key_path))
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "openstack_networking_secgroup_v2" "k8s_master" {
|
resource "openstack_networking_secgroup_v2" "k8s_master" {
|
||||||
name = "${var.cluster_name}-k8s-master"
|
name = "${var.cluster_name}-k8s-master"
|
||||||
description = "${var.cluster_name} - Kubernetes Master"
|
description = "${var.cluster_name} - Kubernetes Master"
|
||||||
|
delete_default_rules = true
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "openstack_networking_secgroup_rule_v2" "k8s_master" {
|
resource "openstack_networking_secgroup_rule_v2" "k8s_master" {
|
||||||
|
count = length(var.master_allowed_remote_ips)
|
||||||
direction = "ingress"
|
direction = "ingress"
|
||||||
ethertype = "IPv4"
|
ethertype = "IPv4"
|
||||||
protocol = "tcp"
|
protocol = "tcp"
|
||||||
port_range_min = "6443"
|
port_range_min = "6443"
|
||||||
port_range_max = "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}"
|
security_group_id = openstack_networking_secgroup_v2.k8s_master.id
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "openstack_networking_secgroup_rule_v2" "k8s_master_ports" {
|
||||||
|
count = length(var.master_allowed_ports)
|
||||||
|
direction = "ingress"
|
||||||
|
ethertype = "IPv4"
|
||||||
|
protocol = lookup(var.master_allowed_ports[count.index], "protocol", "tcp")
|
||||||
|
port_range_min = lookup(var.master_allowed_ports[count.index], "port_range_min")
|
||||||
|
port_range_max = lookup(var.master_allowed_ports[count.index], "port_range_max")
|
||||||
|
remote_ip_prefix = lookup(var.master_allowed_ports[count.index], "remote_ip_prefix", "0.0.0.0/0")
|
||||||
|
security_group_id = openstack_networking_secgroup_v2.k8s_master.id
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "openstack_networking_secgroup_v2" "bastion" {
|
resource "openstack_networking_secgroup_v2" "bastion" {
|
||||||
name = "${var.cluster_name}-bastion"
|
name = "${var.cluster_name}-bastion"
|
||||||
count = "${var.number_of_bastions ? 1 : 0}"
|
count = var.number_of_bastions != "" ? 1 : 0
|
||||||
description = "${var.cluster_name} - Bastion Server"
|
description = "${var.cluster_name} - Bastion Server"
|
||||||
|
delete_default_rules = true
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "openstack_networking_secgroup_rule_v2" "bastion" {
|
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"
|
direction = "ingress"
|
||||||
ethertype = "IPv4"
|
ethertype = "IPv4"
|
||||||
protocol = "tcp"
|
protocol = "tcp"
|
||||||
port_range_min = "22"
|
port_range_min = "22"
|
||||||
port_range_max = "22"
|
port_range_max = "22"
|
||||||
remote_ip_prefix = "${var.bastion_allowed_remote_ips[count.index]}"
|
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[0].id
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "openstack_networking_secgroup_v2" "k8s" {
|
resource "openstack_networking_secgroup_v2" "k8s" {
|
||||||
name = "${var.cluster_name}-k8s"
|
name = "${var.cluster_name}-k8s"
|
||||||
description = "${var.cluster_name} - Kubernetes"
|
description = "${var.cluster_name} - Kubernetes"
|
||||||
|
delete_default_rules = true
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "openstack_networking_secgroup_rule_v2" "k8s" {
|
resource "openstack_networking_secgroup_rule_v2" "k8s" {
|
||||||
direction = "ingress"
|
direction = "ingress"
|
||||||
ethertype = "IPv4"
|
ethertype = "IPv4"
|
||||||
remote_group_id = "${openstack_networking_secgroup_v2.k8s.id}"
|
remote_group_id = openstack_networking_secgroup_v2.k8s.id
|
||||||
security_group_id = "${openstack_networking_secgroup_v2.k8s.id}"
|
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" {
|
resource "openstack_networking_secgroup_v2" "worker" {
|
||||||
name = "${var.cluster_name}-k8s-worker"
|
name = "${var.cluster_name}-k8s-worker"
|
||||||
description = "${var.cluster_name} - Kubernetes worker nodes"
|
description = "${var.cluster_name} - Kubernetes worker nodes"
|
||||||
|
delete_default_rules = true
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "openstack_networking_secgroup_rule_v2" "worker" {
|
resource "openstack_networking_secgroup_rule_v2" "worker" {
|
||||||
count = "${length(var.worker_allowed_ports)}"
|
count = length(var.worker_allowed_ports)
|
||||||
direction = "ingress"
|
direction = "ingress"
|
||||||
ethertype = "IPv4"
|
ethertype = "IPv4"
|
||||||
protocol = "${lookup(var.worker_allowed_ports[count.index], "protocol", "tcp")}"
|
protocol = lookup(var.worker_allowed_ports[count.index], "protocol", "tcp")
|
||||||
port_range_min = "${lookup(var.worker_allowed_ports[count.index], "port_range_min")}"
|
port_range_min = lookup(var.worker_allowed_ports[count.index], "port_range_min")
|
||||||
port_range_max = "${lookup(var.worker_allowed_ports[count.index], "port_range_max")}"
|
port_range_max = lookup(var.worker_allowed_ports[count.index], "port_range_max")
|
||||||
remote_ip_prefix = "${lookup(var.worker_allowed_ports[count.index], "remote_ip_prefix", "0.0.0.0/0")}"
|
remote_ip_prefix = lookup(var.worker_allowed_ports[count.index], "remote_ip_prefix", "0.0.0.0/0")
|
||||||
security_group_id = "${openstack_networking_secgroup_v2.worker.id}"
|
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" {
|
resource "openstack_compute_instance_v2" "bastion" {
|
||||||
name = "${var.cluster_name}-bastion-${count.index+1}"
|
name = "${var.cluster_name}-bastion-${count.index + 1}"
|
||||||
count = "${var.number_of_bastions}"
|
count = var.number_of_bastions
|
||||||
image_name = "${var.image}"
|
image_name = var.image
|
||||||
flavor_id = "${var.flavor_bastion}"
|
flavor_id = var.flavor_bastion
|
||||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
key_pair = openstack_compute_keypair_v2.k8s.name
|
||||||
|
|
||||||
network {
|
dynamic "block_device" {
|
||||||
name = "${var.network_name}"
|
for_each = var.bastion_root_volume_size_in_gb > 0 ? [var.image] : []
|
||||||
|
content {
|
||||||
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}",
|
network {
|
||||||
"${openstack_networking_secgroup_v2.bastion.name}",
|
name = var.network_name
|
||||||
"default",
|
}
|
||||||
|
|
||||||
|
security_groups = [openstack_networking_secgroup_v2.k8s.name,
|
||||||
|
element(openstack_networking_secgroup_v2.bastion.*.name, count.index),
|
||||||
]
|
]
|
||||||
|
|
||||||
metadata = {
|
metadata = {
|
||||||
ssh_user = "${var.ssh_user}"
|
ssh_user = var.ssh_user
|
||||||
kubespray_groups = "bastion"
|
kubespray_groups = "bastion"
|
||||||
depends_on = "${var.network_id}"
|
depends_on = var.network_id
|
||||||
|
use_access_ip = var.use_access_ip
|
||||||
}
|
}
|
||||||
|
|
||||||
provisioner "local-exec" {
|
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" "k8s_master" {
|
resource "openstack_compute_instance_v2" "k8s_master" {
|
||||||
name = "${var.cluster_name}-k8s-master-${count.index+1}"
|
name = "${var.cluster_name}-k8s-master-${count.index + 1}"
|
||||||
count = "${var.number_of_k8s_masters}"
|
count = var.number_of_k8s_masters
|
||||||
availability_zone = "${element(var.az_list, count.index)}"
|
availability_zone = element(var.az_list, count.index)
|
||||||
image_name = "${var.image}"
|
image_name = var.image
|
||||||
flavor_id = "${var.flavor_k8s_master}"
|
flavor_id = var.flavor_k8s_master
|
||||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
key_pair = openstack_compute_keypair_v2.k8s.name
|
||||||
|
|
||||||
|
|
||||||
|
dynamic "block_device" {
|
||||||
|
for_each = var.master_root_volume_size_in_gb > 0 ? [var.image] : []
|
||||||
|
content {
|
||||||
|
uuid = data.openstack_images_image_v2.vm_image.id
|
||||||
|
source_type = "image"
|
||||||
|
volume_size = var.master_root_volume_size_in_gb
|
||||||
|
volume_type = var.master_volume_type
|
||||||
|
boot_index = 0
|
||||||
|
destination_type = "volume"
|
||||||
|
delete_on_termination = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
network {
|
network {
|
||||||
name = "${var.network_name}"
|
name = var.network_name
|
||||||
}
|
}
|
||||||
|
|
||||||
# The join() hack is described here: https://github.com/hashicorp/terraform/issues/11566
|
security_groups = [openstack_networking_secgroup_v2.k8s_master.name,
|
||||||
# As a workaround for creating "dynamic" lists (when, for example, no bastion host is created)
|
|
||||||
|
|
||||||
security_groups = ["${compact(list(
|
|
||||||
openstack_networking_secgroup_v2.k8s_master.name,
|
|
||||||
join(" ", openstack_networking_secgroup_v2.bastion.*.id),
|
|
||||||
openstack_networking_secgroup_v2.k8s.name,
|
openstack_networking_secgroup_v2.k8s.name,
|
||||||
"default",
|
]
|
||||||
))}"]
|
|
||||||
metadata = {
|
dynamic "scheduler_hints" {
|
||||||
ssh_user = "${var.ssh_user}"
|
for_each = var.use_server_groups ? [openstack_compute_servergroup_v2.k8s_master[0]] : []
|
||||||
kubespray_groups = "etcd,kube-master,${var.supplementary_master_groups},k8s-cluster,vault"
|
content {
|
||||||
depends_on = "${var.network_id}"
|
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" {
|
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" {
|
resource "openstack_compute_instance_v2" "k8s_master_no_etcd" {
|
||||||
name = "${var.cluster_name}-k8s-master-ne-${count.index+1}"
|
name = "${var.cluster_name}-k8s-master-ne-${count.index + 1}"
|
||||||
count = "${var.number_of_k8s_masters_no_etcd}"
|
count = var.number_of_k8s_masters_no_etcd
|
||||||
availability_zone = "${element(var.az_list, count.index)}"
|
availability_zone = element(var.az_list, count.index)
|
||||||
image_name = "${var.image}"
|
image_name = var.image
|
||||||
flavor_id = "${var.flavor_k8s_master}"
|
flavor_id = var.flavor_k8s_master
|
||||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
key_pair = openstack_compute_keypair_v2.k8s.name
|
||||||
|
|
||||||
network {
|
|
||||||
name = "${var.network_name}"
|
dynamic "block_device" {
|
||||||
|
for_each = var.master_root_volume_size_in_gb > 0 ? [var.image] : []
|
||||||
|
content {
|
||||||
|
uuid = data.openstack_images_image_v2.vm_image.id
|
||||||
|
source_type = "image"
|
||||||
|
volume_size = var.master_root_volume_size_in_gb
|
||||||
|
volume_type = var.master_volume_type
|
||||||
|
boot_index = 0
|
||||||
|
destination_type = "volume"
|
||||||
|
delete_on_termination = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
security_groups = ["${compact(list(
|
network {
|
||||||
openstack_networking_secgroup_v2.k8s_master.name,
|
name = var.network_name
|
||||||
join(" ", openstack_networking_secgroup_v2.bastion.*.id),
|
}
|
||||||
|
|
||||||
|
security_groups = [openstack_networking_secgroup_v2.k8s_master.name,
|
||||||
openstack_networking_secgroup_v2.k8s.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 = {
|
metadata = {
|
||||||
ssh_user = "${var.ssh_user}"
|
ssh_user = var.ssh_user
|
||||||
kubespray_groups = "kube-master,${var.supplementary_master_groups},k8s-cluster,vault"
|
kubespray_groups = "kube-master,${var.supplementary_master_groups},k8s-cluster,vault"
|
||||||
depends_on = "${var.network_id}"
|
depends_on = var.network_id
|
||||||
|
use_access_ip = var.use_access_ip
|
||||||
}
|
}
|
||||||
|
|
||||||
provisioner "local-exec" {
|
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" "etcd" {
|
resource "openstack_compute_instance_v2" "etcd" {
|
||||||
name = "${var.cluster_name}-etcd-${count.index+1}"
|
name = "${var.cluster_name}-etcd-${count.index + 1}"
|
||||||
count = "${var.number_of_etcd}"
|
count = var.number_of_etcd
|
||||||
availability_zone = "${element(var.az_list, count.index)}"
|
availability_zone = element(var.az_list, count.index)
|
||||||
image_name = "${var.image}"
|
image_name = var.image
|
||||||
flavor_id = "${var.flavor_etcd}"
|
flavor_id = var.flavor_etcd
|
||||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
key_pair = openstack_compute_keypair_v2.k8s.name
|
||||||
|
|
||||||
network {
|
dynamic "block_device" {
|
||||||
name = "${var.network_name}"
|
for_each = var.etcd_root_volume_size_in_gb > 0 ? [var.image] : []
|
||||||
|
content {
|
||||||
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}"]
|
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 = {
|
metadata = {
|
||||||
ssh_user = "${var.ssh_user}"
|
ssh_user = var.ssh_user
|
||||||
kubespray_groups = "etcd,vault,no-floating"
|
kubespray_groups = "etcd,vault,no-floating"
|
||||||
depends_on = "${var.network_id}"
|
depends_on = var.network_id
|
||||||
|
use_access_ip = var.use_access_ip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip" {
|
resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip" {
|
||||||
name = "${var.cluster_name}-k8s-master-nf-${count.index+1}"
|
name = "${var.cluster_name}-k8s-master-nf-${count.index + 1}"
|
||||||
count = "${var.number_of_k8s_masters_no_floating_ip}"
|
count = var.number_of_k8s_masters_no_floating_ip
|
||||||
availability_zone = "${element(var.az_list, count.index)}"
|
availability_zone = element(var.az_list, count.index)
|
||||||
image_name = "${var.image}"
|
image_name = var.image
|
||||||
flavor_id = "${var.flavor_k8s_master}"
|
flavor_id = var.flavor_k8s_master
|
||||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
key_pair = openstack_compute_keypair_v2.k8s.name
|
||||||
|
|
||||||
network {
|
dynamic "block_device" {
|
||||||
name = "${var.network_name}"
|
for_each = var.master_root_volume_size_in_gb > 0 ? [var.image] : []
|
||||||
|
content {
|
||||||
|
uuid = data.openstack_images_image_v2.vm_image.id
|
||||||
|
source_type = "image"
|
||||||
|
volume_size = var.master_root_volume_size_in_gb
|
||||||
|
volume_type = var.master_volume_type
|
||||||
|
boot_index = 0
|
||||||
|
destination_type = "volume"
|
||||||
|
delete_on_termination = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
security_groups = ["${openstack_networking_secgroup_v2.k8s_master.name}",
|
network {
|
||||||
"${openstack_networking_secgroup_v2.k8s.name}",
|
name = var.network_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 = {
|
metadata = {
|
||||||
ssh_user = "${var.ssh_user}"
|
ssh_user = var.ssh_user
|
||||||
kubespray_groups = "etcd,kube-master,${var.supplementary_master_groups},k8s-cluster,vault,no-floating"
|
kubespray_groups = "etcd,kube-master,${var.supplementary_master_groups},k8s-cluster,vault,no-floating"
|
||||||
depends_on = "${var.network_id}"
|
depends_on = var.network_id
|
||||||
|
use_access_ip = var.use_access_ip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip_no_etcd" {
|
resource "openstack_compute_instance_v2" "k8s_master_no_floating_ip_no_etcd" {
|
||||||
name = "${var.cluster_name}-k8s-master-ne-nf-${count.index+1}"
|
name = "${var.cluster_name}-k8s-master-ne-nf-${count.index + 1}"
|
||||||
count = "${var.number_of_k8s_masters_no_floating_ip_no_etcd}"
|
count = var.number_of_k8s_masters_no_floating_ip_no_etcd
|
||||||
availability_zone = "${element(var.az_list, count.index)}"
|
availability_zone = element(var.az_list, count.index)
|
||||||
image_name = "${var.image}"
|
image_name = var.image
|
||||||
flavor_id = "${var.flavor_k8s_master}"
|
flavor_id = var.flavor_k8s_master
|
||||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
key_pair = openstack_compute_keypair_v2.k8s.name
|
||||||
|
|
||||||
network {
|
dynamic "block_device" {
|
||||||
name = "${var.network_name}"
|
for_each = var.master_root_volume_size_in_gb > 0 ? [var.image] : []
|
||||||
|
content {
|
||||||
|
uuid = data.openstack_images_image_v2.vm_image.id
|
||||||
|
source_type = "image"
|
||||||
|
volume_size = var.master_root_volume_size_in_gb
|
||||||
|
volume_type = var.master_volume_type
|
||||||
|
boot_index = 0
|
||||||
|
destination_type = "volume"
|
||||||
|
delete_on_termination = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
security_groups = ["${openstack_networking_secgroup_v2.k8s_master.name}",
|
network {
|
||||||
"${openstack_networking_secgroup_v2.k8s.name}",
|
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 = {
|
metadata = {
|
||||||
ssh_user = "${var.ssh_user}"
|
ssh_user = var.ssh_user
|
||||||
kubespray_groups = "kube-master,${var.supplementary_master_groups},k8s-cluster,vault,no-floating"
|
kubespray_groups = "kube-master,${var.supplementary_master_groups},k8s-cluster,vault,no-floating"
|
||||||
depends_on = "${var.network_id}"
|
depends_on = var.network_id
|
||||||
|
use_access_ip = var.use_access_ip
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "openstack_compute_instance_v2" "k8s_node" {
|
resource "openstack_compute_instance_v2" "k8s_node" {
|
||||||
name = "${var.cluster_name}-k8s-node-${count.index+1}"
|
name = "${var.cluster_name}-k8s-node-${count.index + 1}"
|
||||||
count = "${var.number_of_k8s_nodes}"
|
count = var.number_of_k8s_nodes
|
||||||
availability_zone = "${element(var.az_list, count.index)}"
|
availability_zone = element(var.az_list_node, count.index)
|
||||||
image_name = "${var.image}"
|
image_name = var.image
|
||||||
flavor_id = "${var.flavor_k8s_node}"
|
flavor_id = var.flavor_k8s_node
|
||||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
key_pair = openstack_compute_keypair_v2.k8s.name
|
||||||
|
|
||||||
network {
|
dynamic "block_device" {
|
||||||
name = "${var.network_name}"
|
for_each = var.node_root_volume_size_in_gb > 0 ? [var.image] : []
|
||||||
|
content {
|
||||||
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
security_groups = ["${compact(list(
|
network {
|
||||||
openstack_networking_secgroup_v2.k8s_master.name,
|
name = var.network_name
|
||||||
join(" ", openstack_networking_secgroup_v2.bastion.*.id),
|
}
|
||||||
openstack_networking_secgroup_v2.k8s.name,
|
|
||||||
"default",
|
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 = {
|
metadata = {
|
||||||
ssh_user = "${var.ssh_user}"
|
ssh_user = var.ssh_user
|
||||||
kubespray_groups = "kube-node,k8s-cluster,${var.supplementary_node_groups}"
|
kubespray_groups = "kube-node,k8s-cluster,${var.supplementary_node_groups}"
|
||||||
depends_on = "${var.network_id}"
|
depends_on = var.network_id
|
||||||
|
use_access_ip = var.use_access_ip
|
||||||
}
|
}
|
||||||
|
|
||||||
provisioner "local-exec" {
|
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"
|
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" {
|
resource "openstack_compute_instance_v2" "k8s_node_no_floating_ip" {
|
||||||
name = "${var.cluster_name}-k8s-node-nf-${count.index+1}"
|
name = "${var.cluster_name}-k8s-node-nf-${count.index + 1}"
|
||||||
count = "${var.number_of_k8s_nodes_no_floating_ip}"
|
count = var.number_of_k8s_nodes_no_floating_ip
|
||||||
availability_zone = "${element(var.az_list, count.index)}"
|
availability_zone = element(var.az_list_node, count.index)
|
||||||
image_name = "${var.image}"
|
image_name = var.image
|
||||||
flavor_id = "${var.flavor_k8s_node}"
|
flavor_id = var.flavor_k8s_node
|
||||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
key_pair = openstack_compute_keypair_v2.k8s.name
|
||||||
|
|
||||||
network {
|
dynamic "block_device" {
|
||||||
name = "${var.network_name}"
|
for_each = var.node_root_volume_size_in_gb > 0 ? [var.image] : []
|
||||||
|
content {
|
||||||
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}",
|
network {
|
||||||
"${openstack_networking_secgroup_v2.worker.name}",
|
name = var.network_name
|
||||||
"default",
|
}
|
||||||
|
|
||||||
|
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 = {
|
metadata = {
|
||||||
ssh_user = "${var.ssh_user}"
|
ssh_user = var.ssh_user
|
||||||
kubespray_groups = "kube-node,k8s-cluster,no-floating,${var.supplementary_node_groups}"
|
kubespray_groups = "kube-node,k8s-cluster,no-floating,${var.supplementary_node_groups}"
|
||||||
depends_on = "${var.network_id}"
|
depends_on = var.network_id
|
||||||
|
use_access_ip = var.use_access_ip
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
resource "openstack_compute_instance_v2" "k8s_nodes" {
|
||||||
|
for_each = var.number_of_k8s_nodes == 0 && var.number_of_k8s_nodes_no_floating_ip == 0 ? var.k8s_nodes : {}
|
||||||
|
name = "${var.cluster_name}-k8s-node-${each.key}"
|
||||||
|
availability_zone = each.value.az
|
||||||
|
image_name = var.image
|
||||||
|
flavor_id = each.value.flavor
|
||||||
|
key_pair = openstack_compute_keypair_v2.k8s.name
|
||||||
|
|
||||||
|
dynamic "block_device" {
|
||||||
|
for_each = var.node_root_volume_size_in_gb > 0 ? [var.image] : []
|
||||||
|
content {
|
||||||
|
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,%{if each.value.floating_ip == false}no-floating,%{endif}${var.supplementary_node_groups}"
|
||||||
|
depends_on = var.network_id
|
||||||
|
use_access_ip = var.use_access_ip
|
||||||
|
}
|
||||||
|
|
||||||
|
provisioner "local-exec" {
|
||||||
|
command = "%{if each.value.floating_ip}sed s/USER/${var.ssh_user}/ ../../contrib/terraform/openstack/ansible_bastion_template.txt | sed s/BASTION_ADDRESS/${element(concat(var.bastion_fips, [for key, value in var.k8s_nodes_fips : value.address]), 0)}/ > group_vars/no-floating.yml%{else}true%{endif}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
availability_zone = element(var.az_list, count.index)
|
||||||
|
image_name = var.image_gfs
|
||||||
|
flavor_id = var.flavor_gfs_node
|
||||||
|
key_pair = openstack_compute_keypair_v2.k8s.name
|
||||||
|
|
||||||
|
dynamic "block_device" {
|
||||||
|
for_each = var.gfs_root_volume_size_in_gb > 0 ? [var.image] : []
|
||||||
|
content {
|
||||||
|
uuid = data.openstack_images_image_v2.vm_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_floatingip_associate_v2" "bastion" {
|
resource "openstack_compute_floatingip_associate_v2" "bastion" {
|
||||||
count = "${var.number_of_bastions}"
|
count = var.number_of_bastions
|
||||||
floating_ip = "${var.bastion_fips[count.index]}"
|
floating_ip = var.bastion_fips[count.index]
|
||||||
instance_id = "${element(openstack_compute_instance_v2.bastion.*.id, 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" "k8s_master" {
|
resource "openstack_compute_floatingip_associate_v2" "k8s_master" {
|
||||||
count = "${var.number_of_k8s_masters}"
|
count = var.number_of_k8s_masters
|
||||||
instance_id = "${element(openstack_compute_instance_v2.k8s_master.*.id, count.index)}"
|
instance_id = element(openstack_compute_instance_v2.k8s_master.*.id, count.index)
|
||||||
floating_ip = "${var.k8s_master_fips[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_node" {
|
resource "openstack_compute_floatingip_associate_v2" "k8s_node" {
|
||||||
count = "${var.number_of_k8s_nodes}"
|
count = var.node_root_volume_size_in_gb == 0 ? var.number_of_k8s_nodes : 0
|
||||||
floating_ip = "${var.k8s_node_fips[count.index]}"
|
floating_ip = var.k8s_node_fips[count.index]
|
||||||
instance_id = "${element(openstack_compute_instance_v2.k8s_node.*.id, 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_nodes" {
|
||||||
|
for_each = var.number_of_k8s_nodes == 0 && var.number_of_k8s_nodes_no_floating_ip == 0 ? { for key, value in var.k8s_nodes : key => value if value.floating_ip } : {}
|
||||||
|
floating_ip = var.k8s_nodes_fips[each.key].address
|
||||||
|
instance_id = openstack_compute_instance_v2.k8s_nodes[each.key].id
|
||||||
|
wait_until_associated = var.wait_for_floatingip
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "openstack_blockstorage_volume_v2" "glusterfs_volume" {
|
resource "openstack_blockstorage_volume_v2" "glusterfs_volume" {
|
||||||
name = "${var.cluster_name}-glusterfs_volume-${count.index+1}"
|
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"
|
description = "Non-ephemeral volume for GlusterFS"
|
||||||
size = "${var.gfs_volume_size_in_gb}"
|
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}"
|
|
||||||
availability_zone = "${element(var.az_list, count.index)}"
|
|
||||||
image_name = "${var.image_gfs}"
|
|
||||||
flavor_id = "${var.flavor_gfs_node}"
|
|
||||||
key_pair = "${openstack_compute_keypair_v2.k8s.name}"
|
|
||||||
|
|
||||||
network {
|
|
||||||
name = "${var.network_name}"
|
|
||||||
}
|
|
||||||
|
|
||||||
security_groups = ["${openstack_networking_secgroup_v2.k8s.name}",
|
|
||||||
"default",
|
|
||||||
]
|
|
||||||
|
|
||||||
metadata = {
|
|
||||||
ssh_user = "${var.ssh_user_gfs}"
|
|
||||||
kubespray_groups = "gfs-cluster,network-storage,no-floating"
|
|
||||||
depends_on = "${var.network_id}"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
resource "openstack_compute_volume_attach_v2" "glusterfs_volume" {
|
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)}"
|
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)}"
|
volume_id = element(openstack_blockstorage_volume_v2.glusterfs_volume.*.id, count.index)
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user