Compare commits
679 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f701a0041 | ||
|
|
593f9231ae | ||
|
|
59df8a0dda | ||
|
|
6b93973bad | ||
|
|
df3ec571fb | ||
|
|
f03fad7a96 | ||
|
|
f714e9faf3 | ||
|
|
3e1a3d83da | ||
|
|
8ba2ea9ca7 | ||
|
|
7dc8ef1028 | ||
|
|
ef51cceff5 | ||
|
|
a40c2502de | ||
|
|
0201f9cba8 | ||
|
|
7c1277f24c | ||
|
|
29f03dfb55 | ||
|
|
02d2d38c21 | ||
|
|
6757efe290 | ||
|
|
5990af8ced | ||
|
|
6cddc25f0e | ||
|
|
8bd773b536 | ||
|
|
d9ba209543 | ||
|
|
c51646e3db | ||
|
|
4f9d00c021 | ||
|
|
0042c4be54 | ||
|
|
910eb322e0 | ||
|
|
064b768176 | ||
|
|
4daa655516 | ||
|
|
d6910e9788 | ||
|
|
eed16afb00 | ||
|
|
6ec77b27da | ||
|
|
621ed52bab | ||
|
|
b8c2ed20d1 | ||
|
|
19ad9c2d46 | ||
|
|
41cc210fa0 | ||
|
|
3488b542ac | ||
|
|
04a030bcf0 | ||
|
|
25415c5501 | ||
|
|
a094be45d9 | ||
|
|
fdb8a7d74a | ||
|
|
d481dbad62 | ||
|
|
c1e7f1b957 | ||
|
|
93094c78eb | ||
|
|
a14609f730 | ||
|
|
a8984578e4 | ||
|
|
51e9fec65d | ||
|
|
38b7f42f9e | ||
|
|
e574948577 | ||
|
|
ebf1efe07e | ||
|
|
83bc67c8ad | ||
|
|
1648eceb47 | ||
|
|
538aaaf217 | ||
|
|
5b35443533 | ||
|
|
e089a56e05 | ||
|
|
5c4a778e6a | ||
|
|
e0ec8028eb | ||
|
|
578ff2e45c | ||
|
|
d04877a9e7 | ||
|
|
727b5ebd7f | ||
|
|
af1e1e6942 | ||
|
|
d05bb6b199 | ||
|
|
ba953484bf | ||
|
|
fdf78b1d7d | ||
|
|
95fed47c1c | ||
|
|
4cf916e6f4 | ||
|
|
23bf326d93 | ||
|
|
bcd4d185a7 | ||
|
|
57a5fa593c | ||
|
|
421ca3fb3c | ||
|
|
29945c2c7a | ||
|
|
9d82d54c5b | ||
|
|
4827d9984f | ||
|
|
d718fe3ee1 | ||
|
|
a8fbe35ecf | ||
|
|
5947f696ff | ||
|
|
40e0bbeec2 | ||
|
|
ecbf3c5f51 | ||
|
|
dfa952f0d5 | ||
|
|
793577d044 | ||
|
|
1224dc0c87 | ||
|
|
885c1952a4 | ||
|
|
383b3e798b | ||
|
|
1020167e22 | ||
|
|
3c242f58da | ||
|
|
f8a18ce662 | ||
|
|
6a917c5f36 | ||
|
|
7af1f206aa | ||
|
|
0714abfe79 | ||
|
|
6037734641 | ||
|
|
76ba38cec5 | ||
|
|
5c918dc56a | ||
|
|
292ed0e605 | ||
|
|
e97960c2f0 | ||
|
|
9f73341271 | ||
|
|
163515c5a0 | ||
|
|
41845522f6 | ||
|
|
ec86b30d2b | ||
|
|
a90c957463 | ||
|
|
18a2321ddd | ||
|
|
a5f0d457ec | ||
|
|
368b7f3939 | ||
|
|
e4dfbe79e1 | ||
|
|
fdf5fa58d3 | ||
|
|
9ef96e9bb2 | ||
|
|
a8e393496f | ||
|
|
6b302443e6 | ||
|
|
3fdf7a0b88 | ||
|
|
0cb02f1448 | ||
|
|
8b09afdf3e | ||
|
|
23963e854a | ||
|
|
04167cf77e | ||
|
|
6f0a01fcf4 | ||
|
|
0824433260 | ||
|
|
3e0f5ea327 | ||
|
|
a4be48eb32 | ||
|
|
90d03b0afe | ||
|
|
37802e1026 | ||
|
|
16add04ccf | ||
|
|
90c88d7f96 | ||
|
|
2b0e2725f9 | ||
|
|
66bbae586f | ||
|
|
d2ac2df372 | ||
|
|
d5aed20f0a | ||
|
|
42fcdef9f0 | ||
|
|
482811460d | ||
|
|
8fd93030b4 | ||
|
|
5db1ef23fe | ||
|
|
14fc54e323 | ||
|
|
3d1d1f0bb8 | ||
|
|
a5f56027b5 | ||
|
|
bad3ccddc3 | ||
|
|
da35a219d1 | ||
|
|
8209aeea6d | ||
|
|
2d2315c4c4 | ||
|
|
c6a78cee92 | ||
|
|
e0958159f3 | ||
|
|
9d804ba3a8 | ||
|
|
808df20cdb | ||
|
|
c46d2ce791 | ||
|
|
f20528be35 | ||
|
|
5253747c00 | ||
|
|
aaee97c0fa | ||
|
|
d82c40c9fe | ||
|
|
dcc9c4d31a | ||
|
|
3b119fb707 | ||
|
|
b198b65d52 | ||
|
|
f94974cc2c | ||
|
|
d9f9a51e55 | ||
|
|
111f41785f | ||
|
|
e65995cd32 | ||
|
|
ea9d5e3670 | ||
|
|
40b2bf76ae | ||
|
|
6fa110d4fd | ||
|
|
d33d154e14 | ||
|
|
483d329556 | ||
|
|
f3e4615a33 | ||
|
|
9106cee216 | ||
|
|
2d26d95a98 | ||
|
|
5745d030fb | ||
|
|
9f7eccc68f | ||
|
|
3fe047f79c | ||
|
|
9897ce8bf2 | ||
|
|
c33a97fcf2 | ||
|
|
ca4a5d33f0 | ||
|
|
2953dad221 | ||
|
|
f35a11ff37 | ||
|
|
8534107fc8 | ||
|
|
681e2bf213 | ||
|
|
2283c06971 | ||
|
|
bb9435a604 | ||
|
|
96091dfcf5 | ||
|
|
cf4a1ba083 | ||
|
|
4c7b63a215 | ||
|
|
1e04a0e943 | ||
|
|
f7353b1295 | ||
|
|
dbf04985c4 | ||
|
|
f783486057 | ||
|
|
0faef46773 | ||
|
|
cbd7a1bb58 | ||
|
|
19ac0e9327 | ||
|
|
b5cf3a2146 | ||
|
|
5cf0cbe041 | ||
|
|
df5c3ab91e | ||
|
|
5b95db2208 | ||
|
|
22d955b3a9 | ||
|
|
b7fa38e2e7 | ||
|
|
b16c85888e | ||
|
|
261d64ec1d | ||
|
|
62f7cdbb43 | ||
|
|
30814302af | ||
|
|
fd3cd64e11 | ||
|
|
536cd8d45e | ||
|
|
78de5374ed | ||
|
|
aff76e0d0e | ||
|
|
0f4ab07324 | ||
|
|
08da2455dd | ||
|
|
8e0c55f9fa | ||
|
|
00b4beda91 | ||
|
|
1af119db80 | ||
|
|
4eb2757847 | ||
|
|
3cdfbd843b | ||
|
|
0f5a39f328 | ||
|
|
9c8302b2d2 | ||
|
|
e5ea1b0a19 | ||
|
|
e6558fb9fc | ||
|
|
b67f8d2b7b | ||
|
|
5c92f09dd0 | ||
|
|
f2f1125e44 | ||
|
|
6d4ad82262 | ||
|
|
7cf5f8caae | ||
|
|
3d4bf3abbf | ||
|
|
5036a12a65 | ||
|
|
489f6e2e67 | ||
|
|
c9887e8c15 | ||
|
|
239db504ff | ||
|
|
9b7ce3b6ba | ||
|
|
3b86e64faf | ||
|
|
c3ae23d3a5 | ||
|
|
73e28ca556 | ||
|
|
a634da4d19 | ||
|
|
a3dce9409b | ||
|
|
a9cf1975ca | ||
|
|
51ece9412e | ||
|
|
b37258edf0 | ||
|
|
bb9fafa6cc | ||
|
|
f5fee4decf | ||
|
|
279826f6d6 | ||
|
|
56e11b57e3 | ||
|
|
6d65049221 | ||
|
|
65ee4e4f2a | ||
|
|
a1538c5610 | ||
|
|
e32e5c21d7 | ||
|
|
132cdad7c4 | ||
|
|
fa89a0ab4d | ||
|
|
ad093555a6 | ||
|
|
2fbccdd05b | ||
|
|
eb985a8af0 | ||
|
|
8f150d84ae | ||
|
|
74d8575097 | ||
|
|
71c3cf163e | ||
|
|
b95423285f | ||
|
|
24733315d7 | ||
|
|
fbc38d0c60 | ||
|
|
8b5c4aa591 | ||
|
|
c9aff4c47a | ||
|
|
8a8f35863c | ||
|
|
9a5d759230 | ||
|
|
94c3b1212e | ||
|
|
c129a3d3b8 | ||
|
|
6d935b6a4a | ||
|
|
8f903b6e3f | ||
|
|
78139957d2 | ||
|
|
ffffbedf41 | ||
|
|
fb6130e1e0 | ||
|
|
4c94f3ec38 | ||
|
|
d67425daf1 | ||
|
|
48065cc694 | ||
|
|
f35e16bd8d | ||
|
|
986c7cc31b | ||
|
|
078c90cabe | ||
|
|
30597252c7 | ||
|
|
d8b27ef8fe | ||
|
|
19197a490e | ||
|
|
317833aeff | ||
|
|
acf989f1be | ||
|
|
7ab710889c | ||
|
|
8ef87309a2 | ||
|
|
20fa90a137 | ||
|
|
fb355eb320 | ||
|
|
8aa0cc145c | ||
|
|
e276fc71c7 | ||
|
|
119c3e3b24 | ||
|
|
67adc56c73 | ||
|
|
97a771d1e2 | ||
|
|
c27279ce7a | ||
|
|
13c368a2db | ||
|
|
2f47e298d2 | ||
|
|
188ede2cd4 | ||
|
|
f23419fde6 | ||
|
|
c614f4b5de | ||
|
|
3266716584 | ||
|
|
8cc6df51f3 | ||
|
|
6b1ffe13a0 | ||
|
|
ce3daf254f | ||
|
|
6c5a75bf73 | ||
|
|
58492e2d83 | ||
|
|
a9f44aa259 | ||
|
|
b17d7fbbfd | ||
|
|
d78e77fb92 | ||
|
|
64fdb8d760 | ||
|
|
a377ec1dde | ||
|
|
87e9964091 | ||
|
|
60d8334fed | ||
|
|
71f5105a86 | ||
|
|
09a62efe88 | ||
|
|
6dbf4b5b60 | ||
|
|
5401bd367b | ||
|
|
f7def79764 | ||
|
|
cda909a609 | ||
|
|
6f61cadf9f | ||
|
|
1c616b1962 | ||
|
|
849343fb41 | ||
|
|
8810027d89 | ||
|
|
548ea8a9fb | ||
|
|
81b5cf65d6 | ||
|
|
dc9ae64646 | ||
|
|
829cb2baa3 | ||
|
|
7b301446fa | ||
|
|
4a297fa138 | ||
|
|
7811d9f2bc | ||
|
|
21ff81b758 | ||
|
|
485bbddd3e | ||
|
|
6dc80293a6 | ||
|
|
b649ad5c69 | ||
|
|
d782abb214 | ||
|
|
95f5becee1 | ||
|
|
cdb78cbdd3 | ||
|
|
694d809f33 | ||
|
|
df3c3c3357 | ||
|
|
99e770b05a | ||
|
|
340cb2b385 | ||
|
|
cdbd83a645 | ||
|
|
fab2a5a5d7 | ||
|
|
8da2f37181 | ||
|
|
c906a0c16e | ||
|
|
93618166b6 | ||
|
|
babfb3faa9 | ||
|
|
cedf215445 | ||
|
|
51a4907f89 | ||
|
|
6457162383 | ||
|
|
7f0e9e3a6a | ||
|
|
95cf508b2b | ||
|
|
4a565ffdb8 | ||
|
|
17f1779a48 | ||
|
|
a76cb0b008 | ||
|
|
9700bc3298 | ||
|
|
ce31dac24f | ||
|
|
a81b2e32e0 | ||
|
|
b713d5a1cc | ||
|
|
e11ba17248 | ||
|
|
3d9d4bd36f | ||
|
|
6a3e3c3a71 | ||
|
|
633c43a672 | ||
|
|
0833693372 | ||
|
|
77c07ba96e | ||
|
|
6847bb7924 | ||
|
|
f0deaf707d | ||
|
|
e113944027 | ||
|
|
1cf9131ae2 | ||
|
|
da142a8e97 | ||
|
|
6c81e3b95f | ||
|
|
a0089a2521 | ||
|
|
11768f6232 | ||
|
|
675c17737f | ||
|
|
735a93d000 | ||
|
|
67d2c2ed4a | ||
|
|
f931e15653 | ||
|
|
34169174a8 | ||
|
|
ebf33964c7 | ||
|
|
38a5e12d66 | ||
|
|
04ab218fa0 | ||
|
|
950c353f90 | ||
|
|
aff09b1108 | ||
|
|
6da691f874 | ||
|
|
22c99aa535 | ||
|
|
5fa209acfa | ||
|
|
d72879e109 | ||
|
|
337f3631ff | ||
|
|
b3993dc874 | ||
|
|
11c04dd6c4 | ||
|
|
b29e449d4a | ||
|
|
430f2f84fb | ||
|
|
52c6b5755b | ||
|
|
958bc63293 | ||
|
|
94ed0fe515 | ||
|
|
bb8233ceff | ||
|
|
6221bed190 | ||
|
|
1ffeb181e7 | ||
|
|
759ba1cbf4 | ||
|
|
12f2c41273 | ||
|
|
2174741376 | ||
|
|
31dd8fc5b1 | ||
|
|
77f4811779 | ||
|
|
7050a45134 | ||
|
|
3b64f1e102 | ||
|
|
6c4c79e2cc | ||
|
|
3975ebc21a | ||
|
|
ec95e5f97e | ||
|
|
72b1a4bc5c | ||
|
|
16447efca3 | ||
|
|
524d593c5c | ||
|
|
3b644474c4 | ||
|
|
42e6ced2b0 | ||
|
|
f018370628 | ||
|
|
c9a8bc1121 | ||
|
|
8c7cbb12dd | ||
|
|
b02f7775c5 | ||
|
|
f9a0e671b7 | ||
|
|
70fb22cad6 | ||
|
|
2ae00db6a9 | ||
|
|
f9577ab540 | ||
|
|
6a2786a5c4 | ||
|
|
924aa6fb29 | ||
|
|
e2cd44f9d8 | ||
|
|
017c4ae0aa | ||
|
|
7b2baad390 | ||
|
|
bc2d69f4f9 | ||
|
|
e913a71fad | ||
|
|
7406dda074 | ||
|
|
0b4df3d414 | ||
|
|
7d38916d63 | ||
|
|
79d1abe573 | ||
|
|
9563052094 | ||
|
|
f881c19bb6 | ||
|
|
8d7b5f82c4 | ||
|
|
7554406c61 | ||
|
|
cf17050170 | ||
|
|
3857a67701 | ||
|
|
10665c6fc9 | ||
|
|
e0a09f4755 | ||
|
|
31c6a55747 | ||
|
|
8332a70d19 | ||
|
|
7fe2338acd | ||
|
|
43d4dbc07a | ||
|
|
f0cf4579d2 | ||
|
|
68ba37f139 | ||
|
|
bf73633cda | ||
|
|
55f8828ba1 | ||
|
|
0e1307dccf | ||
|
|
4471b75912 | ||
|
|
75c6204337 | ||
|
|
1b7171ac9e | ||
|
|
5193d6b4a8 | ||
|
|
6a834b6262 | ||
|
|
083d3cbb65 | ||
|
|
e68411b71e | ||
|
|
664774576c | ||
|
|
37e97084f9 | ||
|
|
de4d8b7dfa | ||
|
|
7f97108686 | ||
|
|
71f069cf95 | ||
|
|
3dbe732cb5 | ||
|
|
e5aea4423b | ||
|
|
100f05260e | ||
|
|
02f9329747 | ||
|
|
b6abd7600c | ||
|
|
2e7093e67f | ||
|
|
3b3a272d27 | ||
|
|
36115a7fa3 | ||
|
|
4d9d54e2c7 | ||
|
|
88aec95628 | ||
|
|
e30401489d | ||
|
|
58bc4b14a2 | ||
|
|
2824c28e08 | ||
|
|
d7cbb95d9c | ||
|
|
e771ec1169 | ||
|
|
9e5374e725 | ||
|
|
4569a09d54 | ||
|
|
25d3ad7522 | ||
|
|
77e18724db | ||
|
|
12d1771bb3 | ||
|
|
a78aa22399 | ||
|
|
05a91893bf | ||
|
|
8d420ec3f7 | ||
|
|
838a766d12 | ||
|
|
50d79e4d3e | ||
|
|
4d2d450f6e | ||
|
|
fdc46fb0b1 | ||
|
|
92ac9b5a0e | ||
|
|
857a9df70f | ||
|
|
969f4f28fa | ||
|
|
58aa45c50a | ||
|
|
5715f4bab4 | ||
|
|
c8502c78f5 | ||
|
|
909de5c94a | ||
|
|
2eaeb83ec3 | ||
|
|
03b9c2a3a3 | ||
|
|
59b98727ec | ||
|
|
5851f96524 | ||
|
|
08be3f061e | ||
|
|
5906aaba19 | ||
|
|
4b6f180d0c | ||
|
|
7f22f187f8 | ||
|
|
fa3a64e352 | ||
|
|
82f2cf9124 | ||
|
|
276693cf0e | ||
|
|
0197c019cc | ||
|
|
9576a81787 | ||
|
|
ff4a1c0b4f | ||
|
|
7dd28b1fd9 | ||
|
|
b754557418 | ||
|
|
f305c0d791 | ||
|
|
3fdaa2e903 | ||
|
|
964c74fb46 | ||
|
|
f14988ff80 | ||
|
|
f1adbfdbff | ||
|
|
072bf992b0 | ||
|
|
2d0d09e178 | ||
|
|
564b0d6827 | ||
|
|
187415430f | ||
|
|
afac2fb46a | ||
|
|
20fd433f75 | ||
|
|
1e3824057b | ||
|
|
5edae84a9e | ||
|
|
9432671887 | ||
|
|
8fda0f87ab | ||
|
|
08bc8637c8 | ||
|
|
9645f397ef | ||
|
|
ed9f716361 | ||
|
|
9986b65326 | ||
|
|
94dab9ddc4 | ||
|
|
81f246ed60 | ||
|
|
30ed50eb27 | ||
|
|
4325401fe7 | ||
|
|
65af5c13f1 | ||
|
|
9674fd12b2 | ||
|
|
2377902a0b | ||
|
|
1dbde0b085 | ||
|
|
5920563bbd | ||
|
|
23201c27f0 | ||
|
|
d4c7131f8f | ||
|
|
d2b189874b | ||
|
|
98a38eb290 | ||
|
|
aa729229e2 | ||
|
|
afbc1b0401 | ||
|
|
3305be9589 | ||
|
|
36772aac89 | ||
|
|
7755d6cac2 | ||
|
|
6f82073d4b | ||
|
|
2a3f09a2f0 | ||
|
|
6392e6629f | ||
|
|
c25ed7f7bc | ||
|
|
918247d2cc | ||
|
|
0c260ef804 | ||
|
|
2a06a174e8 | ||
|
|
54e8a014bc | ||
|
|
5b67b580f2 | ||
|
|
6a67183ed7 | ||
|
|
a38befdaa1 | ||
|
|
0312cdf677 | ||
|
|
991ffbbdfc | ||
|
|
bbd29d9dc1 | ||
|
|
28953e03a0 | ||
|
|
37489ec2e9 | ||
|
|
636ab874eb | ||
|
|
90d16c2377 | ||
|
|
5d24dda28a | ||
|
|
dec5109e31 | ||
|
|
cc8690381c | ||
|
|
f5f95e3692 | ||
|
|
809d5b1fe2 | ||
|
|
38b4365ab3 | ||
|
|
d865300fdb | ||
|
|
e2677cdc8a | ||
|
|
ea00134776 | ||
|
|
ad3cd47c25 | ||
|
|
a1dcf3386b | ||
|
|
e7ecceb0c2 | ||
|
|
50c40eb80c | ||
|
|
398ceb0a92 | ||
|
|
b7be630924 | ||
|
|
f557841e54 | ||
|
|
9fc24634a2 | ||
|
|
0617a283a0 | ||
|
|
f616e30a38 | ||
|
|
50b197f329 | ||
|
|
6fd0330b80 | ||
|
|
8127b09d12 | ||
|
|
09ab2bb5c0 | ||
|
|
54ac4e73e7 | ||
|
|
d4ad7f80e0 | ||
|
|
623e21d1c0 | ||
|
|
0c88c43c67 | ||
|
|
c6d8bcb01b | ||
|
|
5285e6101f | ||
|
|
2fb69db685 | ||
|
|
730597b77e | ||
|
|
d488d9804d | ||
|
|
f98bc42cbb | ||
|
|
d7b9f64c5a | ||
|
|
785291af62 | ||
|
|
4f05482e00 | ||
|
|
3c3f85e623 | ||
|
|
40bb81142b | ||
|
|
5563f1529b | ||
|
|
a95b26182a | ||
|
|
934e37d781 | ||
|
|
40bad7783f | ||
|
|
44696d5fb9 | ||
|
|
9d268de5a0 | ||
|
|
46e8fd7065 | ||
|
|
ab0c9b4118 | ||
|
|
4e7610a44d | ||
|
|
37720765fc | ||
|
|
09e64e5991 | ||
|
|
e017d04a16 | ||
|
|
b6efde13eb | ||
|
|
f774172927 | ||
|
|
9459665c96 | ||
|
|
7fb4eaec60 | ||
|
|
211cda054e | ||
|
|
5f75564ff5 | ||
|
|
6b5569d5ed | ||
|
|
e20edaf41e | ||
|
|
d934a28caf | ||
|
|
e002b69ffa | ||
|
|
bdad67c3ef | ||
|
|
92864ba0f7 | ||
|
|
ba45b1366a | ||
|
|
d06620c74d | ||
|
|
4f3f76addd | ||
|
|
71b7e07b02 | ||
|
|
27f652ae8e | ||
|
|
5c8d82aed0 | ||
|
|
c994130005 | ||
|
|
ccd255f323 | ||
|
|
2b05d39067 | ||
|
|
de65503177 | ||
|
|
5a3c6553fc | ||
|
|
7c4ca21578 | ||
|
|
efcc167c35 | ||
|
|
1f8e56a210 | ||
|
|
fa8d6f08e2 | ||
|
|
900ac005dd | ||
|
|
a42c72b2e0 | ||
|
|
a82bd23f8f | ||
|
|
ea24b3795c | ||
|
|
95f568b857 | ||
|
|
708cd7ef17 | ||
|
|
ed7261ca01 | ||
|
|
8a27162d98 | ||
|
|
2e0e43cd76 | ||
|
|
ba2866645e | ||
|
|
fd2ee6034b | ||
|
|
86241dfd98 | ||
|
|
1a28f3a391 | ||
|
|
35344c163a | ||
|
|
526ba2df0c | ||
|
|
db15bc6372 | ||
|
|
c83b7019f5 | ||
|
|
08e2a1047b | ||
|
|
69d816d5ab | ||
|
|
ea2d2c9db1 | ||
|
|
c7ef8a7e4d | ||
|
|
9bda5cf092 | ||
|
|
815db033cb | ||
|
|
501e1a406d | ||
|
|
6e54814b6d | ||
|
|
df2407ad3f | ||
|
|
d0c6a824c8 | ||
|
|
57f3743be8 | ||
|
|
ef71cb478f | ||
|
|
9a5c0f5a25 | ||
|
|
0e2c71cd6f | ||
|
|
0b3ab31248 | ||
|
|
49f586af39 | ||
|
|
487a6ebee4 | ||
|
|
bee9490129 | ||
|
|
8afba0b56c | ||
|
|
16fa3403a4 | ||
|
|
bcb89ee908 | ||
|
|
37f03b4d01 | ||
|
|
bc144275b4 | ||
|
|
7086e4f974 | ||
|
|
4d111436aa | ||
|
|
1583486546 | ||
|
|
10b4c5db43 | ||
|
|
5a54c96203 | ||
|
|
4a5b82333b | ||
|
|
e3934ee69c | ||
|
|
24daa9e3dc | ||
|
|
d9b422cc54 | ||
|
|
d62fb53472 | ||
|
|
00e52095d6 | ||
|
|
9c6d31d70e | ||
|
|
a734b96560 | ||
|
|
8f3fe7d4bd | ||
|
|
5f950813c4 | ||
|
|
920f53853b | ||
|
|
aa88a0563b |
7
.gitignore
vendored
@@ -4,9 +4,16 @@
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
kustomize
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# We use sed -i.bak when doing in-line replace, because it works better cross-platform
|
||||
.bak
|
||||
|
||||
# macOS
|
||||
*.DS_store
|
||||
|
||||
30
.golangci.yml
Normal file
@@ -0,0 +1,30 @@
|
||||
run:
|
||||
deadline: 5m
|
||||
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
- dupl
|
||||
- goconst
|
||||
- gocyclo
|
||||
- gofmt
|
||||
- golint
|
||||
- govet
|
||||
- ineffassign
|
||||
- interfacer
|
||||
- lll
|
||||
- misspell
|
||||
- nakedret
|
||||
- structcheck
|
||||
- unparam
|
||||
- varcheck
|
||||
|
||||
linters-settings:
|
||||
dupl:
|
||||
threshold: 400
|
||||
lll:
|
||||
line-length: 170
|
||||
gocyclo:
|
||||
min-complexity: 15
|
||||
golint:
|
||||
min-confidence: 0.85
|
||||
18
.travis.yml
@@ -1,16 +1,24 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
|
||||
# go_import_path: k8s.io/kubectl
|
||||
go_import_path: sigs.k8s.io/kustomize
|
||||
|
||||
# Maybe, maybe not.
|
||||
# sudo: false
|
||||
|
||||
# Only clone the most recent commit.
|
||||
git:
|
||||
depth: 1
|
||||
|
||||
env:
|
||||
- GOLANGCI_RELEASE="v1.10.2"
|
||||
|
||||
before_install:
|
||||
- source ./bin/consider-early-travis-exit.sh
|
||||
- sudo apt-get install tree
|
||||
- go get -u github.com/golang/lint/golint
|
||||
- go get -u golang.org/x/tools/cmd/goimports
|
||||
- go get -u github.com/onsi/ginkgo/ginkgo
|
||||
- curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $GOPATH/bin ${GOLANGCI_RELEASE}
|
||||
- go get -u github.com/monopole/mdrip
|
||||
|
||||
# Install must be set to prevent default `go get` to run.
|
||||
|
||||
@@ -1,36 +1,22 @@
|
||||
# Contributing guidelines
|
||||
# Contributing Guidelines
|
||||
|
||||
[Contributor License Agreement]: https://git.k8s.io/community/CLA.md
|
||||
[github workflow guide]: https://github.com/kubernetes/community/blob/master/contributors/guide/github-workflow.md
|
||||
[CNCF code of conduct]: https://github.com/cncf/foundation/blob/master/code-of-conduct.md
|
||||
Welcome to Kubernetes. We are excited about the prospect of you joining our [community](https://github.com/kubernetes/community)! The Kubernetes community abides by the CNCF [code of conduct](code-of-conduct.md). Here is an excerpt:
|
||||
|
||||
## Contributing a Patch
|
||||
_As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities._
|
||||
|
||||
1. Kubernetes projects require contributors to sign the
|
||||
[Contributor License Agreement] before pull requests
|
||||
can be considered.
|
||||
1. Submit an issue describing your proposed change to
|
||||
the repo in question.
|
||||
1. The [repo owners](OWNERS) will respond to your issue
|
||||
promptly.
|
||||
1. Fork the repo, develop and test your code.
|
||||
See the [github workflow guide].
|
||||
1. For _new features_, provide a markdown-based demo following
|
||||
the pattern established in the [demos](demos) directory.
|
||||
Run `bin/pre-commit.sh` to test your demo.
|
||||
1. Submit a pull request.
|
||||
## Getting Started
|
||||
|
||||
## Community, discussion, contribution, and support
|
||||
We have full documentation on how to get started contributing here:
|
||||
|
||||
Learn how to engage with the Kubernetes community on
|
||||
the [community page](http://kubernetes.io/community/).
|
||||
- [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests
|
||||
- [Kubernetes Contributor Guide](http://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](http://git.k8s.io/community/contributors/guide#contributing)
|
||||
- [Contributor Cheat Sheet](https://git.k8s.io/community/contributors/guide/contributor-cheatsheet.md) - Common resources for existing developers
|
||||
|
||||
You can reach the maintainers of this project at:
|
||||
## Mentorship
|
||||
|
||||
- [Slack](http://slack.k8s.io/)
|
||||
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-kustomize)
|
||||
- [Mentoring Initiatives](https://git.k8s.io/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers!
|
||||
|
||||
## Code of conduct
|
||||
## Contact Information
|
||||
|
||||
Participation in the Kubernetes community is governed
|
||||
by the [CNCF code of conduct].
|
||||
- [Slack channel](https://kubernetes.slack.com/messages/sig-cli)
|
||||
- [Mailing list](https://groups.google.com/forum/#!forum/kubernetes-sig-cli)
|
||||
|
||||
273
Gopkg.lock
generated
@@ -2,146 +2,387 @@
|
||||
|
||||
|
||||
[[projects]]
|
||||
digest = "1:d8ebbd207f3d3266d4423ce4860c9f3794956306ded6c7ba312ecc69cdfbf04c"
|
||||
name = "github.com/PuerkitoBio/purell"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:8098cd40cd09879efbf12e33bcd51ead4a66006ac802cd563a66c4f3373b9727"
|
||||
name = "github.com/PuerkitoBio/urlesc"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "de5bf2ad457846296e2031421a34e2568e304e35"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:a2c1d0e43bd3baaa071d1b9ed72c27d78169b2b269f71c105ac4ba34b1be4a39"
|
||||
name = "github.com/davecgh/go-spew"
|
||||
packages = ["spew"]
|
||||
pruneopts = "NUT"
|
||||
revision = "346938d642f2ec3594ed81d874461961cd0faa76"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:f8e6f07329067bc182633dcb19a3df53ce5d454b551e1b5a1cac2163748648d9"
|
||||
name = "github.com/emicklei/go-restful"
|
||||
packages = [
|
||||
".",
|
||||
"log",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "3658237ded108b4134956c1b3050349d93e7b895"
|
||||
version = "v2.7.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ad32dc29f37281bacb5dcedff17c9461dc1739dc8a5f63a71ab491c6e92edf8d"
|
||||
name = "github.com/evanphx/json-patch"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "afac545df32f2287a079e2dfb7ba2745a643747e"
|
||||
version = "v3.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:81466b4218bf6adddac2572a30ac733a9255919bc2f470b4827a317bd4ee1756"
|
||||
name = "github.com/ghodss/yaml"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "0ca9ea5df5451ffdf184b4428c902747c2c11cd7"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:260f7ebefc63024c8dfe2c9f1a2935a89fa4213637a1f522f592f80c001cc441"
|
||||
name = "github.com/go-openapi/jsonpointer"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "3a0015ad55fa9873f41605d3e8f28cd279c32ab2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:98abd61947ff5c7c6fcfec5473d02a4821ed3a2dd99a4fbfdb7925b0dd745546"
|
||||
name = "github.com/go-openapi/jsonreference"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "3fb327e6747da3043567ee86abd02bb6376b6be2"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:e95b560c49fb849a61957a5fb3346ce23b3f67426e00e01179e5396cabc9a12c"
|
||||
name = "github.com/go-openapi/spec"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "bcff419492eeeb01f76e77d2ebc714dc97b607f5"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:a610c604eb06f0be4b0fc667388b7a221155d77d7f9089f70ac142a4a9daf014"
|
||||
name = "github.com/go-openapi/swag"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "811b1089cde9dad18d4d0c2d09fbdbf28dbd27a5"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:1b3dd24f14a5280710fc7a3aa2480b6e4d20fdfc905841de9a3aa2aa2f1d4ee9"
|
||||
name = "github.com/gogo/protobuf"
|
||||
packages = ["proto","sortkeys"]
|
||||
packages = [
|
||||
"proto",
|
||||
"sortkeys",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "1adfc126b41513cc696b209667c8656ea7aac67c"
|
||||
version = "v1.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:e2b86e41f3d669fc36b50d31d32d22c8ac656c75aa5ea89717ce7177e134ff2a"
|
||||
name = "github.com/golang/glog"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "23def4e6c14b4da8ac2ed8007337bc5eb5007998"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:03e14cff610a8a58b774e36bd337fa979482be86aab01be81fb8bbd6d0f07fc8"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["proto","ptypes","ptypes/any","ptypes/duration","ptypes/timestamp"]
|
||||
packages = [
|
||||
"proto",
|
||||
"ptypes",
|
||||
"ptypes/any",
|
||||
"ptypes/duration",
|
||||
"ptypes/timestamp",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "b4deda0973fb4c70b50d226b1af49f3da59f5265"
|
||||
version = "v1.1.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:52c5834e2bebac9030c97cc0798ac11c3aa8a39f098aeb419f142533da6cd3cc"
|
||||
name = "github.com/google/gofuzz"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "24818f796faf91cd76ec7bddd72458fbced7a6c1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:3d7c1446fc5c710351b246c0dc6700fae843ca27f5294d0bd9f68bab2a810c44"
|
||||
name = "github.com/googleapis/gnostic"
|
||||
packages = ["OpenAPIv2","compiler","extensions"]
|
||||
packages = [
|
||||
"OpenAPIv2",
|
||||
"compiler",
|
||||
"extensions",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "ee43cbb60db7bd22502942cccbc39059117352ab"
|
||||
version = "v0.1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:406338ad39ab2e37b7f4452906442a3dbf0eb3379dd1f06aafb5c07e769a5fbb"
|
||||
name = "github.com/inconshreveable/mousetrap"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "76626ae9c91c4f2a10f34cad8ce83ea42c93bb75"
|
||||
version = "v1.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:42c47ace7ccb114261ef7e0d418d274921514ab50a3bf6bdb9e51c3dde8ce13d"
|
||||
name = "github.com/json-iterator/go"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "ca39e5af3ece67bbcda3d0f4f56a8e24d9f2dad4"
|
||||
version = "1.1.3"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:ada518b8c338e10e0afa443d84671476d3bd1d926e13713938088e8ddbee1a3e"
|
||||
name = "github.com/mailru/easyjson"
|
||||
packages = [
|
||||
"buffer",
|
||||
"jlexer",
|
||||
"jwriter",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "3fdea8d05856a0c8df22ed4bc71b3219245e4485"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2f42fa12d6911c7b7659738758631bec870b7e9b4c6be5444f963cdcfccc191f"
|
||||
name = "github.com/modern-go/concurrent"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "bacd9c7ef1dd9b15be4a9909b8ac7a4e313eec94"
|
||||
version = "1.0.3"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:314a5881fab303a80d6d2e35a77000f2224bb50f09ef63a9aa4c1f9eaef985d8"
|
||||
name = "github.com/modern-go/reflect2"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "1df9eeb2bb81f327b96228865c5687bc2194af3f"
|
||||
version = "1.0.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:5cf3f025cbee5951a4ee961de067c8a89fc95a5adabead774f82822efabab121"
|
||||
name = "github.com/pkg/errors"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "645ef00459ed84a119197bfb8d8205042c6df63d"
|
||||
version = "v0.8.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:0f156dbd01b40676bdcbc64e51535c09b50f83c9cca5faef3090f82f18bda3c2"
|
||||
name = "github.com/spf13/cobra"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "a1f051bc3eba734da4772d60e2d677f47cf93ef4"
|
||||
version = "v0.0.2"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:15e5c398fbd9d2c439b635a08ac161b13d04f0c2aa587fe256b65dc0c3efe8b7"
|
||||
name = "github.com/spf13/pflag"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "583c0c0531f06d5278b7d917446061adc344b5cd"
|
||||
version = "v1.0.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:d1a6ebe75268a41b6fbb1d43947cf8688d8580423b7484fa5ae608beef6df24d"
|
||||
name = "golang.org/x/net"
|
||||
packages = ["http/httpguts","http2","http2/hpack","idna"]
|
||||
revision = "2491c5de3490fced2f6cff376127c667efeed857"
|
||||
packages = [
|
||||
"http2",
|
||||
"http2/hpack",
|
||||
"idna",
|
||||
"lex/httplex",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "1c05540f6879653db88113bc4a2b70aec4bd491f"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:e33513a825fcd765e97b5de639a2f7547542d1a8245df0cef18e1fd390b778a9"
|
||||
name = "golang.org/x/text"
|
||||
packages = ["collate","collate/build","internal/colltab","internal/gen","internal/tag","internal/triegen","internal/ucd","language","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"]
|
||||
packages = [
|
||||
"collate",
|
||||
"collate/build",
|
||||
"internal/colltab",
|
||||
"internal/gen",
|
||||
"internal/tag",
|
||||
"internal/triegen",
|
||||
"internal/ucd",
|
||||
"language",
|
||||
"secure/bidirule",
|
||||
"transform",
|
||||
"unicode/bidi",
|
||||
"unicode/cldr",
|
||||
"unicode/norm",
|
||||
"unicode/rangetable",
|
||||
"width",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0"
|
||||
version = "v0.3.0"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:2d1fbdc6777e5408cabeb02bf336305e724b925ff4546ded0fa8715a7267922a"
|
||||
name = "gopkg.in/inf.v0"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "d2d2541c53f18d2a059457998ce2876cc8e67cbf"
|
||||
version = "v0.9.1"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:7c95b35057a0ff2e19f707173cc1a947fa43a6eb5c4d300d196ece0334046082"
|
||||
name = "gopkg.in/yaml.v2"
|
||||
packages = ["."]
|
||||
pruneopts = "NUT"
|
||||
revision = "5420a8b6744d3b0345ab293f6fcba19c978f1183"
|
||||
version = "v2.2.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:d895c7c24a0dd1ed2ecd061fd88dfea9e1e84d6f280ed859942a2d1aabee10ec"
|
||||
name = "k8s.io/api"
|
||||
packages = ["admissionregistration/v1alpha1","admissionregistration/v1beta1","apps/v1","apps/v1beta1","apps/v1beta2","authentication/v1","authentication/v1beta1","authorization/v1","authorization/v1beta1","autoscaling/v1","autoscaling/v2beta1","batch/v1","batch/v1beta1","batch/v2alpha1","certificates/v1beta1","core/v1","events/v1beta1","extensions/v1beta1","networking/v1","policy/v1beta1","rbac/v1","rbac/v1alpha1","rbac/v1beta1","scheduling/v1alpha1","settings/v1alpha1","storage/v1","storage/v1alpha1","storage/v1beta1"]
|
||||
packages = [
|
||||
"admissionregistration/v1alpha1",
|
||||
"admissionregistration/v1beta1",
|
||||
"apps/v1",
|
||||
"apps/v1beta1",
|
||||
"apps/v1beta2",
|
||||
"authentication/v1",
|
||||
"authentication/v1beta1",
|
||||
"authorization/v1",
|
||||
"authorization/v1beta1",
|
||||
"autoscaling/v1",
|
||||
"autoscaling/v2beta1",
|
||||
"batch/v1",
|
||||
"batch/v1beta1",
|
||||
"batch/v2alpha1",
|
||||
"certificates/v1beta1",
|
||||
"core/v1",
|
||||
"events/v1beta1",
|
||||
"extensions/v1beta1",
|
||||
"networking/v1",
|
||||
"policy/v1beta1",
|
||||
"rbac/v1",
|
||||
"rbac/v1alpha1",
|
||||
"rbac/v1beta1",
|
||||
"scheduling/v1alpha1",
|
||||
"settings/v1alpha1",
|
||||
"storage/v1",
|
||||
"storage/v1alpha1",
|
||||
"storage/v1beta1",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "53d615ae3f440f957cb9989d989d597f047262d9"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:dff69dd9d9fc681ae077ce5a409aca3c24894d09102ab0395ca7972f6ec01811"
|
||||
name = "k8s.io/apimachinery"
|
||||
packages = ["pkg/api/resource","pkg/apis/meta/v1","pkg/apis/meta/v1/unstructured","pkg/conversion","pkg/conversion/queryparams","pkg/fields","pkg/labels","pkg/runtime","pkg/runtime/schema","pkg/runtime/serializer","pkg/runtime/serializer/json","pkg/runtime/serializer/protobuf","pkg/runtime/serializer/recognizer","pkg/runtime/serializer/versioning","pkg/selection","pkg/types","pkg/util/errors","pkg/util/framer","pkg/util/intstr","pkg/util/json","pkg/util/mergepatch","pkg/util/net","pkg/util/runtime","pkg/util/sets","pkg/util/strategicpatch","pkg/util/validation","pkg/util/validation/field","pkg/util/wait","pkg/util/yaml","pkg/watch","third_party/forked/golang/json","third_party/forked/golang/reflect"]
|
||||
packages = [
|
||||
"pkg/api/equality",
|
||||
"pkg/api/meta",
|
||||
"pkg/api/resource",
|
||||
"pkg/api/validation",
|
||||
"pkg/apis/meta/v1",
|
||||
"pkg/apis/meta/v1/unstructured",
|
||||
"pkg/apis/meta/v1/validation",
|
||||
"pkg/apis/meta/v1beta1",
|
||||
"pkg/conversion",
|
||||
"pkg/conversion/queryparams",
|
||||
"pkg/fields",
|
||||
"pkg/labels",
|
||||
"pkg/runtime",
|
||||
"pkg/runtime/schema",
|
||||
"pkg/runtime/serializer",
|
||||
"pkg/runtime/serializer/json",
|
||||
"pkg/runtime/serializer/protobuf",
|
||||
"pkg/runtime/serializer/recognizer",
|
||||
"pkg/runtime/serializer/versioning",
|
||||
"pkg/selection",
|
||||
"pkg/types",
|
||||
"pkg/util/errors",
|
||||
"pkg/util/framer",
|
||||
"pkg/util/intstr",
|
||||
"pkg/util/json",
|
||||
"pkg/util/mergepatch",
|
||||
"pkg/util/net",
|
||||
"pkg/util/runtime",
|
||||
"pkg/util/sets",
|
||||
"pkg/util/strategicpatch",
|
||||
"pkg/util/validation",
|
||||
"pkg/util/validation/field",
|
||||
"pkg/util/wait",
|
||||
"pkg/util/yaml",
|
||||
"pkg/watch",
|
||||
"third_party/forked/golang/json",
|
||||
"third_party/forked/golang/reflect",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "13b73596e4b63e03203e86f6d9c7bcc1b937c62f"
|
||||
|
||||
[[projects]]
|
||||
digest = "1:ae9ced9ef7b8eb2794a4f80bc3af9d2bc38ec7d60337367bad9a655c1d641458"
|
||||
name = "k8s.io/client-go"
|
||||
packages = ["kubernetes/scheme"]
|
||||
pruneopts = "NUT"
|
||||
revision = "23781f4d6632d88e869066eaebb743857aa1ef9b"
|
||||
version = "v7.0.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
digest = "1:f4fb3421360af5c51070bfe0c1c7467f8809fa70e278e129f068f5106b5c8a65"
|
||||
name = "k8s.io/kube-openapi"
|
||||
packages = ["pkg/util/proto"]
|
||||
packages = [
|
||||
"pkg/common",
|
||||
"pkg/util/proto",
|
||||
]
|
||||
pruneopts = "NUT"
|
||||
revision = "b3f03f55328800731ce03a164b80973014ecd455"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "k8s.io/utils"
|
||||
packages = ["exec"]
|
||||
revision = "258e2a2fa64568210fbd6267cf1d8fd87c3cb86e"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "6e36daa1798b0dae7f45160f9275ca6bbe6c5667de7cd808d0057cbaf19fc55e"
|
||||
input-imports = [
|
||||
"github.com/evanphx/json-patch",
|
||||
"github.com/ghodss/yaml",
|
||||
"github.com/pkg/errors",
|
||||
"github.com/spf13/cobra",
|
||||
"gopkg.in/yaml.v2",
|
||||
"k8s.io/api/core/v1",
|
||||
"k8s.io/apimachinery/pkg/api/validation",
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1",
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured",
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/validation",
|
||||
"k8s.io/apimachinery/pkg/runtime",
|
||||
"k8s.io/apimachinery/pkg/runtime/schema",
|
||||
"k8s.io/apimachinery/pkg/util/mergepatch",
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch",
|
||||
"k8s.io/apimachinery/pkg/util/validation",
|
||||
"k8s.io/apimachinery/pkg/util/validation/field",
|
||||
"k8s.io/apimachinery/pkg/util/yaml",
|
||||
"k8s.io/client-go/kubernetes/scheme",
|
||||
"k8s.io/kube-openapi/pkg/common",
|
||||
]
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
||||
16
Gopkg.toml
@@ -1,4 +1,3 @@
|
||||
|
||||
# Gopkg.toml example
|
||||
#
|
||||
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
|
||||
@@ -20,6 +19,11 @@
|
||||
# name = "github.com/x/y"
|
||||
# version = "2.4.0"
|
||||
|
||||
# prune out unused content from vendor
|
||||
[prune]
|
||||
go-tests = true
|
||||
non-go = true
|
||||
unused-packages = true
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/evanphx/json-patch"
|
||||
@@ -29,10 +33,6 @@
|
||||
name = "github.com/ghodss/yaml"
|
||||
version = "1.0.0"
|
||||
|
||||
[[constraint]]
|
||||
branch = "master"
|
||||
name = "github.com/golang/glog"
|
||||
|
||||
[[constraint]]
|
||||
name = "github.com/spf13/cobra"
|
||||
version = "0.0.2"
|
||||
@@ -49,6 +49,10 @@
|
||||
name = "k8s.io/client-go"
|
||||
version = "7.0.0"
|
||||
|
||||
[[constraint]]
|
||||
[[override]]
|
||||
branch = "master"
|
||||
name = "k8s.io/utils"
|
||||
|
||||
[[override]]
|
||||
branch = "master"
|
||||
name = "github.com/go-openapi/spec"
|
||||
|
||||
180
README.md
@@ -1,71 +1,155 @@
|
||||
# kustomize
|
||||
|
||||
[applied]: docs/glossary.md#apply
|
||||
[base]: docs/glossary.md#base
|
||||
[declarative configuration]: docs/glossary.md#declarative-application-management
|
||||
[demo]: demos/README.md
|
||||
[demos]: demos/README.md
|
||||
[imageBase]: docs/base.jpg
|
||||
[imageOverlay]: docs/overlay.jpg
|
||||
[kubernetes style]: docs/glossary.md#kubernetes-style-object
|
||||
[KEP]: https://github.com/kubernetes/community/blob/master/keps/sig-cli/0008-kustomize.md
|
||||
[kustomization]: docs/glossary.md#kustomization
|
||||
[overlay]: docs/glossary.md#overlay
|
||||
[resources]: docs/glossary.md#resource
|
||||
[sig-cli]: https://github.com/kubernetes/community/blob/master/sig-cli/README.md
|
||||
[workflows]: docs/workflows.md
|
||||
`kustomize` lets you customize raw, template-free YAML
|
||||
files for multiple purposes, leaving the original YAML
|
||||
untouched and usable as is.
|
||||
|
||||
`kustomize` targets kubernetes; it understands and can
|
||||
patch [kubernetes style] API objects. It's like
|
||||
[`make`], in that what it does is declared in a file,
|
||||
and it's like [`sed`], in that it emits editted text.
|
||||
|
||||
`kustomize` is a command line tool supporting
|
||||
template-free customization of YAML (or JSON) objects
|
||||
that conform to the [kubernetes style]. If your
|
||||
objects have a `kind` and a `metadata` field,
|
||||
`kustomize` can patch them to support configuration
|
||||
sharing and re-use.
|
||||
|
||||
For more details, try a [demo].
|
||||
This tool is sponsored by [sig-cli] ([KEP]).
|
||||
|
||||
[](https://travis-ci.org/kubernetes-sigs/kustomize)
|
||||
[](https://goreportcard.com/report/github.com/kubernetes-sigs/kustomize)
|
||||
|
||||
|
||||
## Installation
|
||||
|
||||
This assumes [Go](https://golang.org/) (v1.10.1 or higher)
|
||||
is installed and your `PATH` contains `$GOPATH/bin`:
|
||||
|
||||
<!-- @installkustomize @test -->
|
||||
```
|
||||
go get github.com/kubernetes-sigs/kustomize
|
||||
```
|
||||
|
||||
**Installation**: Download a binary from the [release
|
||||
page], or see these [install] notes. Then try one of
|
||||
the tested [examples].
|
||||
|
||||
## Usage
|
||||
|
||||
#### 1) Make a base
|
||||
|
||||
A [base] configuration is a [kustomization] file listing a set of
|
||||
k8s [resources] - deployments, services, configmaps,
|
||||
secrets that serve some common purpose.
|
||||
### 1) Make a [kustomization] file
|
||||
|
||||
In some directory containing your YAML [resource]
|
||||
files (deployments, services, configmaps, etc.), create a
|
||||
[kustomization] file.
|
||||
|
||||
This file should declare those resources, and any
|
||||
customization to apply to them, e.g. _add a common
|
||||
label_.
|
||||
|
||||
![base image][imageBase]
|
||||
|
||||
#### 2) Customize it with overlays
|
||||
File structure:
|
||||
|
||||
An [overlay] customizes your base along different dimensions
|
||||
for different purposes or different teams, e.g. for
|
||||
_development, staging and production_.
|
||||
> ```
|
||||
> ~/someApp
|
||||
> ├── deployment.yaml
|
||||
> ├── kustomization.yaml
|
||||
> └── service.yaml
|
||||
> ```
|
||||
|
||||
The resources in this directory could be a fork of
|
||||
someone else's configuration. If so, you can easily
|
||||
rebase from the source material to capture
|
||||
improvements, because you don't modify the resources
|
||||
directly.
|
||||
|
||||
Generate customized YAML with:
|
||||
|
||||
```
|
||||
kustomize build ~/someApp
|
||||
```
|
||||
|
||||
The YAML can be directly [applied] to a cluster:
|
||||
|
||||
> ```
|
||||
> kustomize build ~/someApp | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
|
||||
### 2) Create [variants] using [overlays]
|
||||
|
||||
Manage traditional [variants] of a configuration - like
|
||||
_development_, _staging_ and _production_ - using
|
||||
[overlays] that modify a common [base].
|
||||
|
||||
![overlay image][imageOverlay]
|
||||
|
||||
#### 3) Run kustomize
|
||||
File structure:
|
||||
> ```
|
||||
> ~/someApp
|
||||
> ├── base
|
||||
> │ ├── deployment.yaml
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── service.yaml
|
||||
> └── overlays
|
||||
> ├── development
|
||||
> │ ├── cpu_count.yaml
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── replica_count.yaml
|
||||
> └── production
|
||||
> ├── cpu_count.yaml
|
||||
> ├── kustomization.yaml
|
||||
> └── replica_count.yaml
|
||||
> ```
|
||||
|
||||
Run `kustomize` on your overlay. The result
|
||||
is printed to `stdout` as a set of complete
|
||||
resources, ready to be [applied] to a cluster.
|
||||
See the [demos].
|
||||
Take the work from step (1) above, move it into a
|
||||
`someApp` subdirectory called `base`, then
|
||||
place overlays in a sibling directory.
|
||||
|
||||
An overlay is just another kustomization, refering to
|
||||
the base, and referring to patches to apply to that
|
||||
base.
|
||||
|
||||
## About
|
||||
This arrangement makes it easy to manage your
|
||||
configuration with `git`. The base could have files
|
||||
from an upstream repository managed by someone else.
|
||||
The overlays could be in a repository you own.
|
||||
Arranging the repo clones as siblings on disk avoids
|
||||
the need for git submodules (though that works fine, if
|
||||
you are a submodule fan).
|
||||
|
||||
This project sponsored by [sig-cli] ([KEP]).
|
||||
Generate YAML with
|
||||
|
||||
```sh
|
||||
kustomize build ~/someApp/overlays/production
|
||||
```
|
||||
|
||||
The YAML can be directly [applied] to a cluster:
|
||||
|
||||
> ```sh
|
||||
> kustomize build ~/someApp/overlays/production | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
## Community, discussion, contribution, and support
|
||||
|
||||
Learn how to engage with the Kubernetes community on the [community page].
|
||||
|
||||
You can reach the maintainers of this project at:
|
||||
|
||||
- [Slack]
|
||||
- [Mailing List]
|
||||
|
||||
### Code of conduct
|
||||
|
||||
Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct].
|
||||
|
||||
[KEP]: https://github.com/kubernetes/community/blob/master/keps/sig-cli/0008-kustomize.md
|
||||
[`make`]: https://www.gnu.org/software/make
|
||||
[`sed`]: https://www.gnu.org/software/sed
|
||||
[applied]: docs/glossary.md#apply
|
||||
[base]: docs/glossary.md#base
|
||||
[declarative configuration]: docs/glossary.md#declarative-application-management
|
||||
[examples]: examples/README.md
|
||||
[imageBase]: docs/base.jpg
|
||||
[imageOverlay]: docs/overlay.jpg
|
||||
[install]: docs/INSTALL.md
|
||||
[kubernetes style]: docs/glossary.md#kubernetes-style-object
|
||||
[kustomization]: docs/glossary.md#kustomization
|
||||
[overlay]: docs/glossary.md#overlay
|
||||
[overlays]: docs/glossary.md#overlay
|
||||
[release page]: https://github.com/kubernetes-sigs/kustomize/releases
|
||||
[resource]: docs/glossary.md#resource
|
||||
[resources]: docs/glossary.md#resource
|
||||
[sig-cli]: https://github.com/kubernetes/community/blob/master/sig-cli/README.md
|
||||
[variant]: docs/glossary.md#variant
|
||||
[variants]: docs/glossary.md#variant
|
||||
[workflows]: docs/workflows.md
|
||||
[community page]: http://kubernetes.io/community/
|
||||
[Kubernetes Code of Conduct]: code-of-conduct.md
|
||||
[Slack]: https://kubernetes.slack.com/messages/sig-cli
|
||||
[Mailing List]: https://groups.google.com/forum/#!forum/kubernetes-sig-cli
|
||||
|
||||
15
SECURITY_CONTACTS
Normal file
@@ -0,0 +1,15 @@
|
||||
# Defined below are the security contacts for this repo.
|
||||
#
|
||||
# They are the contact point for the Product Security Team to reach out
|
||||
# to for triaging and handling of incoming issues.
|
||||
#
|
||||
# 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)
|
||||
# and will be removed and replaced if they violate that agreement.
|
||||
#
|
||||
# DO NOT REPORT SECURITY VULNERABILITIES DIRECTLY TO THESE NAMES, FOLLOW THE
|
||||
# INSTRUCTIONS AT https://kubernetes.io/security/
|
||||
|
||||
monopole
|
||||
Liujingfang1
|
||||
pwittrock
|
||||
@@ -1,4 +1,5 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Make sure, we run in the root of the repo and
|
||||
# therefore run the tests on all packages
|
||||
@@ -10,10 +11,6 @@ cd "$base_dir" || {
|
||||
|
||||
rc=0
|
||||
|
||||
function go_dirs {
|
||||
go list -f '{{.Dir}}' ./... | tail -n +2 | tr '\n' '\0'
|
||||
}
|
||||
|
||||
function runTest {
|
||||
local name=$1
|
||||
local result="SUCCESS"
|
||||
@@ -27,30 +24,26 @@ function runTest {
|
||||
printf "============== end %s : %s code=%d\n\n\n" "$name" "$result" $code
|
||||
}
|
||||
|
||||
function testGoFmt {
|
||||
diff <(echo -n) <(go_dirs | xargs -0 gofmt -s -d -l)
|
||||
}
|
||||
|
||||
function testGoImports {
|
||||
diff -u <(echo -n) <(go_dirs | xargs -0 goimports -l)
|
||||
}
|
||||
|
||||
function testGoVet {
|
||||
go vet -all ./...
|
||||
function testGoLangCILint {
|
||||
golangci-lint run ./...
|
||||
}
|
||||
|
||||
function testGoTest {
|
||||
go test -v ./...
|
||||
}
|
||||
|
||||
function testDemos {
|
||||
mdrip --mode test --label test README.md ./demos
|
||||
function testExamples {
|
||||
mdrip --mode test --label test README.md ./examples
|
||||
}
|
||||
|
||||
runTest testGoFmt
|
||||
runTest testGoImports
|
||||
runTest testGoVet
|
||||
runTest testGoLangCILint
|
||||
runTest testGoTest
|
||||
runTest testDemos
|
||||
runTest testExamples
|
||||
|
||||
if [ $rc -eq 0 ]; then
|
||||
echo "SUCCESS!"
|
||||
else
|
||||
echo "FAILURE; exit code $rc"
|
||||
fi
|
||||
|
||||
exit $rc
|
||||
|
||||
@@ -1,13 +1,45 @@
|
||||
## Overview
|
||||
[releases page]: https://github.com/kubernetes-sigs/kustomize/releases
|
||||
[`cloud-build-local`]: https://github.com/GoogleCloudPlatform/cloud-build-local
|
||||
[Google Cloud Build]: https://cloud.google.com/cloud-build
|
||||
|
||||
This directory contains scripts and configuration files for publishing a
|
||||
`kustomize` release on [release page](https://github.com/kubernetes-sigs/kustomize/releases)
|
||||
Scripts and configuration files for publishing a
|
||||
`kustomize` release on the [releases page].
|
||||
|
||||
## Steps to run build a release locally
|
||||
Install container-builder-local from [github](https://github.com/GoogleCloudPlatform/container-builder-local).
|
||||
### Build a release locally
|
||||
|
||||
```sh
|
||||
container-builder-local --config=build/cloudbuild_local.yaml --dryrun=false --write-workspace=/tmp/w .
|
||||
Install [`cloud-build-local`], then run
|
||||
|
||||
```
|
||||
cloud-build-local \
|
||||
--config=build/cloudbuild_local.yaml \
|
||||
--dryrun=false --write-workspace=/tmp/w .
|
||||
```
|
||||
|
||||
You will find the build artifacts under `/tmp/w/dist` directory
|
||||
to build artifacts under `/tmp/w/dist`.
|
||||
|
||||
### Publish a Release
|
||||
|
||||
Get on an up-to-date master branch:
|
||||
```
|
||||
git checkout master
|
||||
git fetch upstream
|
||||
git rebase upstream/master
|
||||
```
|
||||
|
||||
Define the version (see [semver principles](https://semver.org)), e.g.:
|
||||
```
|
||||
version=v1.0.3
|
||||
```
|
||||
|
||||
Tag the repo:
|
||||
```
|
||||
git tag -a $version -m "$version release"
|
||||
```
|
||||
|
||||
Push the tag upstream:
|
||||
```
|
||||
git push upstream $version
|
||||
```
|
||||
|
||||
The new tag will trigger a job in [Google Cloud
|
||||
Build] to put a new release on the [releases page].
|
||||
|
||||
@@ -23,10 +23,10 @@ set -x
|
||||
# - Use /go as the default GOPATH because this is what the image uses
|
||||
# - Link our current directory (containing the source code) to the package location in the GOPATH
|
||||
|
||||
OWNER="kubernetes-sigs"
|
||||
OWNER="sigs.k8s.io"
|
||||
REPO="kustomize"
|
||||
|
||||
GO_PKG_OWNER=$GOPATH/src/github.com/$OWNER
|
||||
GO_PKG_OWNER=$GOPATH/src/$OWNER
|
||||
GO_PKG_PATH=$GO_PKG_OWNER/$REPO
|
||||
|
||||
mkdir -p $GO_PKG_OWNER
|
||||
@@ -56,4 +56,4 @@ case $key in
|
||||
esac
|
||||
done
|
||||
|
||||
/goreleaser release --config=build/goreleaser.yml --rm-dist --skip-validate ${SNAPSHOT}
|
||||
/goreleaser release --config=build/goreleaser.yaml --rm-dist --skip-validate ${SNAPSHOT}
|
||||
|
||||
@@ -4,7 +4,7 @@ project_name: kustomize
|
||||
builds:
|
||||
- main: ./kustomize.go
|
||||
binary: kustomize
|
||||
ldflags: -s -X github.com/kubernetes-sigs/kustomize/version.kustomizeVersion={{.Version}} -X github.com/kubernetes-sigs/kustomize/version.gitCommit={{.Commit}} -X github.com/kubernetes-sigs/kustomize/version.buildDate={{.Date}}
|
||||
ldflags: -s -X sigs.k8s.io/kustomize/pkg/commands/misc.kustomizeVersion={{.Version}} -X sigs.k8s.io/kustomize/pkg/commands/misc.gitCommit={{.Commit}} -X sigs.k8s.io/kustomize/pkg/commands/misc.buildDate={{.Date}}
|
||||
goos:
|
||||
- darwin
|
||||
- linux
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
# This is an example goreleaser.yaml file with some sane defaults.
|
||||
# Make sure to check the documentation at http://goreleaser.com
|
||||
project_name: kustomize
|
||||
builds:
|
||||
- main: ./kustomize.go
|
||||
binary: kustomize
|
||||
ldflags: -s -X github.com/kubernetes-sigs/kustomize/version.kustomizeVersion={{.Version}} -X github.com/kubernetes-sigs/kustomize/version.gitCommit={{.Commit}} -X github.com/kubernetes-sigs/kustomize/version.buildDate={{.Date}}
|
||||
goos:
|
||||
- darwin
|
||||
- linux
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
archive:
|
||||
format: binary
|
||||
snapshot:
|
||||
name_template: "master"
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
- Merge pull request
|
||||
- Merge branch
|
||||
release:
|
||||
github:
|
||||
owner: kubernetes-sigs
|
||||
name: kustomize
|
||||
281
build/vendor_kustomize.diff
Executable file
@@ -0,0 +1,281 @@
|
||||
commit 1b893558aa83ac6491e5ba416b493170a9045fec
|
||||
Author: Jingfang Liu <jingfangliu@google.com>
|
||||
Date: Mon Nov 12 10:26:12 2018 -0800
|
||||
|
||||
last change
|
||||
|
||||
diff --git a/staging/src/k8s.io/cli-runtime/artifacts/kustomization/configMap.yaml b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/configMap.yaml
|
||||
new file mode 100644
|
||||
index 0000000000..0008853094
|
||||
--- /dev/null
|
||||
+++ b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/configMap.yaml
|
||||
@@ -0,0 +1,8 @@
|
||||
+
|
||||
+apiVersion: v1
|
||||
+kind: ConfigMap
|
||||
+metadata:
|
||||
+ name: the-map
|
||||
+data:
|
||||
+ altGreeting: "Good Morning!"
|
||||
+ enableRisky: "false"
|
||||
diff --git a/staging/src/k8s.io/cli-runtime/artifacts/kustomization/deployment.yaml b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/deployment.yaml
|
||||
new file mode 100644
|
||||
index 0000000000..6e79409080
|
||||
--- /dev/null
|
||||
+++ b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/deployment.yaml
|
||||
@@ -0,0 +1,30 @@
|
||||
+apiVersion: apps/v1
|
||||
+kind: Deployment
|
||||
+metadata:
|
||||
+ name: the-deployment
|
||||
+spec:
|
||||
+ replicas: 3
|
||||
+ template:
|
||||
+ metadata:
|
||||
+ labels:
|
||||
+ deployment: hello
|
||||
+ spec:
|
||||
+ containers:
|
||||
+ - name: the-container
|
||||
+ image: monopole/hello:1
|
||||
+ command: ["/hello",
|
||||
+ "--port=8080",
|
||||
+ "--enableRiskyFeature=$(ENABLE_RISKY)"]
|
||||
+ ports:
|
||||
+ - containerPort: 8080
|
||||
+ env:
|
||||
+ - name: ALT_GREETING
|
||||
+ valueFrom:
|
||||
+ configMapKeyRef:
|
||||
+ name: the-map
|
||||
+ key: altGreeting
|
||||
+ - name: ENABLE_RISKY
|
||||
+ valueFrom:
|
||||
+ configMapKeyRef:
|
||||
+ name: the-map
|
||||
+ key: enableRisky
|
||||
diff --git a/staging/src/k8s.io/cli-runtime/artifacts/kustomization/kustomization.yaml b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/kustomization.yaml
|
||||
new file mode 100644
|
||||
index 0000000000..6e1e3202d5
|
||||
--- /dev/null
|
||||
+++ b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/kustomization.yaml
|
||||
@@ -0,0 +1,5 @@
|
||||
+nameprefix: test-
|
||||
+ resources:
|
||||
+- deployment.yaml
|
||||
+- service.yaml
|
||||
+- configMap.yaml
|
||||
diff --git a/staging/src/k8s.io/cli-runtime/artifacts/kustomization/service.yaml b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/service.yaml
|
||||
new file mode 100644
|
||||
index 0000000000..2942cdb7df
|
||||
--- /dev/null
|
||||
+++ b/staging/src/k8s.io/cli-runtime/artifacts/kustomization/service.yaml
|
||||
@@ -0,0 +1,13 @@
|
||||
+kind: Service
|
||||
+apiVersion: v1
|
||||
+metadata:
|
||||
+ name: the-service
|
||||
+spec:
|
||||
+ selector:
|
||||
+ deployment: hello
|
||||
+ type: LoadBalancer
|
||||
+ ports:
|
||||
+ - protocol: TCP
|
||||
+ port: 8666
|
||||
+ targetPort: 8080
|
||||
+
|
||||
\ No newline at end of file
|
||||
diff --git a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/BUILD b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/BUILD
|
||||
index 22b34de008..b91d1c0130 100644
|
||||
--- a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/BUILD
|
||||
+++ b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/BUILD
|
||||
@@ -35,12 +35,15 @@ go_library(
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/yaml:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/watch:go_default_library",
|
||||
+ "//staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/discovery:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/kubernetes/scheme:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/rest:go_default_library",
|
||||
"//staging/src/k8s.io/client-go/restmapper:go_default_library",
|
||||
"//vendor/golang.org/x/text/encoding/unicode:go_default_library",
|
||||
"//vendor/golang.org/x/text/transform:go_default_library",
|
||||
+ "//vendor/sigs.k8s.io/kustomize/pkg/commands/build:go_default_library",
|
||||
+ "//vendor/sigs.k8s.io/kustomize/pkg/fs:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
diff --git a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/builder_test.go b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/builder_test.go
|
||||
index 7fd526b33c..801f13f772 100644
|
||||
--- a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/builder_test.go
|
||||
+++ b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/builder_test.go
|
||||
@@ -465,27 +465,48 @@ func TestPathBuilderWithMultipleInvalid(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDirectoryBuilder(t *testing.T) {
|
||||
- b := newDefaultBuilder().
|
||||
- FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: []string{"../../../artifacts/guestbook"}}).
|
||||
- NamespaceParam("test").DefaultNamespace()
|
||||
+ tests := []struct {
|
||||
+ directories []string
|
||||
+ singleItem bool
|
||||
+ number int
|
||||
+ expectedNames []string
|
||||
+ }{
|
||||
+ {[]string{"../../../artifacts/guestbook"}, false, 3, []string{"redis-master"}},
|
||||
+ {[]string{"../../../artifacts/kustomization"}, true, 3, []string{"test-the-deployment"}},
|
||||
+ {[]string{"../../../artifacts/guestbook", "../../../artifacts/kustomization"}, false, 6, []string{"redis-master", "test-the-deployment"}},
|
||||
+ }
|
||||
|
||||
- test := &testVisitor{}
|
||||
- singleItemImplied := false
|
||||
+ for _, tt := range tests {
|
||||
+ b := newDefaultBuilder().
|
||||
+ FilenameParam(false, &FilenameOptions{Recursive: false, Filenames: tt.directories}).
|
||||
+ NamespaceParam("test").DefaultNamespace()
|
||||
|
||||
- err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle)
|
||||
- if err != nil || singleItemImplied || len(test.Infos) < 3 {
|
||||
- t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos)
|
||||
- }
|
||||
+ test := &testVisitor{}
|
||||
+ singleItemImplied := false
|
||||
|
||||
- found := false
|
||||
- for _, info := range test.Infos {
|
||||
- if info.Name == "redis-master" && info.Namespace == "test" && info.Object != nil {
|
||||
- found = true
|
||||
- break
|
||||
+ err := b.Do().IntoSingleItemImplied(&singleItemImplied).Visit(test.Handle)
|
||||
+ if err != nil || singleItemImplied != tt.singleItem || len(test.Infos) < tt.number {
|
||||
+ t.Fatalf("unexpected response: %v %t %#v", err, singleItemImplied, test.Infos)
|
||||
+ }
|
||||
+
|
||||
+ contained := func(name string) bool {
|
||||
+ for _, info := range test.Infos {
|
||||
+ if info.Name == name && info.Namespace == "test" && info.Object != nil {
|
||||
+ return true
|
||||
+ }
|
||||
+ }
|
||||
+ return false
|
||||
+ }
|
||||
+
|
||||
+ allFound := true
|
||||
+ for _, name := range tt.expectedNames {
|
||||
+ if !contained(name) {
|
||||
+ allFound = false
|
||||
+ }
|
||||
+ }
|
||||
+ if !allFound {
|
||||
+ t.Errorf("unexpected responses: %#v", test.Infos)
|
||||
}
|
||||
- }
|
||||
- if !found {
|
||||
- t.Errorf("unexpected responses: %#v", test.Infos)
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/visitor.go b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/visitor.go
|
||||
index 32c1a691a5..d7a37e1cde 100644
|
||||
--- a/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/visitor.go
|
||||
+++ b/staging/src/k8s.io/cli-runtime/pkg/genericclioptions/resource/visitor.go
|
||||
@@ -20,10 +20,12 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
+ "io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
+ "strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/text/encoding/unicode"
|
||||
@@ -38,6 +40,9 @@ import (
|
||||
utilerrors "k8s.io/apimachinery/pkg/util/errors"
|
||||
"k8s.io/apimachinery/pkg/util/yaml"
|
||||
"k8s.io/apimachinery/pkg/watch"
|
||||
+ "k8s.io/cli-runtime/pkg/kustomize/k8sdeps"
|
||||
+ "sigs.k8s.io/kustomize/pkg/commands/build"
|
||||
+ "sigs.k8s.io/kustomize/pkg/fs"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -452,7 +457,10 @@ func ExpandPathsToFileVisitors(mapper *mapper, paths string, recursive bool, ext
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
-
|
||||
+ if isKustomizationDir(path) {
|
||||
+ visitors = append(visitors, NewKustomizationVisitor(mapper, path, schema))
|
||||
+ return filepath.SkipDir
|
||||
+ }
|
||||
if fi.IsDir() {
|
||||
if path != paths && !recursive {
|
||||
return filepath.SkipDir
|
||||
@@ -463,7 +471,10 @@ func ExpandPathsToFileVisitors(mapper *mapper, paths string, recursive bool, ext
|
||||
if path != paths && ignoreFile(path, extensions) {
|
||||
return nil
|
||||
}
|
||||
-
|
||||
+ if strings.HasSuffix(path, "kustomization.yaml") {
|
||||
+ visitors = append(visitors, NewKustomizationVisitor(mapper, filepath.Dir(path), schema))
|
||||
+ return nil
|
||||
+ }
|
||||
visitor := &FileVisitor{
|
||||
Path: path,
|
||||
StreamVisitor: NewStreamVisitor(nil, mapper, path, schema),
|
||||
@@ -479,6 +490,14 @@ func ExpandPathsToFileVisitors(mapper *mapper, paths string, recursive bool, ext
|
||||
return visitors, nil
|
||||
}
|
||||
|
||||
+func isKustomizationDir(path string) bool {
|
||||
+ if _, err := os.Stat(filepath.Join(path, "kustomization.yaml")); err == nil {
|
||||
+ return true
|
||||
+ }
|
||||
+ return false
|
||||
+}
|
||||
+
|
||||
+
|
||||
// FileVisitor is wrapping around a StreamVisitor, to handle open/close files
|
||||
type FileVisitor struct {
|
||||
Path string
|
||||
@@ -507,6 +526,37 @@ func (v *FileVisitor) Visit(fn VisitorFunc) error {
|
||||
return v.StreamVisitor.Visit(fn)
|
||||
}
|
||||
|
||||
+// KustomizationVisitor prorvides the output of kustomization build
|
||||
+type KustomizationVisitor struct {
|
||||
+ Path string
|
||||
+ *StreamVisitor
|
||||
+}
|
||||
+
|
||||
+// Visit in a KustomizationVisitor build the kustomization output
|
||||
+func (v *KustomizationVisitor) Visit(fn VisitorFunc) error {
|
||||
+ fSys := fs.MakeRealFS()
|
||||
+ f := k8sdeps.NewFactory()
|
||||
+ var out bytes.Buffer
|
||||
+ cmd := build.NewCmdBuild(&out, fSys, f.ResmapF, f.TransformerF)
|
||||
+ cmd.SetArgs([]string{v.Path})
|
||||
+ // we want to silence usage, error output, and any future output from cobra
|
||||
+ // we will get error output as a golang error from execute
|
||||
+ cmd.SetOutput(ioutil.Discard)
|
||||
+ _, err := cmd.ExecuteC()
|
||||
+ if err != nil {
|
||||
+ return err
|
||||
+ }
|
||||
+ v.StreamVisitor.Reader = bytes.NewReader(out.Bytes())
|
||||
+ return v.StreamVisitor.Visit(fn)
|
||||
+}
|
||||
+
|
||||
+func NewKustomizationVisitor(mapper *mapper, path string, schema ContentValidator) *KustomizationVisitor {
|
||||
+ return &KustomizationVisitor{
|
||||
+ Path: path,
|
||||
+ StreamVisitor: NewStreamVisitor(nil, mapper, path, schema),
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
// StreamVisitor reads objects from an io.Reader and walks them. A stream visitor can only be
|
||||
// visited once.
|
||||
// TODO: depends on objects being in JSON format before being passed to decode - need to implement
|
||||
118
build/vendor_kustomize.sh
Executable file
@@ -0,0 +1,118 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2018 The Kubernetes Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
set -e
|
||||
set -x
|
||||
|
||||
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
|
||||
|
||||
# vendor_kustomize.sh creates the change in kubernetes repo for vendoring kustomize
|
||||
|
||||
function setUpWorkspace {
|
||||
KPATH=~/kustomize_vendor
|
||||
mkdir $KPATH
|
||||
GOPATH=$KPATH
|
||||
}
|
||||
|
||||
function cloneK8s {
|
||||
mkdir -p $KPATH/src/k8s.io
|
||||
cd $KPATH/src/k8s.io
|
||||
|
||||
git clone git@github.com:kubernetes/kubernetes.git
|
||||
}
|
||||
|
||||
function godepRestore {
|
||||
cd $KPATH/src/k8s.io/kubernetes
|
||||
|
||||
# restore dependencies
|
||||
hack/run-in-gopath.sh hack/godep-restore.sh
|
||||
}
|
||||
|
||||
function getKustomizeDeps {
|
||||
# get Kustomize and Kustomize dependencies
|
||||
hack/run-in-gopath.sh godep get sigs.k8s.io/kustomize/pkg/commands
|
||||
hack/run-in-gopath.sh godep get github.com/bgentry/go-netrc/netrc
|
||||
hack/run-in-gopath.sh godep get github.com/hashicorp/go-cleanhttp
|
||||
hack/run-in-gopath.sh godep get github.com/hashicorp/go-getter
|
||||
hack/run-in-gopath.sh godep get github.com/hashicorp/go-safetemp
|
||||
hack/run-in-gopath.sh godep get github.com/hashicorp/go-version
|
||||
|
||||
# The hashes below passed bin/pre-commit.sh with kustomize HEAD at time of merger.
|
||||
DEPS=(
|
||||
"hashicorp/go-getter 4bda8fa99001c61db3cad96b421d4c12a81f256d"
|
||||
"hashicorp/go-cleanhttp d5fe4b57a186c716b0e00b8c301cbd9b4182694d"
|
||||
"hashicorp/go-safetemp b1a1dbde6fdc11e3ae79efd9039009e22d4ae240"
|
||||
"hashicorp/go-version 270f2f71b1ee587f3b609f00f422b76a6b28f348"
|
||||
"bgentry/go-netrc 9fd32a8b3d3d3f9d43c341bfe098430e07609480"
|
||||
"mitchellh/go-homedir 58046073cbffe2f25d425fe1331102f55cf719de"
|
||||
"mitchellh/go-testing-interface a61a99592b77c9ba629d254a693acffaeb4b7e28"
|
||||
"ulikunitz/xz v0.5.4"
|
||||
)
|
||||
|
||||
function foo {
|
||||
cd $KPATH/src/k8s.io/kubernetes/_output/local/go/src/github.com/$1
|
||||
git checkout $2
|
||||
}
|
||||
for i in "${DEPS[@]}"; do
|
||||
foo $i
|
||||
done
|
||||
}
|
||||
|
||||
function updateK8s {
|
||||
# Copy k8sdeps from Kustomize to cli-runtime in staging
|
||||
mkdir -p $KPATH/src/k8s.io/kubernetes/staging/src/k8s.io/cli-runtime/pkg/kustomize
|
||||
cp -r $KPATH/src/k8s.io/kubernetes/_output/local/go/src/sigs.k8s.io/kustomize/k8sdeps \
|
||||
$KPATH/src/k8s.io/kubernetes/staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps
|
||||
|
||||
# Change import path of k8sdeps
|
||||
find $KPATH/src/k8s.io/kubernetes/staging/src/k8s.io/cli-runtime/pkg/kustomize/k8sdeps \
|
||||
-type f -name "*.go" | \
|
||||
xargs sed -i \
|
||||
's!sigs.k8s.io/kustomize/k8sdeps!k8s.io/cli-runtime/pkg/kustomize/k8sdeps!'
|
||||
|
||||
|
||||
# Add kustomize command to kubectl
|
||||
cp $DIR/vendor_kustomize.diff $KPATH/vendor_kustomize.diff
|
||||
|
||||
cd $GOPATH/src/k8s.io/kubernetes
|
||||
git apply --ignore-space-change --ignore-whitespace $KPATH/vendor_kustomize.diff
|
||||
}
|
||||
|
||||
function godepSave {
|
||||
# Save all dependencies into k8s.io/kubernetes/vendor by running
|
||||
# hack/godep-save.sh
|
||||
hack/run-in-gopath.sh hack/godep-save.sh
|
||||
}
|
||||
|
||||
function verify {
|
||||
# make sure in k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize
|
||||
# there is no internal package
|
||||
test 0 == $(ls $KPATH/src/k8s.io/kubernetes/vendor/sigs.k8s.io/kustomize | grep “internal” | wc -l)
|
||||
|
||||
# Make sure it compiles.
|
||||
test 0 == $(bazel build cmd/kubectl:kubectl)
|
||||
|
||||
# next step, open a PR
|
||||
echo "The change for vendoring kustomize is ready in $GOPATH/src/k8s.io/kubernetes.\n Next step, open a PR for it.\n"
|
||||
}
|
||||
|
||||
setUpWorkspace
|
||||
cloneK8s
|
||||
godepRestore
|
||||
getKustomizeDeps
|
||||
updateK8s
|
||||
godepSave
|
||||
verify
|
||||
@@ -1,6 +1,3 @@
|
||||
[Kubernetes Community Code of Conduct]: https://git.k8s.io/community/code-of-conduct.md
|
||||
# Kubernetes Community Code of Conduct
|
||||
|
||||
# Code of Conduct
|
||||
|
||||
This project has adopted the
|
||||
[Kubernetes Community Code of Conduct].
|
||||
Please refer to our [Kubernetes Community Code of Conduct](https://git.k8s.io/community/code-of-conduct.md)
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
# Demos
|
||||
|
||||
These demos assume that `kustomize` is on your `$PATH`.
|
||||
They are covered by pre-submit tests.
|
||||
|
||||
* [hello world](helloWorld/README.md) - Deploy multiple
|
||||
(differently configured) variants of a simple Hello
|
||||
World server.
|
||||
|
||||
* [LDAP](ldap/README.md) - Deploy multiple
|
||||
(differently configured) variants of a LDAP server.
|
||||
|
||||
* [mySql](mySql/README.md) - Create a MySQL production
|
||||
configuration from scratch.
|
||||
|
||||
* [springboot](springboot/README.md) - Create a Spring Boot
|
||||
application production configuration from scratch.
|
||||
|
||||
* [configGeneration](configGeneration.md) -
|
||||
Mixing configuration data from different owners
|
||||
(e.g. devops/SRE and developers).
|
||||
|
||||
* [breakfast](breakfast.md) - Customize breakfast for
|
||||
Alice and Bob.
|
||||
@@ -1,298 +0,0 @@
|
||||
[overlay]: ../docs/glossary.md#overlay
|
||||
[target]: ../docs/glossary.md#target
|
||||
|
||||
# Demo: combining config data from devops and developers
|
||||
|
||||
Scenario: you have a Java-based server storefront in
|
||||
production that various internal development teams
|
||||
(signups, checkout, search, etc.) contribute to.
|
||||
|
||||
The server runs in different environments:
|
||||
_development_, _testing_, _staging_ and _production_,
|
||||
accepting configuration parameters from java property
|
||||
files.
|
||||
|
||||
Using one big properties file for each environment is
|
||||
difficult to manage. The files change frequently, and
|
||||
have to be changed by devops exclusively because
|
||||
|
||||
1. the files must at least partially agree on certain
|
||||
values that devops cares about and that developers
|
||||
ignore and
|
||||
1. because the production
|
||||
properties contain sensitive data like production
|
||||
database credentials.
|
||||
|
||||
## Property sharding
|
||||
|
||||
With some study, we notice that the properties are
|
||||
separable into categories.
|
||||
|
||||
### Common properties
|
||||
|
||||
E.g. internationalization data, static data like
|
||||
physical constants, location of external services, etc.
|
||||
|
||||
_Things that are the same regardless of environment._
|
||||
|
||||
Only one set of values is needed.
|
||||
|
||||
Place them in a file called
|
||||
|
||||
* `common.properties`
|
||||
|
||||
(relative location defined below).
|
||||
|
||||
### Plumbing properties
|
||||
|
||||
E.g. serving location of static content (HTML, CSS,
|
||||
javascript), location of product and customer database
|
||||
tables, ports expected by load balancers, log sinks,
|
||||
etc.
|
||||
|
||||
_The different values for these properties are
|
||||
precisely what sets the environments apart._
|
||||
|
||||
Devops or SRE will want full control over the values
|
||||
used in production. Testing will have fixed
|
||||
databases supporting testing. Developers will want
|
||||
to do whatever they want to try scenarios under
|
||||
development.
|
||||
|
||||
Places these values in
|
||||
|
||||
* `development/plumbing.properties`
|
||||
* `staging/plumbing.properties`
|
||||
* `production/plumbing.properties`
|
||||
|
||||
|
||||
### Secret properties
|
||||
|
||||
E.g. location of actual user tables, database
|
||||
credentials, decryption keys, etc.
|
||||
|
||||
_Things that are a subset of devops controls, that
|
||||
nobody else has (or should want) access to._
|
||||
|
||||
Places these values in
|
||||
|
||||
* `development/secret.properties`
|
||||
* `staging/secret.properties`
|
||||
* `production/secret.properties`
|
||||
|
||||
[kubernetes secret]: https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/
|
||||
|
||||
and control access to them with (for example) unix file
|
||||
owner and mode bits, or better yet, put them in
|
||||
a server dedicated to storing password protected
|
||||
secrets, and use a field called `secretGenerator`
|
||||
in your _kustomization_ to create a kubernetes
|
||||
secret holding them (not covering that here).
|
||||
|
||||
<!--
|
||||
secretGenerator:
|
||||
- name: app-tls
|
||||
commands:
|
||||
tls.crt: "cat tls.cert"
|
||||
tls.key: "cat tls.key"
|
||||
type: "kubernetes.io/tls"
|
||||
EOF
|
||||
-->
|
||||
|
||||
## A mixin approach to management
|
||||
|
||||
The way to create _n_ cluster environments that share
|
||||
some common information is to create _n_ overlays of a
|
||||
common base.
|
||||
|
||||
For the rest of this example, we'll do _n==2_, just
|
||||
_development_ and _production_, since adding more
|
||||
environments follows the same pattern.
|
||||
|
||||
A cluster environment is created by
|
||||
running `kustomize build` on a [target] that happens to
|
||||
be an [overlay].
|
||||
|
||||
[helloworld]: helloworld.md
|
||||
|
||||
The following example will do that, but will focus on
|
||||
configMap construction, and not worry about how to
|
||||
connect the configMaps to deployments (that is covered
|
||||
in the [helloworld] example).
|
||||
|
||||
|
||||
All files - including the shared property files
|
||||
discussed above - will be created in a directory tree
|
||||
that is consistent with the base vs overlay file layout
|
||||
defined in the [helloworld] demo.
|
||||
|
||||
It will all live in this work directory:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Create the base
|
||||
|
||||
<!-- kubectl create configmap BOB --dry-run -o yaml --from-file db. -->
|
||||
|
||||
Make a place to put the base configuration:
|
||||
|
||||
<!-- @baseDir @test -->
|
||||
```
|
||||
mkdir -p $DEMO_HOME/base
|
||||
```
|
||||
|
||||
Make the data for the base. This direction by
|
||||
definition should hold resources common to all
|
||||
environments. Here we're only defining a java
|
||||
properties file, and a `kustomization` file that
|
||||
references it.
|
||||
|
||||
<!-- @baseKustomization @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/base/common.properties
|
||||
color=blue
|
||||
height=10m
|
||||
EOF
|
||||
|
||||
cat <<EOF >$DEMO_HOME/base/kustomization.yaml
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
files:
|
||||
- common.properties
|
||||
EOF
|
||||
```
|
||||
|
||||
|
||||
### Create and use the overlay for _development_
|
||||
|
||||
Make an abbreviation for the parent of the overlay
|
||||
directories:
|
||||
|
||||
<!-- @overlays @test -->
|
||||
```
|
||||
OVERLAYS=$DEMO_HOME/overlays
|
||||
```
|
||||
|
||||
Create the files that define the _development_ overlay:
|
||||
|
||||
<!-- @developmentFiles @test -->
|
||||
```
|
||||
mkdir -p $OVERLAYS/development
|
||||
|
||||
cat <<EOF >$OVERLAYS/development/plumbing.properties
|
||||
port=30000
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/development/secret.properties
|
||||
dbpassword=mothersMaidenName
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/development/kustomization.yaml
|
||||
bases:
|
||||
- ../../base
|
||||
namePrefix: dev-
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
behavior: merge
|
||||
files:
|
||||
- plumbing.properties
|
||||
- secret.properties
|
||||
EOF
|
||||
```
|
||||
|
||||
One can now generate the configMaps for development:
|
||||
|
||||
<!-- @runDev @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/development
|
||||
```
|
||||
|
||||
#### Check the ConfigMap name
|
||||
|
||||
The name of the generated `ConfigMap` is visible in this
|
||||
output.
|
||||
|
||||
The name should be something like `dev-my-configmap-b5m75ck895`:
|
||||
|
||||
* `"dev-"` comes from the `namePrefix` field,
|
||||
* `"my-configmap"` comes from the `configMapGenerator/name` field,
|
||||
* `"-b5m75ck895"` comes from a deterministic hash that `kustomize`
|
||||
computes from the contents of the configMap.
|
||||
|
||||
The hash suffix is critical. If the configMap content
|
||||
changes, so does the configMap name, along with all
|
||||
references to that name that appear in the YAML output
|
||||
from `kustomize`.
|
||||
|
||||
The name change means deployments will do a rolling
|
||||
restart to get new data if this YAML is applied to the
|
||||
cluster using a command like
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/development | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
A deployment has no means to automatically know when or
|
||||
if a configMap in use by the deployment changes.
|
||||
|
||||
If one changes a configMap without changing its name
|
||||
and all references to that name, one must imperatively
|
||||
restart the cluster to pick up the change.
|
||||
|
||||
The best practice is to treat configMaps as immutable.
|
||||
|
||||
Instead of editing configMaps, modify your declarative
|
||||
specification of the cluster's desired state to
|
||||
point deployments to _new_ configMaps with _new_ names.
|
||||
`kustomize` makes this easy with its
|
||||
`configMapGenerator` directive and associated naming
|
||||
controls. A GC process in the k8s master eventually
|
||||
deletes unused configMaps.
|
||||
|
||||
|
||||
### Create and use the overlay for _production_
|
||||
|
||||
Next, create the files for the _production_ overlay:
|
||||
|
||||
|
||||
<!-- @productionFiles @test -->
|
||||
```
|
||||
mkdir -p $OVERLAYS/production
|
||||
|
||||
cat <<EOF >$OVERLAYS/production/plumbing.properties
|
||||
port=8080
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/production/secret.properties
|
||||
dbpassword=thisShouldProbablyBeInASecretInstead
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/production/kustomization.yaml
|
||||
bases:
|
||||
- ../../base
|
||||
namePrefix: prod-
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
behavior: merge
|
||||
files:
|
||||
- plumbing.properties
|
||||
- secret.properties
|
||||
EOF
|
||||
```
|
||||
|
||||
One can now generate the configMaps for production:
|
||||
|
||||
<!-- @runProd @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/production
|
||||
```
|
||||
|
||||
A CICD process could apply this directly to
|
||||
the cluser using:
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/production | kubectl apply -f -
|
||||
> ```
|
||||
@@ -1,430 +0,0 @@
|
||||
[base]: ../../docs/glossary.md#base
|
||||
[config]: https://github.com/kinflate/example-hello
|
||||
[gitops]: ../../docs/glossary.md#gitops
|
||||
[hello]: https://github.com/monopole/hello
|
||||
[kustomization]: ../../docs/glossary.md#kustomization
|
||||
[original]: https://github.com/kinflate/example-hello
|
||||
[overlay]: ../../docs/glossary.md#overlay
|
||||
[overlays]: ../../docs/glossary.md#overlay
|
||||
[patch]: ../../docs/glossary.md#patch
|
||||
[variant]: ../../docs/glossary.md#variant
|
||||
[variants]: ../../docs/glossary.md#variant
|
||||
|
||||
# Demo: hello world with variants
|
||||
|
||||
Steps:
|
||||
|
||||
1. Clone an existing configuration as a [base].
|
||||
1. Customize it.
|
||||
1. Create two different [overlays] (_staging_ and _production_)
|
||||
from the customized base.
|
||||
1. Run kustomize and kubectl to deploy staging and production.
|
||||
|
||||
First define a place to work:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
Alternatively, use
|
||||
|
||||
> ```
|
||||
> DEMO_HOME=~/hello
|
||||
> ```
|
||||
|
||||
## Establish the base
|
||||
|
||||
Let's run the [hello] service.
|
||||
|
||||
To use [overlays] to create [variants], we must
|
||||
first establish a common [base].
|
||||
|
||||
To keep this document shorter, the base resources are
|
||||
off in a supplemental data directory rather than
|
||||
declared here as HERE documents. Download them:
|
||||
|
||||
<!-- @downloadBase @test -->
|
||||
```
|
||||
BASE=$DEMO_HOME/base
|
||||
mkdir -p $BASE
|
||||
|
||||
curl -s -o "$BASE/#1.yaml" "https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/demos/helloWorld\
|
||||
/{configMap,deployment,kustomization,service}.yaml"
|
||||
```
|
||||
|
||||
Look at the directory:
|
||||
|
||||
<!-- @runTree @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expect something like:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP
|
||||
> └── base
|
||||
> ├── configMap.yaml
|
||||
> ├── deployment.yaml
|
||||
> ├── kustomization.yaml
|
||||
> └── service.yaml
|
||||
> ```
|
||||
|
||||
|
||||
One could immediately apply these resources to a
|
||||
cluster:
|
||||
|
||||
> ```
|
||||
> kubectl apply -f $DEMO_HOME/base
|
||||
> ```
|
||||
|
||||
to instantiate the _hello_ service. `kubectl`
|
||||
would only recognize the resource files.
|
||||
|
||||
### The Base Kustomization
|
||||
|
||||
The `base` directory has a [kustomization] file:
|
||||
|
||||
<!-- @showKustomization @test -->
|
||||
```
|
||||
more $BASE/kustomization.yaml
|
||||
```
|
||||
|
||||
Optionally, run `kustomize` on the base to emit
|
||||
customized resources to `stdout`:
|
||||
|
||||
<!-- @buildBase @test -->
|
||||
```
|
||||
kustomize build $BASE
|
||||
```
|
||||
|
||||
### Customize the base
|
||||
|
||||
A first customization step could be to change the _app
|
||||
label_ applied to all resources:
|
||||
|
||||
<!-- @addLabel @test -->
|
||||
```
|
||||
sed -i 's/app: hello/app: my-hello/' \
|
||||
$BASE/kustomization.yaml
|
||||
```
|
||||
|
||||
See the effect:
|
||||
<!-- @checkLabel @test -->
|
||||
```
|
||||
kustomize build $BASE | grep -C 3 app:
|
||||
```
|
||||
|
||||
## Create Overlays
|
||||
|
||||
Create a _staging_ and _production_ [overlay]:
|
||||
|
||||
* _Staging_ enables a risky feature not enabled in production.
|
||||
* _Production_ has a higher replica count.
|
||||
* Web server greetings from these cluster
|
||||
[variants] will differ from each other.
|
||||
|
||||
<!-- @overlayDirectories @test -->
|
||||
```
|
||||
OVERLAYS=$DEMO_HOME/overlays
|
||||
mkdir -p $OVERLAYS/staging
|
||||
mkdir -p $OVERLAYS/production
|
||||
```
|
||||
|
||||
#### Staging Kustomization
|
||||
|
||||
In the `staging` directory, make a kustomization
|
||||
defining a new name prefix, and some different labels.
|
||||
|
||||
<!-- @makeStagingKustomization @test -->
|
||||
```
|
||||
cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml
|
||||
namePrefix: staging-
|
||||
commonLabels:
|
||||
variant: staging
|
||||
org: acmeCorporation
|
||||
commonAnnotations:
|
||||
note: Hello, I am staging!
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
- map.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
#### Staging Patch
|
||||
|
||||
Add a configMap customization to change the server
|
||||
greeting from _Good Morning!_ to _Have a pineapple!_
|
||||
|
||||
Also, enable the _risky_ flag.
|
||||
|
||||
<!-- @stagingMap @test -->
|
||||
```
|
||||
cat <<EOF >$OVERLAYS/staging/map.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: the-map
|
||||
data:
|
||||
altGreeting: "Have a pineapple!"
|
||||
enableRisky: "true"
|
||||
EOF
|
||||
```
|
||||
|
||||
#### Production Kustomization
|
||||
|
||||
In the production directory, make a kustomization
|
||||
with a different name prefix and labels.
|
||||
|
||||
<!-- @makeProductionKustomization @test -->
|
||||
```
|
||||
cat <<EOF >$OVERLAYS/production/kustomization.yaml
|
||||
namePrefix: production-
|
||||
commonLabels:
|
||||
variant: production
|
||||
org: acmeCorporation
|
||||
commonAnnotations:
|
||||
note: Hello, I am production!
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
- deployment.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
|
||||
#### Production Patch
|
||||
|
||||
Make a production patch that increases the replica
|
||||
count (because production takes more traffic).
|
||||
|
||||
<!-- @productionDeployment @test -->
|
||||
```
|
||||
cat <<EOF >$OVERLAYS/production/deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: the-deployment
|
||||
spec:
|
||||
replicas: 10
|
||||
EOF
|
||||
```
|
||||
|
||||
## Compare overlays
|
||||
|
||||
|
||||
`DEMO_HOME` now contains:
|
||||
|
||||
- a _base_ directory - a slightly customized clone
|
||||
of the original configuration, and
|
||||
|
||||
- an _overlays_ directory, containing the kustomizations
|
||||
and patches required to create distinct _staging_
|
||||
and _production_ [variants] in a cluster.
|
||||
|
||||
Review the directory structure and differences:
|
||||
|
||||
<!-- @listFiles @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expecting something like:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP1
|
||||
> ├── base
|
||||
> │ ├── configMap.yaml
|
||||
> │ ├── deployment.yaml
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── service.yaml
|
||||
> └── overlays
|
||||
> ├── production
|
||||
> │ ├── deployment.yaml
|
||||
> │ └── kustomization.yaml
|
||||
> └── staging
|
||||
> ├── kustomization.yaml
|
||||
> └── map.yaml
|
||||
> ```
|
||||
|
||||
Compare the output directly
|
||||
to see how _staging_ and _production_ differ:
|
||||
|
||||
<!-- @compareOutput -->
|
||||
```
|
||||
diff \
|
||||
<(kustomize build $OVERLAYS/staging) \
|
||||
<(kustomize build $OVERLAYS/production) |\
|
||||
more
|
||||
```
|
||||
|
||||
The first part of the difference output should look
|
||||
something like
|
||||
|
||||
> ```diff
|
||||
> < altGreeting: Have a pineapple!
|
||||
> < enableRisky: "true"
|
||||
> ---
|
||||
> > altGreeting: Good Morning!
|
||||
> > enableRisky: "false"
|
||||
> 8c8
|
||||
> < note: Hello, I am staging!
|
||||
> ---
|
||||
> > note: Hello, I am production!
|
||||
> 11c11
|
||||
> < variant: staging
|
||||
> ---
|
||||
> > variant: production
|
||||
> 13c13
|
||||
> (...truncated)
|
||||
> ```
|
||||
|
||||
|
||||
## Deploy
|
||||
|
||||
The individual resource sets are:
|
||||
|
||||
<!-- @buildStaging @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging
|
||||
```
|
||||
|
||||
<!-- @buildProduction @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/production
|
||||
```
|
||||
|
||||
To deploy, pipe the above commands to kubectl apply:
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/staging |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/production |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
|
||||
## Rolling updates
|
||||
|
||||
### Review
|
||||
|
||||
The _hello-world_ deployment running in this cluster is
|
||||
configured with data from a configMap.
|
||||
|
||||
The deployment refers to this map by name:
|
||||
|
||||
|
||||
<!-- @showDeployment @test -->
|
||||
```
|
||||
grep -C 2 configMapKeyRef $DEMO_HOME/base/deployment.yaml
|
||||
```
|
||||
|
||||
Changing the data held by a live configMap in a cluster
|
||||
is considered bad practice. Deployments have no means
|
||||
to know that the configMaps they refer to have
|
||||
changed, so such updates have no effect.
|
||||
|
||||
The recommended way to change a deployment's
|
||||
configuration is to
|
||||
|
||||
1. create a new configMap with a new name,
|
||||
1. patch the _deployment_, modifying the name value of
|
||||
the appropriate `configMapKeyRef` field.
|
||||
|
||||
This latter change initiates rolling update to the pods
|
||||
in the deployment. The older configMap, when no longer
|
||||
referenced by any other resource, is eventually garbage
|
||||
collected.
|
||||
|
||||
### How this works with kustomize
|
||||
|
||||
The _staging_ [variant] here has a configMap [patch]:
|
||||
|
||||
<!-- @showMapPatch @test -->
|
||||
```
|
||||
cat $OVERLAYS/staging/map.yaml
|
||||
```
|
||||
|
||||
This patch is by definition a named but not necessarily
|
||||
complete resource spec intended to modify a complete
|
||||
resource spec.
|
||||
|
||||
The resource it modifies is here:
|
||||
|
||||
<!-- @showMapBase @test -->
|
||||
```
|
||||
cat $DEMO_HOME/base/configMap.yaml
|
||||
```
|
||||
|
||||
For a patch to work, the names in the `metadata/name`
|
||||
fields must match.
|
||||
|
||||
However, the name values specified in the file are
|
||||
_not_ what gets used in the cluster. By design,
|
||||
kustomize modifies these names. To see the names
|
||||
ultimately used in the cluster, just run kustomize:
|
||||
|
||||
<!-- @grepStagingName @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging |\
|
||||
grep -B 8 -A 1 staging-the-map
|
||||
```
|
||||
|
||||
The configMap name is prefixed by _staging-_, per the
|
||||
`namePrefix` field in
|
||||
`$OVERLAYS/staging/kustomization.yaml`.
|
||||
|
||||
The suffix to the configMap name is generated from a
|
||||
hash of the maps content - in this case the name suffix
|
||||
is _hhhhkfmgmk_:
|
||||
|
||||
<!-- @grepStagingHash @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging | grep hhhhkfmgmk
|
||||
```
|
||||
|
||||
Now modify the map patch, to change the greeting
|
||||
the server will use:
|
||||
|
||||
<!-- @changeMap @test -->
|
||||
```
|
||||
sed -i 's/pineapple/kiwi/' $OVERLAYS/staging/map.yaml
|
||||
```
|
||||
|
||||
Run kustomize again to see the new names:
|
||||
|
||||
<!-- @grepStagingName @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging |\
|
||||
grep -B 8 -A 1 staging-the-map
|
||||
```
|
||||
|
||||
Confirm that the change in configMap content resulted
|
||||
in three new names ending in _khk45ktkd9_ - one in the
|
||||
configMap name itself, and two in the deployment that
|
||||
uses the map:
|
||||
|
||||
<!-- @countHashes @test -->
|
||||
```
|
||||
test 3 == \
|
||||
$(kustomize build $OVERLAYS/staging | grep khk45ktkd9 | wc -l)
|
||||
```
|
||||
|
||||
Applying these resources to the cluster will result in
|
||||
a rolling update of the deployments pods, retargetting
|
||||
them from the _hhhhkfmgmk_ maps to the _khk45ktkd9_
|
||||
maps. The system will later garbage collect the
|
||||
unused maps.
|
||||
|
||||
## Rollback
|
||||
|
||||
To rollback, one would undo whatever edits were made to
|
||||
the configuation in source control, then rerun kustomize
|
||||
on the reverted configuration and apply it to the
|
||||
cluster.
|
||||
@@ -1,9 +0,0 @@
|
||||
# Example configuration for the webserver
|
||||
# at https://github.com/monopole/hello
|
||||
commonLabels:
|
||||
app: hello
|
||||
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- configMap.yaml
|
||||
- service.yaml
|
||||
@@ -1,281 +0,0 @@
|
||||
[base]: ../../docs/glossary.md#base
|
||||
[gitops]: ../../docs/glossary.md#gitops
|
||||
[kustomization]: ../../docs/glossary.md#kustomization
|
||||
[overlay]: ../../docs/glossary.md#overlay
|
||||
[overlays]: ../../docs/glossary.md#overlay
|
||||
[variant]: ../../docs/glossary.md#variant
|
||||
[variants]: ../../docs/glossary.md#variant
|
||||
|
||||
# Demo: LDAP with variants
|
||||
|
||||
Steps:
|
||||
|
||||
1. Clone an existing configuration as a [base].
|
||||
1. Customize it.
|
||||
1. Create two different [overlays] (_staging_ and _production_)
|
||||
from the customized base.
|
||||
1. Run kustomize and kubectl to deploy staging and production.
|
||||
|
||||
First define a place to work:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
Alternatively, use
|
||||
|
||||
> ```
|
||||
> DEMO_HOME=~/ldap
|
||||
> ```
|
||||
|
||||
## Establish the base
|
||||
|
||||
To use [overlays] to create [variants], we must
|
||||
first establish a common [base].
|
||||
|
||||
To keep this document shorter, the base resources are
|
||||
off in a supplemental data directory rather than
|
||||
declared here as HERE documents. Download them:
|
||||
|
||||
<!-- @downloadBase @test -->
|
||||
```
|
||||
BASE=$DEMO_HOME/base
|
||||
mkdir -p $BASE
|
||||
|
||||
CONTENT="https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/demos/ldap"
|
||||
|
||||
curl -s -o "$BASE/#1" "$CONTENT/base\
|
||||
/{deployment.yaml,kustomization.yaml,service.yaml,env.startup.txt}"
|
||||
```
|
||||
|
||||
Look at the directory:
|
||||
|
||||
<!-- @runTree @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expect something like:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP
|
||||
> └── base
|
||||
> ├── deployment.yaml
|
||||
> ├── env.startup.txt
|
||||
> ├── kustomization.yaml
|
||||
> └── service.yaml
|
||||
> ```
|
||||
|
||||
|
||||
One could immediately apply these resources to a
|
||||
cluster:
|
||||
|
||||
> ```
|
||||
> kubectl apply -f $DEMO_HOME/base
|
||||
> ```
|
||||
|
||||
to instantiate the _ldap_ service. `kubectl`
|
||||
would only recognize the resource files.
|
||||
|
||||
### The Base Kustomization
|
||||
|
||||
The `base` directory has a [kustomization] file:
|
||||
|
||||
<!-- @showKustomization @test -->
|
||||
```
|
||||
more $BASE/kustomization.yaml
|
||||
```
|
||||
|
||||
Optionally, run `kustomize` on the base to emit
|
||||
customized resources to `stdout`:
|
||||
|
||||
<!-- @buildBase @test -->
|
||||
```
|
||||
kustomize build $BASE
|
||||
```
|
||||
|
||||
### Customize the base
|
||||
|
||||
A first customization step could be to set the name prefix to all resources:
|
||||
|
||||
<!-- @namePrefix @test -->
|
||||
```
|
||||
cd $BASE
|
||||
kustomize edit set nameprefix "my-"
|
||||
```
|
||||
|
||||
See the effect:
|
||||
<!-- @checkNameprefix @test -->
|
||||
```
|
||||
kustomize build $BASE | grep -C 3 "my-"
|
||||
```
|
||||
|
||||
## Create Overlays
|
||||
|
||||
Create a _staging_ and _production_ [overlay]:
|
||||
|
||||
* _Staging_ adds a configMap.
|
||||
* _Production_ has a higher replica count and a persistent disk.
|
||||
* [variants] will differ from each other.
|
||||
|
||||
<!-- @overlayDirectories @test -->
|
||||
```
|
||||
OVERLAYS=$DEMO_HOME/overlays
|
||||
mkdir -p $OVERLAYS/staging
|
||||
mkdir -p $OVERLAYS/production
|
||||
```
|
||||
|
||||
#### Staging Kustomization
|
||||
|
||||
Download the staging customization and patch.
|
||||
|
||||
<!-- @downloadStagingKustomization @test -->
|
||||
```
|
||||
curl -s -o "$OVERLAYS/staging/#1" "$CONTENT/overlays/staging\
|
||||
/{config.env,deployment.yaml,kustomization.yaml}"
|
||||
```
|
||||
|
||||
The staging customization adds a configMap.
|
||||
> ```cat $OVERLAYS/staging/kustomization.yaml
|
||||
> (...truncated)
|
||||
> configMapGenerator:
|
||||
> - name: env-config
|
||||
> files:
|
||||
> - config.env
|
||||
> ```
|
||||
as well as 2 replica
|
||||
> ```cat $OVERLAYS/staging/deployment.yaml
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: ldap
|
||||
> spec:
|
||||
> replicas: 2
|
||||
> ```
|
||||
|
||||
#### Production Kustomization
|
||||
|
||||
Download the production customization and patch.
|
||||
<!-- @downloadProductionKustomization @test -->
|
||||
```
|
||||
curl -s -o "$OVERLAYS/production/#1" "$CONTENT/overlays/production\
|
||||
/{deployment.yaml,kustomization.yaml}"
|
||||
```
|
||||
|
||||
The production customization adds 6 replica as well as a consistent disk.
|
||||
> ```cat $OVERLAYS/production/deployment.yaml
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: ldap
|
||||
> spec:
|
||||
> replicas: 6
|
||||
> template:
|
||||
> spec:
|
||||
> volumes:
|
||||
> - name: ldap-data
|
||||
> emptyDir: null
|
||||
> gcePersistentDisk:
|
||||
> pdName: ldap-persistent-storage
|
||||
> ```
|
||||
|
||||
## Compare overlays
|
||||
|
||||
|
||||
`DEMO_HOME` now contains:
|
||||
|
||||
- a _base_ directory - a slightly customized clone
|
||||
of the original configuration, and
|
||||
|
||||
- an _overlays_ directory, containing the kustomizations
|
||||
and patches required to create distinct _staging_
|
||||
and _production_ [variants] in a cluster.
|
||||
|
||||
Review the directory structure and differences:
|
||||
|
||||
<!-- @listFiles @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expecting something like:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP1
|
||||
> ├── base
|
||||
> │ ├── deployment.yaml
|
||||
> │ ├── env.startup.txt
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── service.yaml
|
||||
> └── overlays
|
||||
> ├── production
|
||||
> │ ├── deployment.yaml
|
||||
> │ └── kustomization.yaml
|
||||
> └── staging
|
||||
> ├── config.env
|
||||
> ├── deployment.yaml
|
||||
> └── kustomization.yaml
|
||||
> ```
|
||||
|
||||
Compare the output directly
|
||||
to see how _staging_ and _production_ differ:
|
||||
|
||||
<!-- @compareOutput -->
|
||||
```
|
||||
diff \
|
||||
<(kustomize build $OVERLAYS/staging) \
|
||||
<(kustomize build $OVERLAYS/production) |\
|
||||
more
|
||||
```
|
||||
|
||||
The difference output should look something like
|
||||
|
||||
> ```diff
|
||||
> (...truncated)
|
||||
> < name: staging-my-ldap-configmap-kftftt474h
|
||||
> ---
|
||||
> > name: production-my-ldap-configmap-k27f7hkg4f
|
||||
> 85c75
|
||||
> < name: staging-my-ldap-service
|
||||
> ---
|
||||
> > name: production-my-ldap-service
|
||||
> 97c87
|
||||
> < name: staging-my-ldap
|
||||
> ---
|
||||
> > name: production-my-ldap
|
||||
> 99c89
|
||||
> < replicas: 2
|
||||
> ---
|
||||
> > replicas: 6
|
||||
> (...truncated)
|
||||
> ```
|
||||
|
||||
|
||||
## Deploy
|
||||
|
||||
The individual resource sets are:
|
||||
|
||||
<!-- @buildStaging @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging
|
||||
```
|
||||
|
||||
<!-- @buildProduction @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/production
|
||||
```
|
||||
|
||||
To deploy, pipe the above commands to kubectl apply:
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/staging |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/production |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
@@ -1,5 +0,0 @@
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
- deployment.yaml
|
||||
namePrefix: production-
|
||||
@@ -1,9 +0,0 @@
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
- deployment.yaml
|
||||
nameprefix: staging-
|
||||
configMapGenerator:
|
||||
- name: env-config
|
||||
files:
|
||||
- config.env
|
||||
@@ -1,203 +0,0 @@
|
||||
# Demo: MySql
|
||||
|
||||
This example takes some off-the-shelf k8s resources
|
||||
designed for MySQL, and customizes them to suit a
|
||||
production scenario.
|
||||
|
||||
In the production environment we want:
|
||||
|
||||
- MySQL resource names to be prefixed by 'prod-'.
|
||||
- MySQL resources to have 'env: prod' labels.
|
||||
- MySQL to use persistent disk for storing data.
|
||||
|
||||
First make a place to work:
|
||||
<!-- @makeDemoHome @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Download resources
|
||||
|
||||
To keep this document shorter, the base resources
|
||||
needed to run MySql on a k8s cluster are off in a
|
||||
supplemental data directory rather than declared here
|
||||
as HERE documents.
|
||||
|
||||
Download them:
|
||||
|
||||
<!-- @downloadResources @test -->
|
||||
```
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" "https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/demos/mySql\
|
||||
/{deployment,secret,service}.yaml"
|
||||
```
|
||||
|
||||
### Initialize kustomization.yaml
|
||||
|
||||
The `kustomize` program gets its instructions from
|
||||
a file called `kustomization.yaml`.
|
||||
|
||||
Start this file:
|
||||
|
||||
<!-- @kustomizeYaml @test -->
|
||||
```
|
||||
touch $DEMO_HOME/kustomization.yaml
|
||||
```
|
||||
|
||||
### Add the resources
|
||||
|
||||
<!-- @addResources @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
|
||||
kustomize edit add resource secret.yaml
|
||||
kustomize edit add resource service.yaml
|
||||
kustomize edit add resource deployment.yaml
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml`'s resources section should contain:
|
||||
|
||||
> ```
|
||||
> resources:
|
||||
> - secret.yaml
|
||||
> - service.yaml
|
||||
> - deployment.yaml
|
||||
> ```
|
||||
|
||||
### Name Customization
|
||||
|
||||
Arrange for the MySQL resources to begin with prefix
|
||||
_prod-_ (since they are meant for the _production_
|
||||
environment):
|
||||
|
||||
<!-- @customizeLabel @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
|
||||
kustomize edit set nameprefix 'prod-'
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml` should have updated value of namePrefix field:
|
||||
|
||||
> ```
|
||||
> namePrefix: prod-
|
||||
> ```
|
||||
|
||||
This `namePrefix` directive adds _prod-_ to all
|
||||
resource names.
|
||||
|
||||
<!-- @genNamePrefixConfig @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME
|
||||
```
|
||||
|
||||
The output should contain:
|
||||
|
||||
> ```
|
||||
> apiVersion: v1
|
||||
> data:
|
||||
> password: YWRtaW4=
|
||||
> kind: Secret
|
||||
> metadata:
|
||||
> ....
|
||||
> name: prod-mysql-pass-d2gtcm2t2k
|
||||
> ---
|
||||
> apiVersion: v1
|
||||
> kind: Service
|
||||
> metadata:
|
||||
> ....
|
||||
> name: prod-mysql
|
||||
> spec:
|
||||
> ....
|
||||
> ---
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> ....
|
||||
> name: prod-mysql
|
||||
> spec:
|
||||
> selector:
|
||||
> ....
|
||||
> ```
|
||||
|
||||
### Label Customization
|
||||
|
||||
We want resources in production environment to have
|
||||
certain labels so that we can query them by label
|
||||
selector.
|
||||
|
||||
`kustomize` does not have `edit set label` command to add
|
||||
a label, but one can always edit `kustomization.yaml` directly:
|
||||
|
||||
<!-- @customizeLabels @test -->
|
||||
```
|
||||
sed -i 's/app: helloworld/app: prod/' \
|
||||
$DEMO_HOME/kustomization.yaml
|
||||
```
|
||||
|
||||
At this point, running `kustomize build` will
|
||||
generate MySQL configs with name-prefix 'prod-' and
|
||||
labels `env:prod`.
|
||||
|
||||
### Storage customization
|
||||
|
||||
Off the shelf MySQL uses `emptyDir` type volume, which
|
||||
gets wiped away if the MySQL Pod is recreated, and that
|
||||
is certainly not desirable for production
|
||||
environment. So we want to use Persistent Disk in
|
||||
production. kustomize lets you apply `patches` to the
|
||||
resources.
|
||||
|
||||
<!-- @createPatchFile @test -->
|
||||
```
|
||||
cat <<'EOF' > $DEMO_HOME/persistent-disk.yaml
|
||||
apiVersion: apps/v1beta2 # for versions before 1.9.0 use apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
volumes:
|
||||
- name: mysql-persistent-storage
|
||||
emptyDir: null
|
||||
gcePersistentDisk:
|
||||
pdName: mysql-persistent-storage
|
||||
EOF
|
||||
```
|
||||
|
||||
Add the patch file to `kustomization.yaml`:
|
||||
|
||||
<!-- @specifyPatch @test -->
|
||||
```
|
||||
cat <<'EOF' >> $DEMO_HOME/kustomization.yaml
|
||||
patches:
|
||||
- persistent-disk.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Lets break this down:
|
||||
|
||||
- In the first step, we created a YAML file named
|
||||
`persistent-disk.yaml` to patch the resource defined
|
||||
in deployment.yaml
|
||||
|
||||
- Then we added `persistent-disk.yaml` to list of
|
||||
`patches` in `kustomization.yaml`. `kustomize build`
|
||||
will apply this patch to the deployment resource with
|
||||
the name `mysql` as defined in the patch.
|
||||
|
||||
|
||||
The output of the following command can now be applied
|
||||
to the cluster (i.e. piped to `kubectl apply`) to
|
||||
create the production environment.
|
||||
|
||||
<!-- @finalInflation @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME # | kubectl apply -f -
|
||||
```
|
||||
@@ -1,9 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: mysql-pass-d2gtcm2t2k
|
||||
type: Opaque
|
||||
data:
|
||||
# Default password is "admin".
|
||||
password: YWRtaW4=
|
||||
@@ -1,307 +0,0 @@
|
||||
# Demo: SpringBoot
|
||||
|
||||
In this tutorial, you will learn - how to use `kustomize` to customize a basic Spring Boot application's
|
||||
k8s configuration for production use cases.
|
||||
|
||||
In the production environment we want to customize the following:
|
||||
|
||||
- add application specific configuration for this Spring Boot application
|
||||
- configure prod DB access configuration
|
||||
- resource names to be prefixed by 'prod-'.
|
||||
- resources to have 'env: prod' labels.
|
||||
- JVM memory to be properly set.
|
||||
- health check and readiness check.
|
||||
|
||||
First make a place to work:
|
||||
<!-- @makeDemoHome @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Download resources
|
||||
|
||||
To keep this document shorter, the base resources
|
||||
needed to run springboot on a k8s cluster are off in a
|
||||
supplemental data directory rather than declared here
|
||||
as HERE documents.
|
||||
|
||||
Download them:
|
||||
|
||||
<!-- @downloadResources @test -->
|
||||
```
|
||||
CONTENT="https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/demos/springboot"
|
||||
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" \
|
||||
"$CONTENT/base/{deployment,service}.yaml"
|
||||
```
|
||||
|
||||
### Initialize kustomization.yaml
|
||||
|
||||
The `kustomize` program gets its instructions from
|
||||
a file called `kustomization.yaml`.
|
||||
|
||||
Start this file:
|
||||
|
||||
<!-- @kustomizeYaml @test -->
|
||||
```
|
||||
touch $DEMO_HOME/kustomization.yaml
|
||||
```
|
||||
|
||||
### Add the resources
|
||||
|
||||
<!-- @addResources @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
|
||||
kustomize edit add resource service.yaml
|
||||
kustomize edit add resource deployment.yaml
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml`'s resources section should contain:
|
||||
|
||||
> ```
|
||||
> resources:
|
||||
> - service.yaml
|
||||
> - deployment.yaml
|
||||
> ```
|
||||
|
||||
### Add configMap generator
|
||||
|
||||
<!-- @addConfigMap @test -->
|
||||
```
|
||||
echo "app.name=Kustomize Demo" >$DEMO_HOME/application.properties
|
||||
|
||||
kustomize edit add configmap demo-configmap \
|
||||
--from-file application.properties
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml`'s configMapGenerator section should contain:
|
||||
|
||||
> ```
|
||||
> configMapGenerator:
|
||||
> - files:
|
||||
> - application.properties
|
||||
> name: demo-configmap
|
||||
> ```
|
||||
|
||||
### Customize configMap
|
||||
|
||||
We want to add database credentials for the prod environment. In general, these credentials can be put into the file `application.properties`.
|
||||
However, for some cases, we want to keep the credentials in a different file and keep application specific configs in `application.properties`.
|
||||
With this clear separation, the credentials and application specific things can be managed and maintained flexibly by different teams.
|
||||
For example, application developers only tune the application configs in `application.properties` and operation teams or SREs
|
||||
only care about the credentials.
|
||||
|
||||
For Spring Boot application, we can set an active profile through the environment variable `spring.profiles.active`. Then
|
||||
the application will pick up an extra `application-<profile>.properties` file. With this, we can customize the configMap in two
|
||||
steps. Add an environment variable through the patch and add a file to the configMap.
|
||||
|
||||
<!-- @customizeConfigMap @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/patch.yaml
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sbdemo
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: sbdemo
|
||||
env:
|
||||
- name: spring.profiles.active
|
||||
value: prod
|
||||
EOF
|
||||
|
||||
kustomize edit add patch patch.yaml
|
||||
|
||||
cat <<EOF >$DEMO_HOME/application-prod.properties
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.datasource.url=jdbc:mysql://<prod_database_host>:3306/db_example
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=admin
|
||||
EOF
|
||||
|
||||
kustomize edit add configmap \
|
||||
demo-configmap --from-file application-prod.properties
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml`'s configMapGenerator section should contain:
|
||||
> ```
|
||||
> configMapGenerator:
|
||||
> - files:
|
||||
> - application.properties
|
||||
> - application-prod.properties
|
||||
> name: demo-configmap
|
||||
> ```
|
||||
|
||||
### Name Customization
|
||||
|
||||
Arrange for the resources to begin with prefix
|
||||
_prod-_ (since they are meant for the _production_
|
||||
environment):
|
||||
|
||||
<!-- @customizeLabel @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
kustomize edit set nameprefix 'prod-'
|
||||
```
|
||||
|
||||
`kustomization.yaml` should have updated value of namePrefix field:
|
||||
|
||||
> ```
|
||||
> namePrefix: prod-
|
||||
> ```
|
||||
|
||||
This `namePrefix` directive adds _prod-_ to all
|
||||
resource names, as can be seen by building the
|
||||
resources:
|
||||
|
||||
<!-- @build1 @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME | grep prod-
|
||||
```
|
||||
|
||||
### Label Customization
|
||||
|
||||
We want resources in production environment to have
|
||||
certain labels so that we can query them by label
|
||||
selector.
|
||||
|
||||
`kustomize` does not have `edit set label` command to
|
||||
add a label, but one can always edit
|
||||
`kustomization.yaml` directly:
|
||||
|
||||
<!-- @customizeLabels @test -->
|
||||
```
|
||||
cat <<EOF >>$DEMO_HOME/kustomization.yaml
|
||||
commonLabels:
|
||||
env: prod
|
||||
EOF
|
||||
```
|
||||
|
||||
Confirm that the resources now all have names prefixed
|
||||
by `prod-` and the label tuple `env:prod`:
|
||||
|
||||
<!-- @build2 @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME | grep -C 3 env
|
||||
```
|
||||
|
||||
### Download Patch for JVM memory
|
||||
|
||||
When a Spring Boot application is deployed in a k8s cluster, the JVM is running inside a container. We want to set memory limit for the container and make sure
|
||||
the JVM is aware of that limit. In K8s deployment, we can set the resource limits for containers and inject these limits to
|
||||
some environment variables by downward API. When the container starts to run, it can pick up the environment variables and
|
||||
set JVM options accordingly.
|
||||
|
||||
Download the patch `memorylimit_patch.yaml`. It contains the memory limits setup.
|
||||
|
||||
<!-- @downloadPatch @test -->
|
||||
```
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" \
|
||||
"$CONTENT/overlays/production/{memorylimit_patch}.yaml"
|
||||
|
||||
cat $DEMO_HOME/memorylimit_patch.yaml
|
||||
```
|
||||
|
||||
The output contains
|
||||
|
||||
> ```
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: sbdemo
|
||||
> spec:
|
||||
> template:
|
||||
> spec:
|
||||
> containers:
|
||||
> - name: sbdemo
|
||||
> resources:
|
||||
> limits:
|
||||
> memory: 1250Mi
|
||||
> requests:
|
||||
> memory: 1250Mi
|
||||
> env:
|
||||
> - name: MEM_TOTAL_MB
|
||||
> valueFrom:
|
||||
> resourceFieldRef:
|
||||
> resource: limits.memory
|
||||
> ```
|
||||
|
||||
### Download Patch for health check
|
||||
We also want to add liveness check and readiness check in the production environment. Spring Boot application
|
||||
has end points such as `/actuator/health` for this. We can customize the k8s deployment resource to talk to Spring Boot end point.
|
||||
|
||||
Download the patch `healthcheck_patch.yaml`. It contains the liveness probes and readyness probes.
|
||||
|
||||
<!-- @downloadPatch @test -->
|
||||
```
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" \
|
||||
"$CONTENT/overlays/production/{healthcheck_patch}.yaml"
|
||||
|
||||
cat $DEMO_HOME/healthcheck_patch.yaml
|
||||
```
|
||||
|
||||
The output contains
|
||||
|
||||
> ```
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: sbdemo
|
||||
> spec:
|
||||
> template:
|
||||
> spec:
|
||||
> containers:
|
||||
> - name: sbdemo
|
||||
> livenessProbe:
|
||||
> httpGet:
|
||||
> path: /actuator/health
|
||||
> port: 8080
|
||||
> initialDelaySeconds: 10
|
||||
> periodSeconds: 3
|
||||
> readinessProbe:
|
||||
> initialDelaySeconds: 20
|
||||
> periodSeconds: 10
|
||||
> httpGet:
|
||||
> path: /actuator/info
|
||||
> port: 8080
|
||||
> ```
|
||||
|
||||
### Add patches
|
||||
|
||||
Add these patches to the kustomization:
|
||||
|
||||
<!-- @addPatch @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
kustomize edit add patch memorylimit_patch.yaml
|
||||
kustomize edit add patch healthcheck_patch.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml` should have patches field:
|
||||
|
||||
> ```
|
||||
> patches:
|
||||
> - patch.yaml
|
||||
> - memorylimit_patch.yaml
|
||||
> - healthcheck_patch.yaml
|
||||
> ```
|
||||
|
||||
The output of the following command can now be applied
|
||||
to the cluster (i.e. piped to `kubectl apply`) to
|
||||
create the production environment.
|
||||
|
||||
<!-- @finalBuild @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME # | kubectl apply -f -
|
||||
```
|
||||
@@ -1,7 +0,0 @@
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
- patch.yaml
|
||||
- healthcheck_patch.yaml
|
||||
- memorylimit_patch.yaml
|
||||
namePrefix: production-
|
||||
@@ -1,13 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: demo-configmap
|
||||
data:
|
||||
application.properties: |
|
||||
app.name=Staging Kinflate Demo
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.datasource.url=jdbc:mysql://<production_db_ip>:3306/db_example
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=admin
|
||||
server.tomcat.max-threads=20
|
||||
server.tomcat.min-spare-threads=3
|
||||
33
docs/INSTALL.md
Normal file
@@ -0,0 +1,33 @@
|
||||
[release page]: https://github.com/kubernetes-sigs/kustomize/releases
|
||||
[Go]: https://golang.org
|
||||
|
||||
## Installation
|
||||
|
||||
On macOS, you can install kustomize with Homebrew package
|
||||
manager:
|
||||
|
||||
brew install kustomize
|
||||
|
||||
For all operating systems, download a binary from the
|
||||
[release page].
|
||||
|
||||
Or try this to grab the latest official release
|
||||
using the command line:
|
||||
|
||||
```
|
||||
opsys=linux # or darwin, or windows
|
||||
curl -s https://api.github.com/repos/kubernetes-sigs/kustomize/releases/latest |\
|
||||
grep browser_download |\
|
||||
grep $opsys |\
|
||||
cut -d '"' -f 4 |\
|
||||
xargs curl -O -L
|
||||
mv kustomize_*_${opsys}_amd64 kustomize
|
||||
chmod u+x kustomize
|
||||
```
|
||||
|
||||
To install from head with [Go] v1.10.1 or higher:
|
||||
|
||||
<!-- @installkustomize @test -->
|
||||
```
|
||||
go get sigs.k8s.io/kustomize
|
||||
```
|
||||
23
docs/README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Kustomize docs
|
||||
|
||||
* [installation instructions](INSTALL.md)
|
||||
|
||||
* [kustomization.yaml](kustomization.yaml) - Example of a
|
||||
[kustomization](glossary.md#kustomization)
|
||||
with explanations of each field.
|
||||
|
||||
* [workflow](workflows.md) - Some steps one might take in using
|
||||
bespoke and off-the-shelf configurations.
|
||||
|
||||
* [glossary](glossary.md) - An attempt to disambiguiate terminology.
|
||||
|
||||
* [eschewed features](eschewedFeatures.md) - Why certain features are (currently)
|
||||
not supported in Kustomize.
|
||||
|
||||
* [contributing guidelines](../CONTRIBUTING.md) - Please read before sending a PR.
|
||||
|
||||
* [code of conduct](../code-of-conduct.md)
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
docs/base.jpg
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 40 KiB |
85
docs/eschewedFeatures.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Eschewed Features
|
||||
|
||||
For a bigger picture about why kustomize
|
||||
does some things and not others, see the
|
||||
glossary entry for [DAM].
|
||||
|
||||
## Removal directives
|
||||
|
||||
`kustomize` supports configurations that can be reasoned about as
|
||||
_compositions_ or _mixins_ - concepts that are widely accepted as
|
||||
a best practice in various programming languages.
|
||||
|
||||
To this end, `kustomize` offers various _addition_ directives. One
|
||||
can add labels, annotations, patches, resources and bases.
|
||||
Corresponding _removal_ directives are not offered.
|
||||
|
||||
Removal semantics would introduce many possibilities for
|
||||
inconsistency, and the need to add code to detect, report and
|
||||
reject it. It would also allow, and possibly encourage,
|
||||
unnecessarily complex configuration layouts.
|
||||
|
||||
When faced with a situation where removal is desirable, it's
|
||||
always possible to remove things from a base like labels and
|
||||
annotations, and/or split multi-resource manifests into individual
|
||||
resource files - then add things back as desired via the
|
||||
[kustomization].
|
||||
|
||||
If the underlying base is outside of one's control, an [OTS
|
||||
workflow] is the recommended best practice. Fork the base, remove
|
||||
what you don't want and commit it to your private fork, then use
|
||||
kustomize on your fork. As often as desired, use _git rebase_ to
|
||||
capture improvements from the upstream base.
|
||||
|
||||
## Build-time side effects from CLI args or env variables
|
||||
|
||||
`kustomize` supports the best practice of storing one's
|
||||
entire configuration in a version control system.
|
||||
|
||||
Changing `kustomize build` configuration output as a result
|
||||
of additional arguments or flags to `build`, or by
|
||||
consulting shell environment variable values in `build`
|
||||
code, would violate that goal.
|
||||
|
||||
`kustomize` insteads offers [kustomization] file `edit`
|
||||
commands. Like any shell command, they can accept
|
||||
environment variable arguments.
|
||||
|
||||
For example, to set the tag used on an image to match an
|
||||
environment variable, run
|
||||
|
||||
```
|
||||
kustomize edit set imagetag nginx:$MY_NGINX_VERSION
|
||||
```
|
||||
|
||||
as part of some encapsulating work flow executed before
|
||||
`kustomize build`.
|
||||
|
||||
|
||||
## Globs in kustomization files
|
||||
|
||||
`kustomize` supports the best practice of storing one's
|
||||
entire configuration in a version control system.
|
||||
|
||||
Globbing the local file system for files not explicitly
|
||||
declared in the [kustomization] file at `kustomize build` time
|
||||
would violate that goal.
|
||||
|
||||
Allowing globbing in a kustomization file would also introduce
|
||||
the same problems as allowing globbing in [java import]
|
||||
declarations or BUILD/Makefile dependency rules.
|
||||
|
||||
`kustomize` will instead provide kustomization file editting
|
||||
commands that accept globbed arguments, expand them at _edit
|
||||
time_ relative to the local file system, and store the resulting
|
||||
explicit names into the kustomization file.
|
||||
|
||||
In this way the resources, patches and bases used at _build time_
|
||||
remain explicitly declared in version control.
|
||||
|
||||
|
||||
[DAM]: glossary.md#declarative-application-management
|
||||
[base]: glossary.md#base
|
||||
[kustomization]: glossary.md#kustomization
|
||||
[OTS workflow]: workflows.md#off-the-shelf-configuration
|
||||
[java import]: https://www.codebyamir.com/blog/pitfalls-java-import-wildcards
|
||||
220
docs/glossary.md
@@ -1,7 +1,10 @@
|
||||
# Glossary
|
||||
|
||||
[CRD spec]: https://kubernetes.io/docs/tasks/access-kubernetes-api/custom-resources/custom-resource-definitions/
|
||||
[CRD]: #custom-resource-definition
|
||||
[DAM]: #declarative-application-management
|
||||
[Declarative Application Management]: https://github.com/kubernetes/community/blob/master/contributors/design-proposals/architecture/declarative-application-management.md
|
||||
[JSON]: https://www.json.org/
|
||||
[JSONPatch]: https://tools.ietf.org/html/rfc6902
|
||||
[Resource]: #resource
|
||||
[YAML]: http://www.yaml.org/start.html
|
||||
[application]: #application
|
||||
@@ -15,16 +18,20 @@
|
||||
[kubernetes]: #kubernetes
|
||||
[kustomize]: #kustomize
|
||||
[kustomization]: #kustomization
|
||||
[off-the-shelf]: #off-the-shelf
|
||||
[off-the-shelf]: #off-the-shelf-configuration
|
||||
[overlay]: #overlay
|
||||
[overlays]: #overlay
|
||||
[patch]: #patch
|
||||
[patches]: #patch
|
||||
[patchJson6902]: #patchjson6902
|
||||
[patchExampleJson6902]: https://github.com/kubernetes-sigs/kustomize/blob/master/examples/jsonpatch.md
|
||||
[patchesJson6902]: #patchjson6902
|
||||
[proposal]: https://github.com/kubernetes/community/pull/1629
|
||||
[rebase]: https://git-scm.com/docs/git-rebase
|
||||
[resource]: #resource
|
||||
[resources]: #resource
|
||||
[rpm]: https://en.wikipedia.org/wiki/Rpm_(software)
|
||||
[strategic-merge]: https://github.com/kubernetes/community/blob/master/contributors/devel/strategic-merge-patch.md
|
||||
[target]: #target
|
||||
[variant]: #variant
|
||||
[variants]: #variant
|
||||
@@ -68,25 +75,17 @@ management in k8s.
|
||||
|
||||
A _base_ is a [target] that some [overlay] modifies.
|
||||
|
||||
Any target, including an overlay, can be a base to
|
||||
Any target, including an [overlay], can be a base to
|
||||
another target.
|
||||
|
||||
A base has no knowledge of the overlays that refer to it.
|
||||
|
||||
A base is usable in isolation, i.e. one should
|
||||
be able to [apply] a base to a cluster directly.
|
||||
|
||||
For simple [gitops] management, a base configuration
|
||||
could be the _sole content of a git repository
|
||||
dedicated to that purpose_. Same with [overlays].
|
||||
Changes in a repo could generate a build, test and
|
||||
deploy cycle.
|
||||
|
||||
Some of the demos for [kustomize] will break from this
|
||||
idiom and store all demo config files in directories
|
||||
_next_ to the `kustomize` code so that the code and
|
||||
demos can be more easily maintained by the same group
|
||||
of people.
|
||||
|
||||
## bespoke configuration
|
||||
|
||||
@@ -100,22 +99,37 @@ simpler than the workflow associated with an
|
||||
periodically capturing someone else's upgrades to the
|
||||
[off-the-shelf] config.
|
||||
|
||||
## custom resource definition
|
||||
|
||||
One can extend the k8s API by making a
|
||||
Custom Resource Definition ([CRD spec]).
|
||||
|
||||
This defines a custom [resource] (CD), an entirely
|
||||
new resource that can be used alongside _native_
|
||||
resources like ConfigMaps, Deployments, etc.
|
||||
|
||||
Kustomize can customize a CD, but to do so
|
||||
kustomize must also be given the corresponding CRD
|
||||
so that it can interpret the structure correctly.
|
||||
|
||||
## declarative application management
|
||||
|
||||
_Declarative Application Management_ (DAM) is a [set of
|
||||
ideas](https://goo.gl/T66ZcD) aiming to ease management
|
||||
of k8s clusters.
|
||||
Kustomize aspires to support [Declarative Application Management],
|
||||
a set of best practices around managing k8s clusters.
|
||||
|
||||
* Works with any configuration, be it bespoke,
|
||||
In brief, kustomize should
|
||||
|
||||
* Work with any configuration, be it bespoke,
|
||||
off-the-shelf, stateless, stateful, etc.
|
||||
* Supports common customizations, and creation of
|
||||
[variants] (dev vs. staging vs. production).
|
||||
* Exposes and teaches native k8s APIs, rather than
|
||||
hiding them.
|
||||
* No friction integration with version control to
|
||||
* Support common customizations, and creation of
|
||||
[variants] (e.g. _development_ vs.
|
||||
_staging_ vs. _production_).
|
||||
* Expose and teach native k8s APIs, rather than
|
||||
hide them.
|
||||
* Add no friction to version control integration to
|
||||
support reviews and audit trails.
|
||||
* Composable with other tools in a unix sense.
|
||||
* Eschews crossing the line into templating, domain
|
||||
* Compose with other tools in a unix sense.
|
||||
* Eschew crossing the line into templating, domain
|
||||
specific languages, etc., frustrating the other
|
||||
goals.
|
||||
|
||||
@@ -135,18 +149,23 @@ Here's an [example](kustomization.yaml).
|
||||
|
||||
A kustomization contains fields falling into these categories:
|
||||
|
||||
* Immediate customization declarations, e.g.
|
||||
_namePrefix_, _commonLabels_, etc.
|
||||
* Resource _generators_ for configmaps and secrets.
|
||||
* References to _external files_ in these categories:
|
||||
* _Customization operators_ for modifying operands, e.g.
|
||||
_namePrefix_, _nameSuffix_, _commonLabels_, _patches_, etc.
|
||||
|
||||
* _Customization operands_:
|
||||
* [resources] - completely specified k8s API objects,
|
||||
e.g. `deployment.yaml`, `configmap.yaml`, etc.
|
||||
* [patches] - _partial_ resources that modify full
|
||||
resources defined in a [base]
|
||||
(only meaningful in an [overlay]).
|
||||
* [bases] - path to a directory containing
|
||||
a [kustomization] (only meaningful in an [overlay]).
|
||||
* (_TBD_) Standard k8s API kind-version fields.
|
||||
* [bases] - paths or github URLs specifying directories
|
||||
containing a [kustomization]. These bases may
|
||||
be subjected to more customization, or merely
|
||||
included in the output.
|
||||
* [CRD]s - custom resource definition files, to allow use
|
||||
of _custom_ resources in the _resources_ list.
|
||||
Not an actual operand - but allows the use of new operands.
|
||||
|
||||
* Generators, for creating more resources
|
||||
(configmaps and secrets) which can then be
|
||||
customized.
|
||||
|
||||
## kubernetes
|
||||
|
||||
@@ -162,10 +181,10 @@ It's often abbreviated as _k8s_.
|
||||
|
||||
An object, expressed in a YAML or JSON file, with the
|
||||
[fields required] by kubernetes. Basically just a
|
||||
`kind` field to identify the type, a `metadata/name`
|
||||
field to identify the variant, and an `apiVersion`
|
||||
field to identify the version (if there's more than one
|
||||
version).
|
||||
_kind_ field to identify the type, a _metadata/name_
|
||||
field to identify the particular instance, and an
|
||||
_apiVersion_ field to identify the version (if there's
|
||||
more than one version).
|
||||
|
||||
## kustomize
|
||||
|
||||
@@ -210,19 +229,24 @@ An _overlay_ is a [target] that modifies (and thus
|
||||
depends on) another target.
|
||||
|
||||
The [kustomization] in an overlay refers to (via file
|
||||
path, URI or other method) _some other kustomization_,
|
||||
path, URI or other method) some other kustomization,
|
||||
known as its [base].
|
||||
|
||||
An overlay is unusable without its base.
|
||||
|
||||
An overlay supports the typical notion of a
|
||||
_development_, _QA_, _staging_ and _production_
|
||||
environment variants.
|
||||
An overlay may act as a base to another overlay.
|
||||
|
||||
The configuration of these environments is specified in
|
||||
individual overlays (one per environment) that all
|
||||
refer to a common base that holds common configuration.
|
||||
One configures the cluster like this:
|
||||
Overlays make the most sense when there is _more than
|
||||
one_, because they create different [variants] of a
|
||||
common base - e.g. _development_, _QA_, _staging_ and
|
||||
_production_ environment variants.
|
||||
|
||||
These variants use the same overall resources, and vary
|
||||
in relatively simple ways, e.g. the number of replicas
|
||||
in a deployment, the CPU to a particular pod, the data
|
||||
source used in a configmap, etc.
|
||||
|
||||
One configures a cluster like this:
|
||||
|
||||
> ```
|
||||
> kustomize build someapp/overlays/staging |\
|
||||
@@ -232,10 +256,9 @@ One configures the cluster like this:
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
|
||||
Usage of the base is implicit (the overlay's kustomization
|
||||
points to the base).
|
||||
Usage of the base is implicit - the overlay's
|
||||
kustomization points to the base.
|
||||
|
||||
An overlay may act as a base to another overlay.
|
||||
|
||||
## package
|
||||
|
||||
@@ -246,34 +269,66 @@ management tool in the tradition of, say, [apt] or
|
||||
|
||||
## patch
|
||||
|
||||
A _patch_ is a partially defined k8s resource with a
|
||||
name that must match a resource already known per
|
||||
traversal rules built into [kustomize].
|
||||
General instructions to modify a resource.
|
||||
|
||||
_Patch_ is a field in the kustomization, distinct from
|
||||
resources, because a patch file looks like a resource
|
||||
file, but has different semantics. A patch depends on
|
||||
(modifies) a resource, whereas a resource has no
|
||||
dependencies. Since any resource file can be used as a
|
||||
patch, one cannot reliably distinguish a resource from
|
||||
a patch just by looking at the file's [YAML].
|
||||
There are two alternative techniques with similar
|
||||
power but different notation - the
|
||||
[strategic merge patch](#patchstrategicmerge)
|
||||
and the [JSON patch](#patchjson6902).
|
||||
|
||||
## patchStrategicMerge
|
||||
|
||||
A _patchStrategicMerge_ is [strategic-merge]-style patch (SMP).
|
||||
|
||||
An SMP looks like an incomplete YAML specification of
|
||||
a k8s resource. The SMP includes `TypeMeta`
|
||||
fields to establish the group/version/kind/name of the
|
||||
[resource] to patch, then just enough remaining fields
|
||||
to step into a nested structure to specify a new field
|
||||
value, e.g. an image tag.
|
||||
|
||||
By default, an SMP _replaces_ values. This
|
||||
usually desired when the target value is a simple
|
||||
string, but may not be desired when the target
|
||||
value is a list.
|
||||
|
||||
To change this
|
||||
default behavior, add a _directive_. Recognized
|
||||
directives include _replace_ (the default), _merge_
|
||||
(avoid replacing a list), _delete_ and a few more
|
||||
(see [these notes][strategic-merge]).
|
||||
|
||||
Fun fact - any resource file can be used as
|
||||
an SMP, overwriting matching fields in another
|
||||
resource with the same group/version/kind/name,
|
||||
but leaving all other fields as they were.
|
||||
|
||||
TODO(monopole): add ptr to example.
|
||||
|
||||
## patchJson6902
|
||||
|
||||
A _patchJson6902_ refers to a kubernetes [resource] and
|
||||
a [JSONPatch] specifying how to change the resource.
|
||||
|
||||
A _patchJson6902_ can do almost everything a
|
||||
_patchStrategicMerge_ can do, but with a briefer
|
||||
syntax. See this [example][patchExampleJson6902].
|
||||
|
||||
## resource
|
||||
|
||||
A _resource_, in the context of kustomize, is a path to
|
||||
a [YAML] or [JSON] file that completely defines a
|
||||
functional k8s API object, like a deployment or a
|
||||
configmap.
|
||||
A _resource_ in the context of a REST-ful API is the
|
||||
target object of an HTTP operation like _GET_, _PUT_ or
|
||||
_POST_. k8s offers a REST-ful API surface to interact
|
||||
with clients.
|
||||
|
||||
A _resource_, in the context of kustomization file,
|
||||
is a path to a [YAML] or [JSON] file describing
|
||||
a k8s API object, like a Deployment or a
|
||||
ConfigmMap.
|
||||
|
||||
More generally, a resource can be any correct YAML file
|
||||
that [defines an object](https://kubernetes.io/docs/concepts/overview/working-with-objects/kubernetes-objects/#required-fields)
|
||||
with a `kind` and a `metadata/name` field.
|
||||
|
||||
|
||||
A _resource_ in the content of a REST-ful API is the
|
||||
target of an HTTP operation like _GET_, _PUT_ or
|
||||
_POST_. k8s offers a RESTful API surface to interact
|
||||
with clients.
|
||||
with a _kind_ and a _metadata/name_ field.
|
||||
|
||||
|
||||
## sub-target / sub-application / sub-package
|
||||
@@ -289,9 +344,8 @@ The _target_ is the argument to `kustomize build`, e.g.:
|
||||
> kustomize build $target
|
||||
> ```
|
||||
|
||||
`$target` must be a path to a directory that
|
||||
immediately contains a file called
|
||||
`kustomization.yaml` (i.e. a [kustomization]).
|
||||
`$target` must be a path or a url to a directory that
|
||||
immediately contains a [kustomization].
|
||||
|
||||
The target contains, or refers to, all the information
|
||||
needed to create customized resources to send to the
|
||||
@@ -304,15 +358,15 @@ A target is a [base] or an [overlay].
|
||||
A _variant_ is the outcome, in a cluster, of applying
|
||||
an [overlay] to a [base].
|
||||
|
||||
> E.g., a _staging_ and _production_ overlay both modify some
|
||||
> common base to create distinct variants.
|
||||
>
|
||||
> The _staging_ variant is the set of resources
|
||||
> exposed to quality assurance testing, or to some
|
||||
> external users who'd like to see what the next
|
||||
> version of production will look like.
|
||||
>
|
||||
> The _production_ variant is the set of resources
|
||||
> exposed to production traffic, and thus may employ
|
||||
> deployments with a large number of replicas and higher
|
||||
> cpu and memory requests.
|
||||
E.g., a _staging_ and _production_ overlay both modify
|
||||
some common base to create distinct variants.
|
||||
|
||||
The _staging_ variant is the set of resources exposed
|
||||
to quality assurance testing, or to some external users
|
||||
who'd like to see what the next version of production
|
||||
will look like.
|
||||
|
||||
The _production_ variant is the set of resources
|
||||
exposed to production traffic, and thus may employ
|
||||
deployments with a large number of replicas and higher
|
||||
cpu and memory requests.
|
||||
|
||||
@@ -32,12 +32,21 @@
|
||||
# visible in configuration reviews.
|
||||
# ----------------------------------------------------
|
||||
|
||||
# Adds namespace to all resources.
|
||||
namespace: my-namespace
|
||||
|
||||
# Value of this field is prepended to the
|
||||
# names of all resources, e.g. a deployment named
|
||||
# "wordpress" becomes "alices-wordpress".
|
||||
namePrefix: alices-
|
||||
|
||||
# Value of this field is appended to the
|
||||
# names of all resources, e.g. a deployment named
|
||||
# "wordpress" becomes "wordpress-v2".
|
||||
# The suffix is appended before content hash
|
||||
# if resource type is ConfigMap or Secret.
|
||||
nameSuffix: -v2
|
||||
|
||||
# Labels to add to all resources and selectors.
|
||||
commonLabels:
|
||||
someName: someValue
|
||||
@@ -61,13 +70,18 @@ resources:
|
||||
|
||||
# Each entry in this list results in the creation of
|
||||
# one ConfigMap resource (it's a generator of n maps).
|
||||
# The example below creates a ConfigMap with the
|
||||
# names and contents of the given files.
|
||||
# The example below creates two ConfigMaps. One with the
|
||||
# names and contents of the given files, the other with
|
||||
# key/value as data.
|
||||
configMapGenerator:
|
||||
- name: myJavaServerProps
|
||||
files:
|
||||
- application.properties
|
||||
- more.properties
|
||||
- name: myJavaServerEnvVars
|
||||
literals:
|
||||
- JAVA_HOME=/opt/java/jdk
|
||||
- JAVA_TOOL_OPTIONS=-agentlib:hprof
|
||||
|
||||
# Each entry in this list results in the creation of
|
||||
# one Secret resource (it's a generator of n secrets).
|
||||
@@ -80,11 +94,48 @@ secretGenerator:
|
||||
tls.crt: "cat secret/tls.cert"
|
||||
tls.key: "cat secret/tls.key"
|
||||
type: "kubernetes.io/tls"
|
||||
- name: downloaded_secret
|
||||
# timeoutSeconds specifies the number of seconds to
|
||||
# wait for the commands below. It defaults to 5 seconds.
|
||||
timeoutSeconds: 30
|
||||
commands:
|
||||
username: "curl -s https://path/to/secrets/username.yaml"
|
||||
password: "curl -s https://path/to/secrets/password.yaml"
|
||||
type: Opaque
|
||||
- name: env_file_secret
|
||||
# envCommand is similar to command but outputs lines of key=val pairs
|
||||
# i.e. a Docker .env file or a .ini file.
|
||||
# you can only specify one envCommand per secret.
|
||||
envCommand: printf \"DB_USERNAME=admin\nDB_PASSWORD=somepw\"
|
||||
type: Opaque
|
||||
|
||||
# generatorOptions modify behavior of all ConfigMap and Secret generators
|
||||
generatorOptions:
|
||||
# labels to add to all generated resources
|
||||
labels:
|
||||
kustomize.generated.resources: somevalue
|
||||
# annotations to add to all generated resources
|
||||
annotations:
|
||||
kustomize.generated.resource: somevalue
|
||||
# timeoutSeconds specifies the timeout for commands
|
||||
timeoutSeconds: 30
|
||||
# shell and arguments to use as a context for commands used in resource
|
||||
# generation. Default at time of writing: ["sh", "-c"]
|
||||
shell: ["sh", "-c"]
|
||||
# disableNameSuffixHash is true disables the default behavior of adding a
|
||||
# suffix to the names of generated resources that is a hash of
|
||||
# the resource contents.
|
||||
disableNameSuffixHash: true
|
||||
|
||||
# Each entry in this list should resolve to a directory
|
||||
# containing a kustomization file, else the
|
||||
# customization fails.
|
||||
#
|
||||
# The entry could be a relative path pointing to a local directory
|
||||
# or a url pointing to a directory in a remote repo.
|
||||
# The url should follow hashicorp/go-getter URL format
|
||||
# https://github.com/hashicorp/go-getter#url-format
|
||||
#
|
||||
# The presence of this field means this file (the file
|
||||
# you a reading) is an _overlay_ that further
|
||||
# customizes information coming from these _bases_.
|
||||
@@ -95,6 +146,9 @@ secretGenerator:
|
||||
# etc. that differ from the common base).
|
||||
bases:
|
||||
- ../../base
|
||||
- github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6
|
||||
- github.com/Liujingfang1/mysql
|
||||
- github.com/Liujingfang1/kustomize//examples/helloWorld?ref=test-branch
|
||||
|
||||
# Each entry in this list should resolve to
|
||||
# a partial or complete resource definition file.
|
||||
@@ -113,3 +167,122 @@ patches:
|
||||
- service_port_8888.yaml
|
||||
- deployment_increase_replicas.yaml
|
||||
- deployment_increase_memory.yaml
|
||||
|
||||
# Each entry in this list should resolve to
|
||||
# a kubernetes object and a JSON patch that will be applied
|
||||
# to the object.
|
||||
# The JSON patch is documented at https://tools.ietf.org/html/rfc6902
|
||||
#
|
||||
# target field points to a kubernetes object within the same kustomization
|
||||
# by the object's group, version, kind, name and namespace.
|
||||
# path field is a relative file path of a JSON patch file.
|
||||
# The content in this patch file can be either in JSON format as
|
||||
#
|
||||
# [
|
||||
# {"op": "add", "path": "/some/new/path", "value": "value"},
|
||||
# {"op": "replace", "path": "/some/existing/path", "value": "new value"}
|
||||
# ]
|
||||
#
|
||||
# or in YAML format as
|
||||
#
|
||||
# - op: add
|
||||
# path: /some/new/path
|
||||
# value: value
|
||||
# - op:replace
|
||||
# path: /some/existing/path
|
||||
# value: new value
|
||||
#
|
||||
patchesJson6902:
|
||||
- target:
|
||||
version: v1
|
||||
kind: Deployment
|
||||
name: my-deployment
|
||||
path: add_init_container.yaml
|
||||
- target:
|
||||
version: v1
|
||||
kind: Service
|
||||
name: my-service
|
||||
path: add_service_annotation.yaml
|
||||
|
||||
# Each entry in this list should be a relative path to
|
||||
# a file for custom resource definition(CRD).
|
||||
#
|
||||
# The presence of this field is to allow kustomize be
|
||||
# aware of CRDs and apply proper
|
||||
# transformation for any objects in those types.
|
||||
#
|
||||
# Typical use case: A CRD object refers to a ConfigMap object.
|
||||
# In kustomization, the ConfigMap object name may change by adding namePrefix, nameSuffix, or hashing
|
||||
# The name reference for this ConfigMap object in CRD object need to be
|
||||
# updated with namePrefix, nameSuffix, or hashing in the same way.
|
||||
crds:
|
||||
- crds/typeA.yaml
|
||||
- crds/typeB.yaml
|
||||
|
||||
# Vars are used to insert values from resources that cannot be referenced
|
||||
# otherwise. For example if you need to pass a Service's name to the arguments
|
||||
# or environment variables of a program but without hard coding the actual name
|
||||
# of the Service you'd insert `$(MY_SERVICE_NAME)` into the value field of the
|
||||
# env var or into the command or args of the container as shown here:
|
||||
# ```
|
||||
# containers:
|
||||
# - image: myimage
|
||||
# command: ["start", "--host", "$(MY_SERVICE_NAME)"]
|
||||
# env:
|
||||
# - name: SECRET_TOKEN
|
||||
# value: $(SOME_SECRET_NAME)
|
||||
# ```
|
||||
#
|
||||
# Then you'll add an entry to `vars:` like shown below with the same name
|
||||
# and a reference to the resource from which to pull the field's value.
|
||||
# The actual field's path is optional and by default it will use
|
||||
# `metadata.name`. Currently only string type fields are supported, no integers
|
||||
# or booleans, etc. Also array access is currently not possible. For example getting
|
||||
# the image field of container number 2 inside of a pod can currently not be done.
|
||||
#
|
||||
# Not every location of a variable is supported. To see a complete list of locations
|
||||
# see the file [varreference.go](https://github.com/kubernetes-sigs/kustomize/blob/master/pkg/transformers/config/defaultconfig/varreference.go#L20).
|
||||
#
|
||||
# An example of a situation where you'd not use vars is when you'd like to set a
|
||||
# pod's `serviceAccountName`. In that case you would just reference the ServiceAccount
|
||||
# by name and Kustomize will resolve it to the eventual name while building the manifests.
|
||||
vars:
|
||||
- name: SOME_SECRET_NAME
|
||||
objref:
|
||||
kind: Secret
|
||||
name: my-secret
|
||||
apiVersion: v1
|
||||
- name: MY_SERVICE_NAME
|
||||
objref:
|
||||
kind: Service
|
||||
name: my-service
|
||||
apiVersion: v1
|
||||
fieldref:
|
||||
fieldpath: metadata.name
|
||||
- name: ANOTHER_DEPLOYMENTS_POD_RESTART_POLICY
|
||||
objref:
|
||||
kind: Deployment
|
||||
name: my-deployment
|
||||
apiVersion: apps/v1
|
||||
fieldref:
|
||||
fieldpath: spec.template.spec.restartPolicy
|
||||
|
||||
# ImageTags modify the tags for images without creating patches.
|
||||
# E.g. Given this fragment of a Deployment:
|
||||
# ```
|
||||
# containers:
|
||||
# - name: myapp
|
||||
# image: mycontainerregistry/myimage:v0
|
||||
# - name: nginxapp
|
||||
# image: nginx:1.7.9
|
||||
#```
|
||||
# one can change the tag of myimage to v1 and the tag of nginx to 1.8.0 with the following:
|
||||
#
|
||||
# It also supports digests. If digest is present newTag is ignored.
|
||||
imageTags:
|
||||
- name: mycontainerregistry/myimage
|
||||
newTag: v1
|
||||
- name: nginx
|
||||
newTag: 1.8.0
|
||||
- name: alpine
|
||||
digest: sha256:24a0c4b4a4c0eb97a1aabb8e29f18e917d05abfe1b7a7c07857230879ce7d3d3
|
||||
|
||||
BIN
docs/overlay.jpg
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
@@ -1,16 +1,16 @@
|
||||
[OTS]: glossary.md#off-the-shelf
|
||||
[OTS]: glossary.md#off-the-shelf-configuration
|
||||
[apply]: glossary.md#apply
|
||||
[applying]: glossary.md#apply
|
||||
[base]: glossary.md#base
|
||||
[fork]: https://guides.github.com/activities/forking/
|
||||
[variants]: glossary.md#variant
|
||||
[kustomization]: glossary.md#kustomization
|
||||
[off-the-shelf]: glossary.md#off-the-shelf
|
||||
[off-the-shelf]: glossary.md#off-the-shelf-configuration
|
||||
[overlays]: glossary.md#overlay
|
||||
[patch]: glossary.md#patch
|
||||
[patches]: glossary.md#patch
|
||||
[rebase]: https://git-scm.com/docs/git-rebase
|
||||
[resources]: glossary.md#resources
|
||||
[resources]: glossary.md#resource
|
||||
[workflowBespoke]: workflowBespoke.jpg
|
||||
[workflowOts]: workflowOts.jpg
|
||||
|
||||
@@ -21,14 +21,17 @@ use and maintain a configuration.
|
||||
|
||||
## Bespoke configuration
|
||||
|
||||
In this workflow, all configuration files are owned by
|
||||
the user. No content is incorporated from version
|
||||
In this workflow, all configuration (resource YAML) files
|
||||
are owned by the user. No content is incorporated from version
|
||||
control repositories owned by others.
|
||||
|
||||
![bespoke config workflow image][workflowBespoke]
|
||||
|
||||
#### 1) create a directory in version control
|
||||
|
||||
Speculate some overall cluster application called _ldap_;
|
||||
we want to keep its configuration in its own repo.
|
||||
|
||||
> ```
|
||||
> git init ~/ldap
|
||||
> ```
|
||||
@@ -64,8 +67,8 @@ specified in the base.
|
||||
Run kustomize, and pipe the output to [apply].
|
||||
|
||||
> ```
|
||||
> kustomize ~/ldap/overlays/staging | kubectl apply -f -
|
||||
> kustomize ~/ldap/overlays/production | kubectl apply -f -
|
||||
> kustomize build ~/ldap/overlays/staging | kubectl apply -f -
|
||||
> kustomize build ~/ldap/overlays/production | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
|
||||
@@ -85,13 +88,13 @@ is periodically consulted for updates.
|
||||
|
||||
The [base] directory is maintained in a repo whose
|
||||
upstream is an [OTS] configuration, in this case
|
||||
https://github.com/kinflate/ldap.
|
||||
some user's `ldap` repo:
|
||||
|
||||
> ```
|
||||
> mkdir ~/ldap
|
||||
> git clone https://github.com/$USER/ldap ~/ldap/base
|
||||
> cd ~/ldap/base
|
||||
> git remote add upstream git@github.com:kustomize/ldap
|
||||
> git remote add upstream git@github.com:$USER/ldap
|
||||
> ```
|
||||
|
||||
#### 3) create [overlays]
|
||||
@@ -107,17 +110,19 @@ The [overlays] are siblings to each other and to the
|
||||
> mkdir -p ~/ldap/overlays/production
|
||||
> ```
|
||||
|
||||
The user can maintain the `overlays` directory in a
|
||||
distinct repository.
|
||||
|
||||
#### 4) bring up [variants]
|
||||
|
||||
> ```
|
||||
> kustomize ~/ldap/overlays/staging | kubectl apply -f -
|
||||
> kustomize ~/ldap/overlays/production | kubectl apply -f -
|
||||
> kustomize build ~/ldap/overlays/staging | kubectl apply -f -
|
||||
> kustomize build ~/ldap/overlays/production | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
#### 5) (optionally) capture changes from upstream
|
||||
|
||||
The user can optionally [rebase] their [base] to
|
||||
The user can periodically [rebase] their [base] to
|
||||
capture changes made in the upstream repository.
|
||||
|
||||
> ```
|
||||
|
||||
49
examples/README.md
Normal file
@@ -0,0 +1,49 @@
|
||||
# Examples
|
||||
|
||||
These examples assume that `kustomize` is on your `$PATH`.
|
||||
|
||||
They are covered by [pre-commit](../bin/pre-commit.sh)
|
||||
tests, and should work with HEAD
|
||||
|
||||
<!-- @installkustomize @test -->
|
||||
```
|
||||
go get sigs.k8s.io/kustomize
|
||||
```
|
||||
|
||||
* [hello world](helloWorld/README.md) - Deploy multiple
|
||||
(differently configured) variants of a simple Hello
|
||||
World server.
|
||||
|
||||
* [LDAP](ldap/README.md) - Deploy multiple
|
||||
(differently configured) variants of a LDAP server.
|
||||
|
||||
* [mySql](mySql/README.md) - Create a MySQL production
|
||||
configuration from scratch.
|
||||
|
||||
* [springboot](springboot/README.md) - Create a Spring Boot
|
||||
application production configuration from scratch.
|
||||
|
||||
* [combineConfigs](combineConfigs.md) -
|
||||
Mixing configuration data from different owners
|
||||
(e.g. devops/SRE and developers).
|
||||
|
||||
* [configGenerations](configGeneration.md) -
|
||||
Rolling update when ConfigMapGenerator changes
|
||||
|
||||
* [generatorOptions](generatorOptions.md) - Modifying behavior of all ConfigMap and Secret generators.
|
||||
|
||||
* [breakfast](breakfast.md) - Customize breakfast for
|
||||
Alice and Bob.
|
||||
|
||||
* [vars](wordpress/README.md) - Injecting k8s runtime data into container arguments (e.g. to point wordpress to a SQL service) by vars.
|
||||
|
||||
* [image tags](imageTags.md) - Updating image tags without applying a patch.
|
||||
|
||||
* [multibases](multibases/README.md) - Composing three variants (dev, staging, production) with a common base.
|
||||
|
||||
* [remote target](remoteBuild.md) - Building a kustomization from a github URL
|
||||
|
||||
* [json patch](jsonpatch.md) - Apply a json patch in a kustomization
|
||||
|
||||
* [transformer configs](transformerconfigs/README.md) - Customize transformer configurations
|
||||
|
||||
@@ -73,7 +73,7 @@ commonLabels:
|
||||
who: alice
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
patchesStrategicMerge:
|
||||
- temperature.yaml
|
||||
EOF
|
||||
|
||||
@@ -96,7 +96,7 @@ commonLabels:
|
||||
who: bob
|
||||
bases:
|
||||
- ../../base
|
||||
patches:
|
||||
patchesStrategicMerge:
|
||||
- topping.yaml
|
||||
EOF
|
||||
|
||||
300
examples/combineConfigs.md
Normal file
@@ -0,0 +1,300 @@
|
||||
[overlay]: ../docs/glossary.md#overlay
|
||||
[target]: ../docs/glossary.md#target
|
||||
|
||||
# Demo: combining config data from devops and developers
|
||||
|
||||
Scenario: you have a Java-based server storefront in
|
||||
production that various internal development teams
|
||||
(signups, checkout, search, etc.) contribute to.
|
||||
|
||||
The server runs in different environments:
|
||||
_development_, _testing_, _staging_ and _production_,
|
||||
accepting configuration parameters from java property
|
||||
files.
|
||||
|
||||
Using one big properties file for each environment is
|
||||
difficult to manage. The files change frequently, and
|
||||
have to be changed by devops exclusively because
|
||||
|
||||
1. the files must at least partially agree on certain
|
||||
values that devops cares about and that developers
|
||||
ignore and
|
||||
1. because the production
|
||||
properties contain sensitive data like production
|
||||
database credentials.
|
||||
|
||||
## Property sharding
|
||||
|
||||
With some study, we notice that the properties are
|
||||
separable into categories.
|
||||
|
||||
### Common properties
|
||||
|
||||
E.g. internationalization data, static data like
|
||||
physical constants, location of external services, etc.
|
||||
|
||||
_Things that are the same regardless of environment._
|
||||
|
||||
Only one set of values is needed.
|
||||
|
||||
Place them in a file called
|
||||
|
||||
* `common.properties`
|
||||
|
||||
(relative location defined below).
|
||||
|
||||
### Plumbing properties
|
||||
|
||||
E.g. serving location of static content (HTML, CSS,
|
||||
javascript), location of product and customer database
|
||||
tables, ports expected by load balancers, log sinks,
|
||||
etc.
|
||||
|
||||
_The different values for these properties are
|
||||
precisely what sets the environments apart._
|
||||
|
||||
Devops or SRE will want full control over the values
|
||||
used in production. Testing will have fixed
|
||||
databases supporting testing. Developers will want
|
||||
to do whatever they want to try scenarios under
|
||||
development.
|
||||
|
||||
Places these values in
|
||||
|
||||
* `development/plumbing.properties`
|
||||
* `staging/plumbing.properties`
|
||||
* `production/plumbing.properties`
|
||||
|
||||
|
||||
### Secret properties
|
||||
|
||||
E.g. location of actual user tables, database
|
||||
credentials, decryption keys, etc.
|
||||
|
||||
_Things that are a subset of devops controls, that
|
||||
nobody else has (or should want) access to._
|
||||
|
||||
Places these values in
|
||||
|
||||
* `development/secret.properties`
|
||||
* `staging/secret.properties`
|
||||
* `production/secret.properties`
|
||||
|
||||
[kubernetes secret]: https://kubernetes.io/docs/tasks/inject-data-application/distribute-credentials-secure/
|
||||
|
||||
and control access to them with (for example) unix file
|
||||
owner and mode bits, or better yet, put them in
|
||||
a server dedicated to storing password protected
|
||||
secrets, and use a field called `secretGenerator`
|
||||
in your _kustomization_ to create a kubernetes
|
||||
secret holding them (not covering that here).
|
||||
|
||||
<!--
|
||||
secretGenerator:
|
||||
- name: app-tls
|
||||
commands:
|
||||
tls.crt: "cat tls.cert"
|
||||
tls.key: "cat tls.key"
|
||||
type: "kubernetes.io/tls"
|
||||
EOF
|
||||
-->
|
||||
|
||||
## A mixin approach to management
|
||||
|
||||
The way to create _n_ cluster environments that share
|
||||
some common information is to create _n_ overlays of a
|
||||
common base.
|
||||
|
||||
For the rest of this example, we'll do _n==2_, just
|
||||
_development_ and _production_, since adding more
|
||||
environments follows the same pattern.
|
||||
|
||||
A cluster environment is created by
|
||||
running `kustomize build` on a [target] that happens to
|
||||
be an [overlay].
|
||||
|
||||
[helloworld]: helloWorld/README.md
|
||||
|
||||
The following example will do that, but will focus on
|
||||
configMap construction, and not worry about how to
|
||||
connect the configMaps to deployments (that is covered
|
||||
in the [helloworld] example).
|
||||
|
||||
|
||||
All files - including the shared property files
|
||||
discussed above - will be created in a directory tree
|
||||
that is consistent with the base vs overlay file layout
|
||||
defined in the [helloworld] demo.
|
||||
|
||||
It will all live in this work directory:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Create the base
|
||||
|
||||
<!-- kubectl create configmap BOB --dry-run -o yaml --from-file db. -->
|
||||
|
||||
Make a place to put the base configuration:
|
||||
|
||||
<!-- @baseDir @test -->
|
||||
```
|
||||
mkdir -p $DEMO_HOME/base
|
||||
```
|
||||
|
||||
Make the data for the base. This direction by
|
||||
definition should hold resources common to all
|
||||
environments. Here we're only defining a java
|
||||
properties file, and a `kustomization` file that
|
||||
references it.
|
||||
|
||||
<!-- @baseKustomization @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/base/common.properties
|
||||
color=blue
|
||||
height=10m
|
||||
EOF
|
||||
|
||||
cat <<EOF >$DEMO_HOME/base/kustomization.yaml
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
files:
|
||||
- common.properties
|
||||
EOF
|
||||
```
|
||||
|
||||
|
||||
### Create and use the overlay for _development_
|
||||
|
||||
Make an abbreviation for the parent of the overlay
|
||||
directories:
|
||||
|
||||
<!-- @overlays @test -->
|
||||
```
|
||||
OVERLAYS=$DEMO_HOME/overlays
|
||||
```
|
||||
|
||||
Create the files that define the _development_ overlay:
|
||||
|
||||
<!-- @developmentFiles @test -->
|
||||
```
|
||||
mkdir -p $OVERLAYS/development
|
||||
|
||||
cat <<EOF >$OVERLAYS/development/plumbing.properties
|
||||
port=30000
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/development/secret.properties
|
||||
dbpassword=mothersMaidenName
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/development/kustomization.yaml
|
||||
bases:
|
||||
- ../../base
|
||||
namePrefix: dev-
|
||||
nameSuffix: -v1
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
behavior: merge
|
||||
files:
|
||||
- plumbing.properties
|
||||
- secret.properties
|
||||
EOF
|
||||
```
|
||||
|
||||
One can now generate the configMaps for development:
|
||||
|
||||
<!-- @runDev @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/development
|
||||
```
|
||||
|
||||
#### Check the ConfigMap name
|
||||
|
||||
The name of the generated `ConfigMap` is visible in this
|
||||
output.
|
||||
|
||||
The name should be something like `dev-my-configmap-v1-2gccmccgd5`:
|
||||
|
||||
* `"dev-"` comes from the `namePrefix` field,
|
||||
* `"my-configmap"` comes from the `configMapGenerator/name` field,
|
||||
* `"-v1"` comes from the `nameSuffix` field,
|
||||
* `"-2gccmccgd5"` comes from a deterministic hash that `kustomize`
|
||||
computes from the contents of the configMap.
|
||||
|
||||
The hash suffix is critical. If the configMap content
|
||||
changes, so does the configMap name, along with all
|
||||
references to that name that appear in the YAML output
|
||||
from `kustomize`.
|
||||
|
||||
The name change means deployments will do a rolling
|
||||
restart to get new data if this YAML is applied to the
|
||||
cluster using a command like
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/development | kubectl apply -f -
|
||||
> ```
|
||||
|
||||
A deployment has no means to automatically know when or
|
||||
if a configMap in use by the deployment changes.
|
||||
|
||||
If one changes a configMap without changing its name
|
||||
and all references to that name, one must imperatively
|
||||
restart the cluster to pick up the change.
|
||||
|
||||
The best practice is to treat configMaps as immutable.
|
||||
|
||||
Instead of editing configMaps, modify your declarative
|
||||
specification of the cluster's desired state to
|
||||
point deployments to _new_ configMaps with _new_ names.
|
||||
`kustomize` makes this easy with its
|
||||
`configMapGenerator` directive and associated naming
|
||||
controls. A GC process in the k8s master eventually
|
||||
deletes unused configMaps.
|
||||
|
||||
|
||||
### Create and use the overlay for _production_
|
||||
|
||||
Next, create the files for the _production_ overlay:
|
||||
|
||||
|
||||
<!-- @productionFiles @test -->
|
||||
```
|
||||
mkdir -p $OVERLAYS/production
|
||||
|
||||
cat <<EOF >$OVERLAYS/production/plumbing.properties
|
||||
port=8080
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/production/secret.properties
|
||||
dbpassword=thisShouldProbablyBeInASecretInstead
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/production/kustomization.yaml
|
||||
bases:
|
||||
- ../../base
|
||||
namePrefix: prod-
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
behavior: merge
|
||||
files:
|
||||
- plumbing.properties
|
||||
- secret.properties
|
||||
EOF
|
||||
```
|
||||
|
||||
One can now generate the configMaps for production:
|
||||
|
||||
<!-- @runProd @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/production
|
||||
```
|
||||
|
||||
A CICD process could apply this directly to
|
||||
the cluster using:
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/production | kubectl apply -f -
|
||||
> ```
|
||||
213
examples/configGeneration.md
Normal file
@@ -0,0 +1,213 @@
|
||||
[patch]: ../docs/glossary.md#patch
|
||||
[resource]: ../docs/glossary.md#resource
|
||||
[variant]: ../docs/glossary.md#variant
|
||||
|
||||
## ConfigMap generation and rolling updates
|
||||
|
||||
Kustomize provides two ways of adding ConfigMap in one `kustomization`, either by declaring ConfigMap as a [resource] or declaring ConfigMap from a ConfigMapGenerator. The formats inside `kustomization.yaml` are
|
||||
|
||||
> ```
|
||||
> # declare ConfigMap as a resource
|
||||
> resources:
|
||||
> - configmap.yaml
|
||||
>
|
||||
> # declare ConfigMap from a ConfigMapGenerator
|
||||
> configMapGenerator:
|
||||
> - name: a-configmap
|
||||
> files:
|
||||
> - configs/configfile
|
||||
> - configs/another_configfile
|
||||
> ```
|
||||
|
||||
The ConfigMaps declared as [resource] are treated the same way as other resources. Kustomize doesn't append any hash to the ConfigMap name. The ConfigMap declared from a ConfigMapGenerator is treated differently. A hash is appended to the name and any change in the ConfigMap will trigger a rolling update.
|
||||
|
||||
In this demo, the same [hello_world](helloWorld/README.md) is used while the ConfigMap declared as [resources] is replaced by a ConfigMap declared from a ConfigmapGenerator. The change in this ConfigMap will result in a hash change and a rolling update.
|
||||
|
||||
### Establish base and staging
|
||||
|
||||
Establish the base with a configMapGenerator
|
||||
<!-- @establishBase @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
|
||||
BASE=$DEMO_HOME/base
|
||||
mkdir -p $BASE
|
||||
|
||||
curl -s -o "$BASE/#1.yaml" "https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/examples/helloWorld\
|
||||
/{deployment,service}.yaml"
|
||||
|
||||
cat <<'EOF' >$BASE/kustomization.yaml
|
||||
commonLabels:
|
||||
app: hello
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
configMapGenerator:
|
||||
- name: the-map
|
||||
literals:
|
||||
- altGreeting=Good Morning!
|
||||
- enableRisky="false"
|
||||
EOF
|
||||
```
|
||||
|
||||
Establish the staging with a patch applied to the ConfigMap
|
||||
<!-- @establishStaging @test -->
|
||||
```
|
||||
OVERLAYS=$DEMO_HOME/overlays
|
||||
mkdir -p $OVERLAYS/staging
|
||||
|
||||
cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml
|
||||
namePrefix: staging-
|
||||
nameSuffix: -v1
|
||||
commonLabels:
|
||||
variant: staging
|
||||
org: acmeCorporation
|
||||
commonAnnotations:
|
||||
note: Hello, I am staging!
|
||||
bases:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- map.yaml
|
||||
EOF
|
||||
|
||||
cat <<EOF >$OVERLAYS/staging/map.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: the-map
|
||||
data:
|
||||
altGreeting: "Have a pineapple!"
|
||||
enableRisky: "true"
|
||||
EOF
|
||||
```
|
||||
|
||||
### Review
|
||||
|
||||
The _hello-world_ deployment running in this cluster is
|
||||
configured with data from a configMap.
|
||||
|
||||
The deployment refers to this map by name:
|
||||
|
||||
|
||||
<!-- @showDeployment @test -->
|
||||
```
|
||||
grep -C 2 configMapKeyRef $BASE/deployment.yaml
|
||||
```
|
||||
|
||||
Changing the data held by a live configMap in a cluster
|
||||
is considered bad practice. Deployments have no means
|
||||
to know that the configMaps they refer to have
|
||||
changed, so such updates have no effect.
|
||||
|
||||
The recommended way to change a deployment's
|
||||
configuration is to
|
||||
|
||||
1. create a new configMap with a new name,
|
||||
1. patch the _deployment_, modifying the name value of
|
||||
the appropriate `configMapKeyRef` field.
|
||||
|
||||
This latter change initiates rolling update to the pods
|
||||
in the deployment. The older configMap, when no longer
|
||||
referenced by any other resource, is eventually [garbage
|
||||
collected](https://github.com/kubernetes-sigs/kustomize/issues/242).
|
||||
|
||||
### How this works with kustomize
|
||||
|
||||
The _staging_ [variant] here has a configMap [patch]:
|
||||
|
||||
<!-- @showMapPatch @test -->
|
||||
```
|
||||
cat $OVERLAYS/staging/map.yaml
|
||||
```
|
||||
|
||||
This patch is by definition a named but not necessarily
|
||||
complete resource spec intended to modify a complete
|
||||
resource spec.
|
||||
|
||||
The ConfigMap it modifies is declared from a configMapGenerator.
|
||||
|
||||
<!-- @showMapBase @test -->
|
||||
```
|
||||
grep -C 4 configMapGenerator $BASE/kustomization.yaml
|
||||
```
|
||||
|
||||
For a patch to work, the names in the `metadata/name`
|
||||
fields must match.
|
||||
|
||||
However, the name values specified in the file are
|
||||
_not_ what gets used in the cluster. By design,
|
||||
kustomize modifies names of ConfigMaps declared from ConfigMapGenerator. To see the names
|
||||
ultimately used in the cluster, just run kustomize:
|
||||
|
||||
<!-- @grepStagingName @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging |\
|
||||
grep -B 8 -A 1 staging-the-map
|
||||
```
|
||||
|
||||
The configMap name is prefixed by _staging-_, per the
|
||||
`namePrefix` field in
|
||||
`$OVERLAYS/staging/kustomization.yaml`.
|
||||
|
||||
The configMap name is suffixed by _-v1_, per the
|
||||
`nameSuffix` field in
|
||||
`$OVERLAYS/staging/kustomization.yaml`.
|
||||
|
||||
The suffix to the configMap name is generated from a
|
||||
hash of the maps content - in this case the name suffix
|
||||
is _k25m8k5k5m_:
|
||||
|
||||
<!-- @grepStagingHash @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging | grep k25m8k5k5m
|
||||
```
|
||||
|
||||
Now modify the map patch, to change the greeting
|
||||
the server will use:
|
||||
|
||||
<!-- @changeMap @test -->
|
||||
```
|
||||
sed -i.bak 's/pineapple/kiwi/' $OVERLAYS/staging/map.yaml
|
||||
```
|
||||
|
||||
See the new greeting:
|
||||
|
||||
```
|
||||
kustomize build $OVERLAYS/staging |\
|
||||
grep -B 2 -A 3 kiwi
|
||||
```
|
||||
|
||||
Run kustomize again to see the new configMap names:
|
||||
|
||||
<!-- @grepStagingName @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging |\
|
||||
grep -B 8 -A 1 staging-the-map
|
||||
```
|
||||
|
||||
Confirm that the change in configMap content resulted
|
||||
in three new names ending in _cd7kdh48fd_ - one in the
|
||||
configMap name itself, and two in the deployment that
|
||||
uses the map:
|
||||
|
||||
<!-- @countHashes @test -->
|
||||
```
|
||||
test 3 == \
|
||||
$(kustomize build $OVERLAYS/staging | grep cd7kdh48fd | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
|
||||
Applying these resources to the cluster will result in
|
||||
a rolling update of the deployments pods, retargetting
|
||||
them from the _k25m8k5k5m_ maps to the _cd7kdh48fd_
|
||||
maps. The system will later garbage collect the
|
||||
unused maps.
|
||||
|
||||
## Rollback
|
||||
|
||||
To rollback, one would undo whatever edits were made to
|
||||
the configuation in source control, then rerun kustomize
|
||||
on the reverted configuration and apply it to the
|
||||
cluster.
|
||||
62
examples/generatorOptions.md
Normal file
@@ -0,0 +1,62 @@
|
||||
# Generator Options
|
||||
|
||||
Kustomize provides options to modify the behavior of ConfigMap and Secret generators. These options include
|
||||
|
||||
- disable appending a content hash suffix to the names of generated resources
|
||||
- adding labels to generated resources
|
||||
- adding annotations to generated resources
|
||||
- changing shell and arguments for getting data from commands
|
||||
- changing timeout for executing commands
|
||||
|
||||
This demo shows how to use these options. First create a workspace.
|
||||
```
|
||||
DEMO_HOME=$(mkdir -d)
|
||||
```
|
||||
|
||||
Create a kustomization and add a ConfigMap generator to it.
|
||||
|
||||
<!-- @createCMGenerator @test -->
|
||||
```
|
||||
cat > $DEMO_HOME/kustomization.yaml << EOF
|
||||
configMapGenerator:
|
||||
- name: my-configmap
|
||||
literals:
|
||||
- foo=bar
|
||||
- baz=qux
|
||||
EOF
|
||||
```
|
||||
|
||||
Add following generatorOptions
|
||||
<!-- @addGeneratorOptions @test -->
|
||||
```
|
||||
cat >> $DEMO_HOME/kustomization.yaml << EOF
|
||||
generatorOptions:
|
||||
disableNameSuffixHash: true
|
||||
labels:
|
||||
kustomize.generated.resource: somevalue
|
||||
annotations:
|
||||
annotations.only.for.generated: othervalue
|
||||
EOF
|
||||
```
|
||||
Run `kustomize build` and make sure that the generated ConfigMap
|
||||
|
||||
- doesn't have name suffix
|
||||
<!-- @verify @test -->
|
||||
```
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep "name: my-configmap$" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
- has label `kustomize.generated.resource: somevalue`
|
||||
```
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep -A 1 "labels" | grep "kustomize.generated.resource" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
- has annotation `annotations.only.for.generated: othervalue`
|
||||
```
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep -A 1 "annotations" | grep "annotations.only.for.generated" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
|
||||
311
examples/helloWorld/README.md
Normal file
@@ -0,0 +1,311 @@
|
||||
[base]: ../../docs/glossary.md#base
|
||||
[config]: https://github.com/kinflate/example-hello
|
||||
[gitops]: ../../docs/glossary.md#gitops
|
||||
[hello]: https://github.com/monopole/hello
|
||||
[kustomization]: ../../docs/glossary.md#kustomization
|
||||
[original]: https://github.com/kinflate/example-hello
|
||||
[overlay]: ../../docs/glossary.md#overlay
|
||||
[overlays]: ../../docs/glossary.md#overlay
|
||||
[patch]: ../../docs/glossary.md#patch
|
||||
[variant]: ../../docs/glossary.md#variant
|
||||
[variants]: ../../docs/glossary.md#variant
|
||||
|
||||
# Demo: hello world with variants
|
||||
|
||||
Steps:
|
||||
|
||||
1. Clone an existing configuration as a [base].
|
||||
1. Customize it.
|
||||
1. Create two different [overlays] (_staging_ and _production_)
|
||||
from the customized base.
|
||||
1. Run kustomize and kubectl to deploy staging and production.
|
||||
|
||||
First define a place to work:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
Alternatively, use
|
||||
|
||||
> ```
|
||||
> DEMO_HOME=~/hello
|
||||
> ```
|
||||
|
||||
## Establish the base
|
||||
|
||||
Let's run the [hello] service.
|
||||
|
||||
To use [overlays] to create [variants], we must
|
||||
first establish a common [base].
|
||||
|
||||
To keep this document shorter, the base resources are
|
||||
off in a supplemental data directory rather than
|
||||
declared here as HERE documents. Download them:
|
||||
|
||||
<!-- @downloadBase @test -->
|
||||
```
|
||||
BASE=$DEMO_HOME/base
|
||||
mkdir -p $BASE
|
||||
|
||||
curl -s -o "$BASE/#1.yaml" "https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/examples/helloWorld\
|
||||
/{configMap,deployment,kustomization,service}.yaml"
|
||||
```
|
||||
|
||||
Look at the directory:
|
||||
|
||||
<!-- @runTree @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expect something like:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP
|
||||
> └── base
|
||||
> ├── configMap.yaml
|
||||
> ├── deployment.yaml
|
||||
> ├── kustomization.yaml
|
||||
> └── service.yaml
|
||||
> ```
|
||||
|
||||
|
||||
One could immediately apply these resources to a
|
||||
cluster:
|
||||
|
||||
> ```
|
||||
> kubectl apply -f $DEMO_HOME/base
|
||||
> ```
|
||||
|
||||
to instantiate the _hello_ service. `kubectl`
|
||||
would only recognize the resource files.
|
||||
|
||||
### The Base Kustomization
|
||||
|
||||
The `base` directory has a [kustomization] file:
|
||||
|
||||
<!-- @showKustomization @test -->
|
||||
```
|
||||
more $BASE/kustomization.yaml
|
||||
```
|
||||
|
||||
Optionally, run `kustomize` on the base to emit
|
||||
customized resources to `stdout`:
|
||||
|
||||
<!-- @buildBase @test -->
|
||||
```
|
||||
kustomize build $BASE
|
||||
```
|
||||
|
||||
### Customize the base
|
||||
|
||||
A first customization step could be to change the _app
|
||||
label_ applied to all resources:
|
||||
|
||||
<!-- @addLabel @test -->
|
||||
```
|
||||
sed -i.bak 's/app: hello/app: my-hello/' \
|
||||
$BASE/kustomization.yaml
|
||||
```
|
||||
|
||||
See the effect:
|
||||
<!-- @checkLabel @test -->
|
||||
```
|
||||
kustomize build $BASE | grep -C 3 app:
|
||||
```
|
||||
|
||||
## Create Overlays
|
||||
|
||||
Create a _staging_ and _production_ [overlay]:
|
||||
|
||||
* _Staging_ enables a risky feature not enabled in production.
|
||||
* _Production_ has a higher replica count.
|
||||
* Web server greetings from these cluster
|
||||
[variants] will differ from each other.
|
||||
|
||||
<!-- @overlayDirectories @test -->
|
||||
```
|
||||
OVERLAYS=$DEMO_HOME/overlays
|
||||
mkdir -p $OVERLAYS/staging
|
||||
mkdir -p $OVERLAYS/production
|
||||
```
|
||||
|
||||
#### Staging Kustomization
|
||||
|
||||
In the `staging` directory, make a kustomization
|
||||
defining a new name prefix, and some different labels.
|
||||
|
||||
<!-- @makeStagingKustomization @test -->
|
||||
```
|
||||
cat <<'EOF' >$OVERLAYS/staging/kustomization.yaml
|
||||
namePrefix: staging-
|
||||
commonLabels:
|
||||
variant: staging
|
||||
org: acmeCorporation
|
||||
commonAnnotations:
|
||||
note: Hello, I am staging!
|
||||
bases:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- map.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
#### Staging Patch
|
||||
|
||||
Add a configMap customization to change the server
|
||||
greeting from _Good Morning!_ to _Have a pineapple!_
|
||||
|
||||
Also, enable the _risky_ flag.
|
||||
|
||||
<!-- @stagingMap @test -->
|
||||
```
|
||||
cat <<EOF >$OVERLAYS/staging/map.yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: the-map
|
||||
data:
|
||||
altGreeting: "Have a pineapple!"
|
||||
enableRisky: "true"
|
||||
EOF
|
||||
```
|
||||
|
||||
#### Production Kustomization
|
||||
|
||||
In the production directory, make a kustomization
|
||||
with a different name prefix and labels.
|
||||
|
||||
<!-- @makeProductionKustomization @test -->
|
||||
```
|
||||
cat <<EOF >$OVERLAYS/production/kustomization.yaml
|
||||
namePrefix: production-
|
||||
commonLabels:
|
||||
variant: production
|
||||
org: acmeCorporation
|
||||
commonAnnotations:
|
||||
note: Hello, I am production!
|
||||
bases:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- deployment.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
|
||||
#### Production Patch
|
||||
|
||||
Make a production patch that increases the replica
|
||||
count (because production takes more traffic).
|
||||
|
||||
<!-- @productionDeployment @test -->
|
||||
```
|
||||
cat <<EOF >$OVERLAYS/production/deployment.yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: the-deployment
|
||||
spec:
|
||||
replicas: 10
|
||||
EOF
|
||||
```
|
||||
|
||||
## Compare overlays
|
||||
|
||||
|
||||
`DEMO_HOME` now contains:
|
||||
|
||||
- a _base_ directory - a slightly customized clone
|
||||
of the original configuration, and
|
||||
|
||||
- an _overlays_ directory, containing the kustomizations
|
||||
and patches required to create distinct _staging_
|
||||
and _production_ [variants] in a cluster.
|
||||
|
||||
Review the directory structure and differences:
|
||||
|
||||
<!-- @listFiles @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expecting something like:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP1
|
||||
> ├── base
|
||||
> │ ├── configMap.yaml
|
||||
> │ ├── deployment.yaml
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── service.yaml
|
||||
> └── overlays
|
||||
> ├── production
|
||||
> │ ├── deployment.yaml
|
||||
> │ └── kustomization.yaml
|
||||
> └── staging
|
||||
> ├── kustomization.yaml
|
||||
> └── map.yaml
|
||||
> ```
|
||||
|
||||
Compare the output directly
|
||||
to see how _staging_ and _production_ differ:
|
||||
|
||||
<!-- @compareOutput -->
|
||||
```
|
||||
diff \
|
||||
<(kustomize build $OVERLAYS/staging) \
|
||||
<(kustomize build $OVERLAYS/production) |\
|
||||
more
|
||||
```
|
||||
|
||||
The first part of the difference output should look
|
||||
something like
|
||||
|
||||
> ```diff
|
||||
> < altGreeting: Have a pineapple!
|
||||
> < enableRisky: "true"
|
||||
> ---
|
||||
> > altGreeting: Good Morning!
|
||||
> > enableRisky: "false"
|
||||
> 8c8
|
||||
> < note: Hello, I am staging!
|
||||
> ---
|
||||
> > note: Hello, I am production!
|
||||
> 11c11
|
||||
> < variant: staging
|
||||
> ---
|
||||
> > variant: production
|
||||
> 13c13
|
||||
> (...truncated)
|
||||
> ```
|
||||
|
||||
|
||||
## Deploy
|
||||
|
||||
The individual resource sets are:
|
||||
|
||||
<!-- @buildStaging @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging
|
||||
```
|
||||
|
||||
<!-- @buildProduction @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/production
|
||||
```
|
||||
|
||||
To deploy, pipe the above commands to kubectl apply:
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/staging |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/production |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
9
examples/helloWorld/kustomization.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
# Example configuration for the webserver
|
||||
# at https://github.com/monopole/hello
|
||||
commonLabels:
|
||||
app: hello
|
||||
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
- configMap.yaml
|
||||
75
examples/imageTags.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Demo: change image tags
|
||||
|
||||
|
||||
Define a place to work:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
Make a `kustomization` containing a pod resource
|
||||
|
||||
<!-- @createKustomization @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/kustomization.yaml
|
||||
resources:
|
||||
- pod.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Declare the pod resource
|
||||
|
||||
<!-- @createDeployment @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/pod.yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod
|
||||
labels:
|
||||
app: myapp
|
||||
spec:
|
||||
containers:
|
||||
- name: myapp-container
|
||||
image: busybox:1.29.0
|
||||
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
|
||||
initContainers:
|
||||
- name: init-mydb
|
||||
image: busybox:1.29.0
|
||||
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
|
||||
EOF
|
||||
```
|
||||
|
||||
The `myapp-pod` resource declares an initContainer and a container, both use the image `busybox:1.29.0`.
|
||||
The tag `1.29.0` can be changed by adding `imageTags` in `kustomization.yaml`.
|
||||
|
||||
|
||||
Add `imageTags`:
|
||||
<!-- @addImageTags @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
kustomize edit set imagetag busybox:1.29.1
|
||||
```
|
||||
|
||||
The `kustomization.yaml` will be added following `imageTags`.
|
||||
> ```
|
||||
> imageTags:
|
||||
> - name: busybox
|
||||
> newTag: 1.29.1
|
||||
> ```
|
||||
|
||||
Now build this `kustomization`
|
||||
<!-- @kustomizeBuild @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME
|
||||
```
|
||||
|
||||
Confirm that this replaces _both_ busybox tags:
|
||||
|
||||
<!-- @confirmTags @test -->
|
||||
```
|
||||
test 2 == \
|
||||
$(kustomize build $DEMO_HOME | grep busybox:1.29.1 | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
@@ -24,7 +24,7 @@
|
||||
#
|
||||
# This script assumes that the process running it has
|
||||
# checked out the kubernetes-sigs/kustomize repo, and
|
||||
# has cd'ed into it (i.e. the directory above "demos")
|
||||
# has cd'ed into it (i.e. the directory above "examples")
|
||||
# before running it.
|
||||
#
|
||||
# At time of writing, its 'call point' was in
|
||||
@@ -48,7 +48,7 @@ function setUpEnv {
|
||||
[[ $? -eq 0 ]] || "Failed to cd to $repo"
|
||||
echo "pwd is " `pwd`
|
||||
|
||||
local expectedRepo=kubernetes-sigs/kustomize
|
||||
local expectedRepo=sigs.k8s.io/kustomize
|
||||
if [[ `pwd` != */$expectedRepo ]]; then
|
||||
exitWith "Script must be run from $expectedRepo"
|
||||
fi
|
||||
@@ -79,6 +79,6 @@ function runTest {
|
||||
|
||||
setUpEnv
|
||||
|
||||
pushd demos
|
||||
pushd examples
|
||||
runTest ldap/integration_test.sh ldap/base
|
||||
popd
|
||||
118
examples/jsonpatch.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# Demo: applying a json patch
|
||||
|
||||
A kustomization file supports customizing resources via [JSON patches](https://tools.ietf.org/html/rfc6902).
|
||||
|
||||
The example below modifies an `Ingress` object with such a patch.
|
||||
|
||||
Make a `kustomization` containing an ingress resource.
|
||||
|
||||
<!-- @createIngress @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
|
||||
cat <<EOF >$DEMO_HOME/kustomization.yaml
|
||||
resources:
|
||||
- ingress.yaml
|
||||
EOF
|
||||
|
||||
cat <<EOF >$DEMO_HOME/ingress.yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: my-ingress
|
||||
spec:
|
||||
rules:
|
||||
- host: foo.bar.com
|
||||
http:
|
||||
paths:
|
||||
- backend:
|
||||
serviceName: my-api
|
||||
servicePort: 80
|
||||
EOF
|
||||
```
|
||||
|
||||
Declare a JSON patch file to update two fields of the Ingress object:
|
||||
|
||||
- change host from `foo.bar.com` to `foo.bar.io`
|
||||
- change servicePort from `80` to `8080`
|
||||
|
||||
<!-- @addJsonPatch @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/ingress_patch.json
|
||||
[
|
||||
{"op": "replace", "path": "/spec/rules/0/host", "value": "foo.bar.io"},
|
||||
{"op": "replace", "path": "/spec/rules/0/http/paths/0/backend/servicePort", "value": 8080}
|
||||
]
|
||||
EOF
|
||||
```
|
||||
|
||||
You can also write the patch in YAML format. This example also shows the "add" operation:
|
||||
|
||||
<!-- @addYamlPatch @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/ingress_patch.yaml
|
||||
- op: replace
|
||||
path: /spec/rules/0/host
|
||||
value: foo.bar.io
|
||||
|
||||
- op: add
|
||||
path: /spec/rules/0/http/paths/-
|
||||
value:
|
||||
path: '/test'
|
||||
backend:
|
||||
serviceName: my-test
|
||||
servicePort: 8081
|
||||
EOF
|
||||
```
|
||||
|
||||
Apply the patch by adding _patchesJson6902_ field in kustomization.yaml
|
||||
|
||||
<!-- @applyJsonPatch @test -->
|
||||
```
|
||||
cat <<EOF >>$DEMO_HOME/kustomization.yaml
|
||||
patchesJson6902:
|
||||
- target:
|
||||
group: extensions
|
||||
version: v1beta1
|
||||
kind: Ingress
|
||||
name: my-ingress
|
||||
path: ingress_patch.json
|
||||
EOF
|
||||
```
|
||||
|
||||
Running `kustomize build $DEMO_HOME`, in the output confirm that host has been updated correctly.
|
||||
<!-- @confirmHost @test -->
|
||||
```
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep "host: foo.bar.io" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
Running `kustomize build $DEMO_HOME`, in the output confirm that the servicePort has been updated correctly.
|
||||
<!-- @confirmServicePort @test -->
|
||||
```
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep "servicePort: 8080" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
|
||||
If the patch is YAML-formatted, it will be parsed correctly:
|
||||
|
||||
<!-- @applyYamlPatch @test -->
|
||||
```
|
||||
cat <<EOF >>$DEMO_HOME/kustomization.yaml
|
||||
patchesJson6902:
|
||||
- target:
|
||||
group: extensions
|
||||
version: v1beta1
|
||||
kind: Ingress
|
||||
name: my-ingress
|
||||
path: ingress_patch.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
<!-- @confirmYamlPatch @test -->
|
||||
```
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep "path: /test" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
281
examples/ldap/README.md
Normal file
@@ -0,0 +1,281 @@
|
||||
[base]: ../../docs/glossary.md#base
|
||||
[gitops]: ../../docs/glossary.md#gitops
|
||||
[kustomization]: ../../docs/glossary.md#kustomization
|
||||
[overlay]: ../../docs/glossary.md#overlay
|
||||
[overlays]: ../../docs/glossary.md#overlay
|
||||
[variant]: ../../docs/glossary.md#variant
|
||||
[variants]: ../../docs/glossary.md#variant
|
||||
|
||||
# Demo: LDAP with variants
|
||||
|
||||
Steps:
|
||||
|
||||
1. Clone an existing configuration as a [base].
|
||||
1. Customize it.
|
||||
1. Create two different [overlays] (_staging_ and _production_)
|
||||
from the customized base.
|
||||
1. Run kustomize and kubectl to deploy staging and production.
|
||||
|
||||
First define a place to work:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
Alternatively, use
|
||||
|
||||
> ```
|
||||
> DEMO_HOME=~/ldap
|
||||
> ```
|
||||
|
||||
## Establish the base
|
||||
|
||||
To use [overlays] to create [variants], we must
|
||||
first establish a common [base].
|
||||
|
||||
To keep this document shorter, the base resources are
|
||||
off in a supplemental data directory rather than
|
||||
declared here as HERE documents. Download them:
|
||||
|
||||
<!-- @downloadBase @test -->
|
||||
```
|
||||
BASE=$DEMO_HOME/base
|
||||
mkdir -p $BASE
|
||||
|
||||
CONTENT="https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/examples/ldap"
|
||||
|
||||
curl -s -o "$BASE/#1" "$CONTENT/base\
|
||||
/{deployment.yaml,kustomization.yaml,service.yaml,env.startup.txt}"
|
||||
```
|
||||
|
||||
Look at the directory:
|
||||
|
||||
<!-- @runTree @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expect something like:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP
|
||||
> └── base
|
||||
> ├── deployment.yaml
|
||||
> ├── env.startup.txt
|
||||
> ├── kustomization.yaml
|
||||
> └── service.yaml
|
||||
> ```
|
||||
|
||||
|
||||
One could immediately apply these resources to a
|
||||
cluster:
|
||||
|
||||
> ```
|
||||
> kubectl apply -f $DEMO_HOME/base
|
||||
> ```
|
||||
|
||||
to instantiate the _ldap_ service. `kubectl`
|
||||
would only recognize the resource files.
|
||||
|
||||
### The Base Kustomization
|
||||
|
||||
The `base` directory has a [kustomization] file:
|
||||
|
||||
<!-- @showKustomization @test -->
|
||||
```
|
||||
more $BASE/kustomization.yaml
|
||||
```
|
||||
|
||||
Optionally, run `kustomize` on the base to emit
|
||||
customized resources to `stdout`:
|
||||
|
||||
<!-- @buildBase @test -->
|
||||
```
|
||||
kustomize build $BASE
|
||||
```
|
||||
|
||||
### Customize the base
|
||||
|
||||
A first customization step could be to set the name prefix to all resources:
|
||||
|
||||
<!-- @namePrefix @test -->
|
||||
```
|
||||
cd $BASE
|
||||
kustomize edit set nameprefix "my-"
|
||||
```
|
||||
|
||||
See the effect:
|
||||
<!-- @checkNameprefix @test -->
|
||||
```
|
||||
kustomize build $BASE | grep -C 3 "my-"
|
||||
```
|
||||
|
||||
## Create Overlays
|
||||
|
||||
Create a _staging_ and _production_ [overlay]:
|
||||
|
||||
* _Staging_ adds a configMap.
|
||||
* _Production_ has a higher replica count and a persistent disk.
|
||||
* [variants] will differ from each other.
|
||||
|
||||
<!-- @overlayDirectories @test -->
|
||||
```
|
||||
OVERLAYS=$DEMO_HOME/overlays
|
||||
mkdir -p $OVERLAYS/staging
|
||||
mkdir -p $OVERLAYS/production
|
||||
```
|
||||
|
||||
#### Staging Kustomization
|
||||
|
||||
Download the staging customization and patch.
|
||||
|
||||
<!-- @downloadStagingKustomization @test -->
|
||||
```
|
||||
curl -s -o "$OVERLAYS/staging/#1" "$CONTENT/overlays/staging\
|
||||
/{config.env,deployment.yaml,kustomization.yaml}"
|
||||
```
|
||||
|
||||
The staging customization adds a configMap.
|
||||
> ```cat $OVERLAYS/staging/kustomization.yaml
|
||||
> (...truncated)
|
||||
> configMapGenerator:
|
||||
> - name: env-config
|
||||
> files:
|
||||
> - config.env
|
||||
> ```
|
||||
as well as 2 replica
|
||||
> ```cat $OVERLAYS/staging/deployment.yaml
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: ldap
|
||||
> spec:
|
||||
> replicas: 2
|
||||
> ```
|
||||
|
||||
#### Production Kustomization
|
||||
|
||||
Download the production customization and patch.
|
||||
<!-- @downloadProductionKustomization @test -->
|
||||
```
|
||||
curl -s -o "$OVERLAYS/production/#1" "$CONTENT/overlays/production\
|
||||
/{deployment.yaml,kustomization.yaml}"
|
||||
```
|
||||
|
||||
The production customization adds 6 replica as well as a consistent disk.
|
||||
> ```cat $OVERLAYS/production/deployment.yaml
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: ldap
|
||||
> spec:
|
||||
> replicas: 6
|
||||
> template:
|
||||
> spec:
|
||||
> volumes:
|
||||
> - name: ldap-data
|
||||
> emptyDir: null
|
||||
> gcePersistentDisk:
|
||||
> pdName: ldap-persistent-storage
|
||||
> ```
|
||||
|
||||
## Compare overlays
|
||||
|
||||
|
||||
`DEMO_HOME` now contains:
|
||||
|
||||
- a _base_ directory - a slightly customized clone
|
||||
of the original configuration, and
|
||||
|
||||
- an _overlays_ directory, containing the kustomizations
|
||||
and patches required to create distinct _staging_
|
||||
and _production_ [variants] in a cluster.
|
||||
|
||||
Review the directory structure and differences:
|
||||
|
||||
<!-- @listFiles @test -->
|
||||
```
|
||||
tree $DEMO_HOME
|
||||
```
|
||||
|
||||
Expecting something like:
|
||||
|
||||
> ```
|
||||
> /tmp/tmp.IyYQQlHaJP1
|
||||
> ├── base
|
||||
> │ ├── deployment.yaml
|
||||
> │ ├── env.startup.txt
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── service.yaml
|
||||
> └── overlays
|
||||
> ├── production
|
||||
> │ ├── deployment.yaml
|
||||
> │ └── kustomization.yaml
|
||||
> └── staging
|
||||
> ├── config.env
|
||||
> ├── deployment.yaml
|
||||
> └── kustomization.yaml
|
||||
> ```
|
||||
|
||||
Compare the output directly
|
||||
to see how _staging_ and _production_ differ:
|
||||
|
||||
<!-- @compareOutput -->
|
||||
```
|
||||
diff \
|
||||
<(kustomize build $OVERLAYS/staging) \
|
||||
<(kustomize build $OVERLAYS/production) |\
|
||||
more
|
||||
```
|
||||
|
||||
The difference output should look something like
|
||||
|
||||
> ```diff
|
||||
> (...truncated)
|
||||
> < name: staging-my-ldap-configmap-kftftt474h
|
||||
> ---
|
||||
> > name: production-my-ldap-configmap-k27f7hkg4f
|
||||
> 85c75
|
||||
> < name: staging-my-ldap-service
|
||||
> ---
|
||||
> > name: production-my-ldap-service
|
||||
> 97c87
|
||||
> < name: staging-my-ldap
|
||||
> ---
|
||||
> > name: production-my-ldap
|
||||
> 99c89
|
||||
> < replicas: 2
|
||||
> ---
|
||||
> > replicas: 6
|
||||
> (...truncated)
|
||||
> ```
|
||||
|
||||
|
||||
## Deploy
|
||||
|
||||
The individual resource sets are:
|
||||
|
||||
<!-- @buildStaging @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/staging
|
||||
```
|
||||
|
||||
<!-- @buildProduction @test -->
|
||||
```
|
||||
kustomize build $OVERLAYS/production
|
||||
```
|
||||
|
||||
To deploy, pipe the above commands to kubectl apply:
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/staging |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
|
||||
> ```
|
||||
> kustomize build $OVERLAYS/production |\
|
||||
> kubectl apply -f -
|
||||
> ```
|
||||
5
examples/ldap/overlays/production/kustomization.yaml
Normal file
@@ -0,0 +1,5 @@
|
||||
bases:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- deployment.yaml
|
||||
namePrefix: production-
|
||||
9
examples/ldap/overlays/staging/kustomization.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
bases:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- deployment.yaml
|
||||
nameprefix: staging-
|
||||
configMapGenerator:
|
||||
- name: env-config
|
||||
files:
|
||||
- config.env
|
||||
127
examples/multibases/README.md
Normal file
@@ -0,0 +1,127 @@
|
||||
# Demo: multibases with a common base
|
||||
|
||||
`kustomize` encourages defining multiple variants - e.g. dev, staging and prod, as overlays on a common base.
|
||||
|
||||
It's possible to create an additional overlay to compose these variants together - just declare the overlays as the bases of a new kustomization.
|
||||
|
||||
This is also a means to apply a common label or annotation across the variants, if for some reason the base isn't under your control. It also allows one to define a left-most namePrefix across the variants - something that cannot be done by modifying the common base.
|
||||
|
||||
The following demonstrates this using a base that's just one pod.
|
||||
|
||||
Define a place to work:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
Define a common base:
|
||||
<!-- @makeBase @test -->
|
||||
```
|
||||
BASE=$DEMO_HOME/base
|
||||
mkdir $BASE
|
||||
|
||||
cat <<EOF >$BASE/kustomization.yaml
|
||||
resources:
|
||||
- pod.yaml
|
||||
EOF
|
||||
|
||||
cat <<EOF >$BASE/pod.yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod
|
||||
labels:
|
||||
app: myapp
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.7.9
|
||||
EOF
|
||||
```
|
||||
|
||||
Define a dev variant overlaying base:
|
||||
<!-- @makeDev @test -->
|
||||
```
|
||||
DEV=$DEMO_HOME/dev
|
||||
mkdir $DEV
|
||||
|
||||
cat <<EOF >$DEV/kustomization.yaml
|
||||
bases:
|
||||
- ./../base
|
||||
namePrefix: dev-
|
||||
EOF
|
||||
```
|
||||
|
||||
Define a staging variant overlaying base:
|
||||
<!-- @makeStaging @test -->
|
||||
```
|
||||
STAG=$DEMO_HOME/staging
|
||||
mkdir $STAG
|
||||
|
||||
cat <<EOF >$STAG/kustomization.yaml
|
||||
bases:
|
||||
- ./../base
|
||||
namePrefix: stag-
|
||||
EOF
|
||||
```
|
||||
|
||||
Define a production variant overlaying base:
|
||||
<!-- @makeProd @test -->
|
||||
```
|
||||
PROD=$DEMO_HOME/production
|
||||
mkdir $PROD
|
||||
|
||||
cat <<EOF >$PROD/kustomization.yaml
|
||||
bases:
|
||||
- ./../base
|
||||
namePrefix: prod-
|
||||
EOF
|
||||
```
|
||||
|
||||
Then define a _Kustomization_ composing three variants together:
|
||||
<!-- @makeTopLayer @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/kustomization.yaml
|
||||
bases:
|
||||
- ./dev
|
||||
- ./staging
|
||||
- ./production
|
||||
|
||||
namePrefix: cluster-a-
|
||||
EOF
|
||||
```
|
||||
|
||||
Now the workspace has following directories
|
||||
> ```
|
||||
> .
|
||||
> ├── base
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── pod.yaml
|
||||
> ├── dev
|
||||
> │ └── kustomization.yaml
|
||||
> ├── kustomization.yaml
|
||||
> ├── production
|
||||
> │ └── kustomization.yaml
|
||||
> └── staging
|
||||
> └── kustomization.yaml
|
||||
> ```
|
||||
|
||||
Confirm that the `kustomize build` output contains three pod objects from dev, staging and production variants.
|
||||
|
||||
<!-- @confirmVariants @test -->
|
||||
```
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep cluster-a-dev-myapp-pod | wc -l); \
|
||||
echo $?
|
||||
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep cluster-a-stag-myapp-pod | wc -l); \
|
||||
echo $?
|
||||
|
||||
test 1 == \
|
||||
$(kustomize build $DEMO_HOME | grep cluster-a-prod-myapp-pod | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
Similarly to adding different `namePrefix` in different variants, one can also add different `namespace` and compose those variants in
|
||||
one _kustomization_. For more details, take a look at [multi-namespaces](multi-namespace.md).
|
||||
2
examples/multibases/base/kustomization.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
resources:
|
||||
- pod.yaml
|
||||
10
examples/multibases/base/pod.yaml
Normal file
@@ -0,0 +1,10 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod
|
||||
labels:
|
||||
app: myapp
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.7.9
|
||||
4
examples/multibases/dev/kustomization.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
bases:
|
||||
- ./../base
|
||||
|
||||
namePrefix: dev-
|
||||
6
examples/multibases/kustomization.yaml
Normal file
@@ -0,0 +1,6 @@
|
||||
bases:
|
||||
- ./dev
|
||||
- ./staging
|
||||
- ./production
|
||||
|
||||
namePrefix: cluster-a-
|
||||
115
examples/multibases/multi-namespace.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# Demo: multi namespaces with a common base
|
||||
|
||||
`kustomize` supports defining multiple variants with different namespace, as overlays on a common base.
|
||||
|
||||
It's possible to create an additional overlay to compose these variants together - just declare the overlays as the bases of a new kustomization. The following demonstrates this using a base that's just one pod.
|
||||
|
||||
Define a place to work:
|
||||
|
||||
<!-- @makeWorkplace @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
Define a common base:
|
||||
<!-- @makeBase @test -->
|
||||
```
|
||||
BASE=$DEMO_HOME/base
|
||||
mkdir $BASE
|
||||
|
||||
cat <<EOF >$BASE/kustomization.yaml
|
||||
resources:
|
||||
- pod.yaml
|
||||
EOF
|
||||
|
||||
cat <<EOF >$BASE/pod.yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: myapp-pod
|
||||
labels:
|
||||
app: myapp
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx:1.7.9
|
||||
EOF
|
||||
```
|
||||
|
||||
Define a variant in namespace-a overlaying base:
|
||||
<!-- @makeNamespaceA @test -->
|
||||
```
|
||||
NSA=$DEMO_HOME/namespace-a
|
||||
mkdir $NSA
|
||||
|
||||
cat <<EOF >$NSA/kustomization.yaml
|
||||
bases:
|
||||
- ./../base
|
||||
resources:
|
||||
- namespace.yaml
|
||||
namespace: namespace-a
|
||||
EOF
|
||||
|
||||
cat <<EOF >$NSA/namespace.yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: namespace-a
|
||||
EOF
|
||||
```
|
||||
|
||||
Define a variant in namespace-b overlaying base:
|
||||
<!-- @makeNamespaceB @test -->
|
||||
```
|
||||
NSB=$DEMO_HOME/namespace-b
|
||||
mkdir $NSB
|
||||
|
||||
cat <<EOF >$NSB/kustomization.yaml
|
||||
bases:
|
||||
- ./../base
|
||||
resources:
|
||||
- namespace.yaml
|
||||
namespace: namespace-b
|
||||
EOF
|
||||
|
||||
cat <<EOF >$NSB/namespace.yaml
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: namespace-b
|
||||
EOF
|
||||
```
|
||||
|
||||
Then define a _Kustomization_ composing two variants together:
|
||||
<!-- @makeTopLayer @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/kustomization.yaml
|
||||
bases:
|
||||
- ./namespace-a
|
||||
- ./namespace-b
|
||||
EOF
|
||||
```
|
||||
|
||||
Now the workspace has following directories
|
||||
> ```
|
||||
> .
|
||||
> ├── base
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── pod.yaml
|
||||
> ├── kustomization.yaml
|
||||
> ├── namespace-a
|
||||
> │ ├── kustomization.yaml
|
||||
> │ └── namespace.yaml
|
||||
> └── namespace-b
|
||||
> ├── kustomization.yaml
|
||||
> └── namespace.yaml
|
||||
> ```
|
||||
|
||||
Confirm that the `kustomize build` output contains two pod objects from namespace-a and namespace-b.
|
||||
|
||||
<!-- @confirmVariants @test -->
|
||||
```
|
||||
test 2 == \
|
||||
$(kustomize build $DEMO_HOME| grep -B 4 "namespace: namespace-[ab]" | grep "name: myapp-pod" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
4
examples/multibases/production/kustomization.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
bases:
|
||||
- ./../base
|
||||
|
||||
namePrefix: prod-
|
||||
4
examples/multibases/staging/kustomization.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
bases:
|
||||
- ./../base
|
||||
|
||||
namePrefix: staging-
|
||||
205
examples/mySql/README.md
Normal file
@@ -0,0 +1,205 @@
|
||||
# Demo: MySql
|
||||
|
||||
This example takes some off-the-shelf k8s resources
|
||||
designed for MySQL, and customizes them to suit a
|
||||
production scenario.
|
||||
|
||||
In the production environment we want:
|
||||
|
||||
- MySQL resource names to be prefixed by 'prod-'.
|
||||
- MySQL resources to have 'env: prod' labels.
|
||||
- MySQL to use persistent disk for storing data.
|
||||
|
||||
First make a place to work:
|
||||
<!-- @makeDemoHome @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Download resources
|
||||
|
||||
To keep this document shorter, the base resources
|
||||
needed to run MySql on a k8s cluster are off in a
|
||||
supplemental data directory rather than declared here
|
||||
as HERE documents.
|
||||
|
||||
Download them:
|
||||
|
||||
<!-- @downloadResources @test -->
|
||||
```
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" "https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/examples/mySql\
|
||||
/{deployment,secret,service}.yaml"
|
||||
```
|
||||
|
||||
### Initialize kustomization.yaml
|
||||
|
||||
The `kustomize` program gets its instructions from
|
||||
a file called `kustomization.yaml`.
|
||||
|
||||
Start this file:
|
||||
|
||||
<!-- @kustomizeYaml @test -->
|
||||
```
|
||||
touch $DEMO_HOME/kustomization.yaml
|
||||
```
|
||||
|
||||
### Add the resources
|
||||
|
||||
<!-- @addResources @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
|
||||
kustomize edit add resource secret.yaml
|
||||
kustomize edit add resource service.yaml
|
||||
kustomize edit add resource deployment.yaml
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml`'s resources section should contain:
|
||||
|
||||
> ```
|
||||
> resources:
|
||||
> - secret.yaml
|
||||
> - service.yaml
|
||||
> - deployment.yaml
|
||||
> ```
|
||||
|
||||
### Name Customization
|
||||
|
||||
Arrange for the MySQL resources to begin with prefix
|
||||
_prod-_ (since they are meant for the _production_
|
||||
environment):
|
||||
|
||||
<!-- @customizeLabel @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
|
||||
kustomize edit set nameprefix 'prod-'
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml` should have updated value of namePrefix field:
|
||||
|
||||
> ```
|
||||
> namePrefix: prod-
|
||||
> ```
|
||||
|
||||
This `namePrefix` directive adds _prod-_ to all
|
||||
resource names.
|
||||
|
||||
<!-- @genNamePrefixConfig @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME
|
||||
```
|
||||
|
||||
The output should contain:
|
||||
|
||||
> ```
|
||||
> apiVersion: v1
|
||||
> data:
|
||||
> password: YWRtaW4=
|
||||
> kind: Secret
|
||||
> metadata:
|
||||
> ....
|
||||
> name: prod-mysql-pass-d2gtcm2t2k
|
||||
> ---
|
||||
> apiVersion: v1
|
||||
> kind: Service
|
||||
> metadata:
|
||||
> ....
|
||||
> name: prod-mysql
|
||||
> spec:
|
||||
> ....
|
||||
> ---
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> ....
|
||||
> name: prod-mysql
|
||||
> spec:
|
||||
> selector:
|
||||
> ....
|
||||
> ```
|
||||
|
||||
### Label Customization
|
||||
|
||||
We want resources in production environment to have
|
||||
certain labels so that we can query them by label
|
||||
selector.
|
||||
|
||||
`kustomize` does not have `edit set label` command to add
|
||||
a label, but one can always edit `kustomization.yaml` directly:
|
||||
|
||||
<!-- @customizeLabels @test -->
|
||||
```
|
||||
sed -i.bak 's/app: helloworld/app: prod/' \
|
||||
$DEMO_HOME/kustomization.yaml
|
||||
```
|
||||
|
||||
At this point, running `kustomize build` will
|
||||
generate MySQL configs with name-prefix 'prod-' and
|
||||
labels `env:prod`.
|
||||
|
||||
### Storage customization
|
||||
|
||||
Off the shelf MySQL uses `emptyDir` type volume, which
|
||||
gets wiped away if the MySQL Pod is recreated, and that
|
||||
is certainly not desirable for production
|
||||
environment. So we want to use Persistent Disk in
|
||||
production. kustomize lets you apply `patchesStrategicMerge` to the
|
||||
resources.
|
||||
|
||||
<!-- @createPatchFile @test -->
|
||||
```
|
||||
cat <<'EOF' > $DEMO_HOME/persistent-disk.yaml
|
||||
apiVersion: apps/v1beta2 # for versions before 1.9.0 use apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
volumes:
|
||||
- name: mysql-persistent-storage
|
||||
emptyDir: null
|
||||
gcePersistentDisk:
|
||||
pdName: mysql-persistent-storage
|
||||
EOF
|
||||
```
|
||||
|
||||
Add the patch file to `kustomization.yaml`:
|
||||
|
||||
<!-- @specifyPatch @test -->
|
||||
```
|
||||
cat <<'EOF' >> $DEMO_HOME/kustomization.yaml
|
||||
patchesStrategicMerge:
|
||||
- persistent-disk.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
A `mysql-persistent-storage` persistent disk needs to exist for it to run successfully.
|
||||
|
||||
Lets break this down:
|
||||
|
||||
- In the first step, we created a YAML file named
|
||||
`persistent-disk.yaml` to patch the resource defined
|
||||
in deployment.yaml
|
||||
|
||||
- Then we added `persistent-disk.yaml` to list of
|
||||
`patchesStrategicMerge` in `kustomization.yaml`. `kustomize build`
|
||||
will apply this patch to the deployment resource with
|
||||
the name `mysql` as defined in the patch.
|
||||
|
||||
|
||||
The output of the following command can now be applied
|
||||
to the cluster (i.e. piped to `kubectl apply`) to
|
||||
create the production environment.
|
||||
|
||||
<!-- @finalInflation @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME # | kubectl apply -f -
|
||||
```
|
||||
9
examples/mySql/secret.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: mysql-pass
|
||||
type: Opaque
|
||||
data:
|
||||
# Default password is "admin".
|
||||
password: YWRtaW4=
|
||||
69
examples/remoteBuild.md
Normal file
@@ -0,0 +1,69 @@
|
||||
# remote targets
|
||||
|
||||
`kustomize build` can be run against a url. The effect is the same as cloing the repo, checking out the specified ref,
|
||||
then running `kustomize build` against the desired directory in the local copy.
|
||||
|
||||
Take `github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6` as an example.
|
||||
According to [multibases](multibases/README.md) demo, this kustomization contains three Pod objects with names as
|
||||
`cluster-a-dev-myapp-pod`, `cluster-a-stag-myapp-pod`, `cluster-a-prod-myapp-pod`.
|
||||
Running `kustomize build` against the url gives the same output.
|
||||
|
||||
<!-- @remoteBuild @test -->
|
||||
```
|
||||
target=github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6
|
||||
test 3 == \
|
||||
$(kustomize build $target | grep cluster-a-.*-myapp-pod | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
|
||||
Overlays can be remote as well:
|
||||
|
||||
<!-- @remoteOverlayBuild @test -->
|
||||
|
||||
```
|
||||
target=github.com/kubernetes-sigs/kustomize//examples/multibases/dev/?ref=v1.0.6
|
||||
test 1 == \
|
||||
$(kustomize build $target | grep cluster-a-dev-myapp-pod | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
|
||||
A base can also be specified as a URL:
|
||||
|
||||
<!-- @createOverlay @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
|
||||
cat <<EOF >$DEMO_HOME/kustomization.yaml
|
||||
bases:
|
||||
- github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6
|
||||
namePrefix: remote-
|
||||
EOF
|
||||
```
|
||||
Running `kustomize build $DEMO_HOME` and confirm the output contains three Pods and all have `remote-` prefix.
|
||||
<!-- @remoteBases @test -->
|
||||
```
|
||||
test 3 == \
|
||||
$(kustomize build $DEMO_HOME | grep remote-.*-myapp-pod | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
|
||||
## URL format
|
||||
The url should follow
|
||||
[hashicorp/go-getter URL format](https://github.com/hashicorp/go-getter#url-format).
|
||||
Here are some example urls pointing to Github repos following this convention.
|
||||
|
||||
- a repo with a root level kustomization.yaml
|
||||
|
||||
`github.com/Liujingfang1/mysql`
|
||||
- a repo with a root level kustomization.yaml on branch test
|
||||
|
||||
`github.com/Liujingfang1/mysql?ref=test`
|
||||
- a subdirectory in a repo on version v1.0.6
|
||||
|
||||
`github.com/kubernetes-sigs/kustomize//examples/multibases?ref=v1.0.6`
|
||||
- a subdirectory in a repo on branch repoUrl2
|
||||
|
||||
`github.com/Liujingfang1/kustomize//examples/helloWorld?ref=repoUrl2`
|
||||
- a subdirectory in a repo on commit `7050a45134e9848fca214ad7e7007e96e5042c03`
|
||||
|
||||
`github.com/Liujingfang1/kustomize//examples/helloWorld?ref=7050a45134e9848fca214ad7e7007e96e5042c03`
|
||||
307
examples/springboot/README.md
Normal file
@@ -0,0 +1,307 @@
|
||||
# Demo: SpringBoot
|
||||
|
||||
In this tutorial, you will learn - how to use `kustomize` to customize a basic Spring Boot application's
|
||||
k8s configuration for production use cases.
|
||||
|
||||
In the production environment we want to customize the following:
|
||||
|
||||
- add application specific configuration for this Spring Boot application
|
||||
- configure prod DB access configuration
|
||||
- resource names to be prefixed by 'prod-'.
|
||||
- resources to have 'env: prod' labels.
|
||||
- JVM memory to be properly set.
|
||||
- health check and readiness check.
|
||||
|
||||
First make a place to work:
|
||||
<!-- @makeDemoHome @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Download resources
|
||||
|
||||
To keep this document shorter, the base resources
|
||||
needed to run springboot on a k8s cluster are off in a
|
||||
supplemental data directory rather than declared here
|
||||
as HERE documents.
|
||||
|
||||
Download them:
|
||||
|
||||
<!-- @downloadResources @test -->
|
||||
```
|
||||
CONTENT="https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/examples/springboot"
|
||||
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" \
|
||||
"$CONTENT/base/{deployment,service}.yaml"
|
||||
```
|
||||
|
||||
### Initialize kustomization.yaml
|
||||
|
||||
The `kustomize` program gets its instructions from
|
||||
a file called `kustomization.yaml`.
|
||||
|
||||
Start this file:
|
||||
|
||||
<!-- @kustomizeYaml @test -->
|
||||
```
|
||||
touch $DEMO_HOME/kustomization.yaml
|
||||
```
|
||||
|
||||
### Add the resources
|
||||
|
||||
<!-- @addResources @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
|
||||
kustomize edit add resource service.yaml
|
||||
kustomize edit add resource deployment.yaml
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml`'s resources section should contain:
|
||||
|
||||
> ```
|
||||
> resources:
|
||||
> - service.yaml
|
||||
> - deployment.yaml
|
||||
> ```
|
||||
|
||||
### Add configMap generator
|
||||
|
||||
<!-- @addConfigMap @test -->
|
||||
```
|
||||
echo "app.name=Kustomize Demo" >$DEMO_HOME/application.properties
|
||||
|
||||
kustomize edit add configmap demo-configmap \
|
||||
--from-file application.properties
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml`'s configMapGenerator section should contain:
|
||||
|
||||
> ```
|
||||
> configMapGenerator:
|
||||
> - files:
|
||||
> - application.properties
|
||||
> name: demo-configmap
|
||||
> ```
|
||||
|
||||
### Customize configMap
|
||||
|
||||
We want to add database credentials for the prod environment. In general, these credentials can be put into the file `application.properties`.
|
||||
However, for some cases, we want to keep the credentials in a different file and keep application specific configs in `application.properties`.
|
||||
With this clear separation, the credentials and application specific things can be managed and maintained flexibly by different teams.
|
||||
For example, application developers only tune the application configs in `application.properties` and operation teams or SREs
|
||||
only care about the credentials.
|
||||
|
||||
For Spring Boot application, we can set an active profile through the environment variable `spring.profiles.active`. Then
|
||||
the application will pick up an extra `application-<profile>.properties` file. With this, we can customize the configMap in two
|
||||
steps. Add an environment variable through the patch and add a file to the configMap.
|
||||
|
||||
<!-- @customizeConfigMap @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/patch.yaml
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: sbdemo
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: sbdemo
|
||||
env:
|
||||
- name: spring.profiles.active
|
||||
value: prod
|
||||
EOF
|
||||
|
||||
kustomize edit add patch patch.yaml
|
||||
|
||||
cat <<EOF >$DEMO_HOME/application-prod.properties
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.datasource.url=jdbc:mysql://<prod_database_host>:3306/db_example
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=admin
|
||||
EOF
|
||||
|
||||
kustomize edit add configmap \
|
||||
demo-configmap --from-file application-prod.properties
|
||||
|
||||
cat kustomization.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml`'s configMapGenerator section should contain:
|
||||
> ```
|
||||
> configMapGenerator:
|
||||
> - files:
|
||||
> - application.properties
|
||||
> - application-prod.properties
|
||||
> name: demo-configmap
|
||||
> ```
|
||||
|
||||
### Name Customization
|
||||
|
||||
Arrange for the resources to begin with prefix
|
||||
_prod-_ (since they are meant for the _production_
|
||||
environment):
|
||||
|
||||
<!-- @customizeLabel @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
kustomize edit set nameprefix 'prod-'
|
||||
```
|
||||
|
||||
`kustomization.yaml` should have updated value of namePrefix field:
|
||||
|
||||
> ```
|
||||
> namePrefix: prod-
|
||||
> ```
|
||||
|
||||
This `namePrefix` directive adds _prod-_ to all
|
||||
resource names, as can be seen by building the
|
||||
resources:
|
||||
|
||||
<!-- @build1 @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME | grep prod-
|
||||
```
|
||||
|
||||
### Label Customization
|
||||
|
||||
We want resources in production environment to have
|
||||
certain labels so that we can query them by label
|
||||
selector.
|
||||
|
||||
`kustomize` does not have `edit set label` command to
|
||||
add a label, but one can always edit
|
||||
`kustomization.yaml` directly:
|
||||
|
||||
<!-- @customizeLabels @test -->
|
||||
```
|
||||
cat <<EOF >>$DEMO_HOME/kustomization.yaml
|
||||
commonLabels:
|
||||
env: prod
|
||||
EOF
|
||||
```
|
||||
|
||||
Confirm that the resources now all have names prefixed
|
||||
by `prod-` and the label tuple `env:prod`:
|
||||
|
||||
<!-- @build2 @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME | grep -C 3 env
|
||||
```
|
||||
|
||||
### Download Patch for JVM memory
|
||||
|
||||
When a Spring Boot application is deployed in a k8s cluster, the JVM is running inside a container. We want to set memory limit for the container and make sure
|
||||
the JVM is aware of that limit. In K8s deployment, we can set the resource limits for containers and inject these limits to
|
||||
some environment variables by downward API. When the container starts to run, it can pick up the environment variables and
|
||||
set JVM options accordingly.
|
||||
|
||||
Download the patch `memorylimit_patch.yaml`. It contains the memory limits setup.
|
||||
|
||||
<!-- @downloadPatch @test -->
|
||||
```
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" \
|
||||
"$CONTENT/overlays/production/{memorylimit_patch}.yaml"
|
||||
|
||||
cat $DEMO_HOME/memorylimit_patch.yaml
|
||||
```
|
||||
|
||||
The output contains
|
||||
|
||||
> ```
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: sbdemo
|
||||
> spec:
|
||||
> template:
|
||||
> spec:
|
||||
> containers:
|
||||
> - name: sbdemo
|
||||
> resources:
|
||||
> limits:
|
||||
> memory: 1250Mi
|
||||
> requests:
|
||||
> memory: 1250Mi
|
||||
> env:
|
||||
> - name: MEM_TOTAL_MB
|
||||
> valueFrom:
|
||||
> resourceFieldRef:
|
||||
> resource: limits.memory
|
||||
> ```
|
||||
|
||||
### Download Patch for health check
|
||||
We also want to add liveness check and readiness check in the production environment. Spring Boot application
|
||||
has end points such as `/actuator/health` for this. We can customize the k8s deployment resource to talk to Spring Boot end point.
|
||||
|
||||
Download the patch `healthcheck_patch.yaml`. It contains the liveness probes and readyness probes.
|
||||
|
||||
<!-- @downloadPatch @test -->
|
||||
```
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" \
|
||||
"$CONTENT/overlays/production/{healthcheck_patch}.yaml"
|
||||
|
||||
cat $DEMO_HOME/healthcheck_patch.yaml
|
||||
```
|
||||
|
||||
The output contains
|
||||
|
||||
> ```
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: sbdemo
|
||||
> spec:
|
||||
> template:
|
||||
> spec:
|
||||
> containers:
|
||||
> - name: sbdemo
|
||||
> livenessProbe:
|
||||
> httpGet:
|
||||
> path: /actuator/health
|
||||
> port: 8080
|
||||
> initialDelaySeconds: 10
|
||||
> periodSeconds: 3
|
||||
> readinessProbe:
|
||||
> initialDelaySeconds: 20
|
||||
> periodSeconds: 10
|
||||
> httpGet:
|
||||
> path: /actuator/info
|
||||
> port: 8080
|
||||
> ```
|
||||
|
||||
### Add patches
|
||||
|
||||
Add these patches to the kustomization:
|
||||
|
||||
<!-- @addPatch @test -->
|
||||
```
|
||||
cd $DEMO_HOME
|
||||
kustomize edit add patch memorylimit_patch.yaml
|
||||
kustomize edit add patch healthcheck_patch.yaml
|
||||
```
|
||||
|
||||
`kustomization.yaml` should have patches field:
|
||||
|
||||
> ```
|
||||
> patchesStrategicMerge:
|
||||
> - patch.yaml
|
||||
> - memorylimit_patch.yaml
|
||||
> - healthcheck_patch.yaml
|
||||
> ```
|
||||
|
||||
The output of the following command can now be applied
|
||||
to the cluster (i.e. piped to `kubectl apply`) to
|
||||
create the production environment.
|
||||
|
||||
<!-- @finalBuild @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME # | kubectl apply -f -
|
||||
```
|
||||
@@ -0,0 +1,7 @@
|
||||
bases:
|
||||
- ../../base
|
||||
patchesStrategicMerge:
|
||||
- patch.yaml
|
||||
- healthcheck_patch.yaml
|
||||
- memorylimit_patch.yaml
|
||||
namePrefix: production-
|
||||
13
examples/springboot/overlays/production/patch.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: demo-configmap
|
||||
data:
|
||||
application.properties: |
|
||||
app.name=Production Kinflate Demo
|
||||
spring.jpa.hibernate.ddl-auto=update
|
||||
spring.datasource.url=jdbc:mysql://<production_db_ip>:3306/db_example
|
||||
spring.datasource.username=root
|
||||
spring.datasource.password=admin
|
||||
server.tomcat.max-threads=20
|
||||
server.tomcat.min-spare-threads=3
|
||||
96
examples/transformerconfigs/README.md
Normal file
@@ -0,0 +1,96 @@
|
||||
# Transformer Configurations
|
||||
|
||||
Kustomize computes the resources by applying a series of transformers:
|
||||
- namespace transformer
|
||||
- prefix/suffix transformer
|
||||
- label transformer
|
||||
- annotation transformer
|
||||
- name reference transformer
|
||||
- variable reference transformer
|
||||
|
||||
Each transformer takes a list of resources and modifies certain fields. The modification is based on the transformer's rule.
|
||||
The fields to update is the transformer's configuration, which is a list of filedspec that can be represented in YAML format.
|
||||
|
||||
## fieldSpec
|
||||
FieldSpec is a type to represent a path to a field in one kind of resources. It has following format
|
||||
```
|
||||
group: some-group
|
||||
version: some-version
|
||||
kind: some-kind
|
||||
path: path/to/the/field
|
||||
create: false
|
||||
```
|
||||
If `create` is set to true, it indicates the transformer to create the path if it is not found in the resources. This is most useful for label and annotation transformers, where the path for labels or annotations may not be set before the transformation.
|
||||
|
||||
## prefix/suffix transformer
|
||||
Name prefix suffix transformer adds prefix and suffix to the `metadata/name` field for all resources with following configuration:
|
||||
```
|
||||
namePrefix:
|
||||
- path: metadata/name
|
||||
```
|
||||
|
||||
## label transformer
|
||||
Label transformer adds labels to `metadata/labels` field for all resources. It also adds labels to `spec/selector` field in all Service and to `spec/selector/matchLabels` field in all Deployment.
|
||||
```
|
||||
commonLabels:
|
||||
- path: metadata/labels
|
||||
create: true
|
||||
|
||||
- path: spec/selector
|
||||
create: true
|
||||
version: v1
|
||||
kind: Service
|
||||
|
||||
- path: spec/selector/matchLabels
|
||||
create: true
|
||||
kind: Deployment
|
||||
(etc.)
|
||||
```
|
||||
|
||||
## name reference transformer
|
||||
Name reference transformer's configuration is different from all other transformers. It contains a list of namebackreferences, which represented all the possible fields that a type could be used as a reference in other types of resources. A namebackreference contains a type such as ConfigMap as well as a list of FieldSpecs where ConfigMap is referenced. Here is an example.
|
||||
```
|
||||
kind: ConfigMap
|
||||
version: v1
|
||||
FieldSpecs:
|
||||
- kind: Pod
|
||||
version: v1
|
||||
path: spec/volumes/configMap/name
|
||||
- kind: Deployment
|
||||
path: spec/template/spec/volumes/configMap/name
|
||||
- kind: Job
|
||||
path: spec/template/spec/volumes/configMap/name
|
||||
(etc.)
|
||||
```
|
||||
Name reference transformer configuration contains a list of such namebackreferences for ConfigMap, Secret, Service, Role, ServiceAccount and so on.
|
||||
```
|
||||
nameReference:
|
||||
- kind: ConfigMap
|
||||
version: v1
|
||||
fieldSpecs:
|
||||
- path: spec/volumes/configMap/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/containers/env/valueFrom/configMapKeyRef/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
(etc.)
|
||||
- kind: Secret
|
||||
version: v1
|
||||
fieldSpecs:
|
||||
- path: spec/volumes/secret/secretName
|
||||
version: v1
|
||||
kind: Pod
|
||||
- path: spec/containers/env/valueFrom/secretKeyRef/name
|
||||
version: v1
|
||||
kind: Pod
|
||||
(etc.)
|
||||
```
|
||||
|
||||
## cusotmizing transformer configurations
|
||||
|
||||
Kustomize has a default set of configurations. They can be saved to local directory through `kustomize config save -d`. Kustomize allows modifying those configuration files and using them in kustomization.yaml file. This tutorial shows how to customize those configurations to
|
||||
- [support a CRD type](crd/README.md)
|
||||
- disabling adding commonLabels to fields in some kind of resources
|
||||
- add extra fields for variable substitution
|
||||
- add extra fields for name reference
|
||||
176
examples/transformerconfigs/crd/README.md
Normal file
@@ -0,0 +1,176 @@
|
||||
## Supporting Custom Resources (defined by a CRD)
|
||||
|
||||
This tutorial shows how to add transformer configurations to support a custom resource.
|
||||
|
||||
Create a workspace by
|
||||
<!-- @createws @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
```
|
||||
|
||||
### Get the native config as a starting point
|
||||
|
||||
Get the default transformer configurations using this command:
|
||||
|
||||
<!-- @saveConfig @test -->
|
||||
```
|
||||
kustomize config save -d $DEMO_HOME/kustomizeconfig
|
||||
```
|
||||
The default configurations are saved
|
||||
in the directory `$DEMO_HOME/kusotmizeconfig` as several files
|
||||
|
||||
> ```
|
||||
> commonannotations.yaml
|
||||
> commonlabels.yaml
|
||||
> nameprefix.yaml
|
||||
> namereference.yaml
|
||||
> namespace.yaml
|
||||
> varreference.yaml
|
||||
> ```
|
||||
|
||||
These files contain the field specifications for native resources
|
||||
that transformation directives like `namePrefix`, `commonLabels`, etc.
|
||||
need to do their work.
|
||||
|
||||
These default configurations already include some common
|
||||
field specifictions for all types:
|
||||
|
||||
- nameprefix is added to `.metadata.name`
|
||||
- namespace is added to `.metadata.namespace`
|
||||
- labels is added to `.metadata.labels`
|
||||
- annotations is added to `.metadata.annotations`
|
||||
|
||||
### Adding a custom resource
|
||||
|
||||
Consider a CRD of kind `MyKind` with fields
|
||||
- `.spec.secretRef.name` reference a Secret
|
||||
- `.spec.beeRef.name` reference an instance of CRD `Bee`
|
||||
- `.spec.containers.command` as the list of container commands
|
||||
- `.spec.selectors` as the label selectors
|
||||
|
||||
Add the following file to configure the transformers for the above fields
|
||||
<!-- @addConfig @test -->
|
||||
```
|
||||
cat > $DEMO_HOME/kustomizeconfig/mykind.yaml << EOF
|
||||
|
||||
commonLabels:
|
||||
- path: spec/selectors
|
||||
create: true
|
||||
kind: MyKind
|
||||
|
||||
nameReference:
|
||||
- kind: Bee
|
||||
fieldSpecs:
|
||||
- path: spec/beeRef/name
|
||||
kind: MyKind
|
||||
- kind: Secret
|
||||
fieldSpecs:
|
||||
- path: spec/secretRef/name
|
||||
kind: MyKind
|
||||
|
||||
varReference:
|
||||
- path: spec/containers/command
|
||||
kind: MyKind
|
||||
- path: spec/beeRef/action
|
||||
kind: MyKind
|
||||
|
||||
EOF
|
||||
```
|
||||
|
||||
### Apply config
|
||||
|
||||
Create a file with some resources that
|
||||
includes an instance of `MyKind`:
|
||||
|
||||
<!-- @createResource @test -->
|
||||
```
|
||||
cat > $DEMO_HOME/resources.yaml << EOF
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: crdsecret
|
||||
data:
|
||||
PATH: YmJiYmJiYmIK
|
||||
---
|
||||
apiVersion: v1beta1
|
||||
kind: Bee
|
||||
metadata:
|
||||
name: bee
|
||||
spec:
|
||||
action: fly
|
||||
---
|
||||
apiVersion: jingfang.example.com/v1beta1
|
||||
kind: MyKind
|
||||
metadata:
|
||||
name: mykind
|
||||
spec:
|
||||
secretRef:
|
||||
name: crdsecret
|
||||
beeRef:
|
||||
name: bee
|
||||
action: \$(BEE_ACTION)
|
||||
containers:
|
||||
- command:
|
||||
- "echo"
|
||||
- "\$(BEE_ACTION)"
|
||||
image: myapp
|
||||
EOF
|
||||
```
|
||||
|
||||
Create a kustomization referring to it:
|
||||
|
||||
<!-- @createKustomization @test -->
|
||||
```
|
||||
cat > $DEMO_HOME/kustomization.yaml << EOF
|
||||
resources:
|
||||
- resources.yaml
|
||||
|
||||
namePrefix: test-
|
||||
|
||||
commonLabels:
|
||||
foo: bar
|
||||
|
||||
vars:
|
||||
- name: BEE_ACTION
|
||||
objref:
|
||||
kind: Bee
|
||||
name: bee
|
||||
apiVersion: v1beta1
|
||||
fieldref:
|
||||
fieldpath: spec.action
|
||||
EOF
|
||||
```
|
||||
|
||||
Use the customized transformer configurations by specifying them
|
||||
in the kustomization file:
|
||||
<!-- @addTransformerConfigs @test -->
|
||||
```
|
||||
cat >> $DEMO_HOME/kustomization.yaml << EOF
|
||||
configurations:
|
||||
- kustomizeconfig/mykind.yaml
|
||||
- kustomizeconfig/commonannotations.yaml
|
||||
- kustomizeconfig/commonlabels.yaml
|
||||
- kustomizeconfig/nameprefix.yaml
|
||||
- kustomizeconfig/namereference.yaml
|
||||
- kustomizeconfig/namespace.yaml
|
||||
- kustomizeconfig/varreference.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
Run `kustomize build` and verify that the namereference is correctly resolved.
|
||||
|
||||
<!-- @build @test -->
|
||||
```
|
||||
test 2 == \
|
||||
$(kustomize build $DEMO_HOME | grep -A 2 ".*Ref" | grep "test-" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
|
||||
Run `kustomize build` and verify that the vars correctly resolved.
|
||||
|
||||
<!-- @verify @test -->
|
||||
```
|
||||
test 0 == \
|
||||
$(kustomize build $DEMO_HOME | grep "BEE_ACTION" | wc -l); \
|
||||
echo $?
|
||||
```
|
||||
16
examples/transformerconfigs/crd/kustomization.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
resources:
|
||||
- resources.yaml
|
||||
|
||||
namePrefix: test-
|
||||
|
||||
commonLabels:
|
||||
foo: bar
|
||||
|
||||
vars:
|
||||
- name: BEE_ACTION
|
||||
objref:
|
||||
kind: Bee
|
||||
name: bee
|
||||
apiVersion: v1beta1
|
||||
fieldref:
|
||||
fieldpath: spec.action
|
||||
29
examples/transformerconfigs/crd/resources.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: crdsecret
|
||||
data:
|
||||
PATH: YmJiYmJiYmIK
|
||||
---
|
||||
apiVersion: v1beta1
|
||||
kind: Bee
|
||||
metadata:
|
||||
name: bee
|
||||
spec:
|
||||
action: fly
|
||||
---
|
||||
apiVersion: jingfang.example.com/v1beta1
|
||||
kind: MyKind
|
||||
metadata:
|
||||
name: mykind
|
||||
spec:
|
||||
secretRef:
|
||||
name: crdsecret
|
||||
beeRef:
|
||||
name: bee
|
||||
action: $(BEE_ACTION)
|
||||
containers:
|
||||
- command:
|
||||
- "echo"
|
||||
- "$(BEE_ACTION)"
|
||||
image: myapp
|
||||
146
examples/wordpress/README.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# Demo: Injecting k8s runtime data into containers
|
||||
|
||||
In this tutorial, you will learn how to use `kustomize` to declare a variable reference and substitute it in container's command. Note that, the substitution is not for arbitrary fields, it is only applicable to container env, args and command.
|
||||
|
||||
To run WordPress, it's necessary to
|
||||
|
||||
- connect WordPress with a MySQL database
|
||||
- access the service name of MySQL database from WordPress container
|
||||
|
||||
First make a place to work:
|
||||
<!-- @makeDemoHome @test -->
|
||||
```
|
||||
DEMO_HOME=$(mktemp -d)
|
||||
MYSQL_HOME=$DEMO_HOME/mysql
|
||||
mkdir -p $MYSQL_HOME
|
||||
WORDPRESS_HOME=$DEMO_HOME/wordpress
|
||||
mkdir -p $WORDPRESS_HOME
|
||||
```
|
||||
|
||||
### Download resources
|
||||
|
||||
Download the resources and `kustomization.yaml` for WordPress.
|
||||
|
||||
<!-- @downloadResources @test -->
|
||||
```
|
||||
CONTENT="https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/examples/wordpress/wordpress"
|
||||
|
||||
curl -s -o "$WORDPRESS_HOME/#1.yaml" \
|
||||
"$CONTENT/{deployment,service,kustomization}.yaml"
|
||||
```
|
||||
|
||||
Download the resources and `kustomization.yaml` for MySQL.
|
||||
|
||||
<!-- @downloadResources @test -->
|
||||
```
|
||||
CONTENT="https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/examples/wordpress/mysql"
|
||||
|
||||
curl -s -o "$MYSQL_HOME/#1.yaml" \
|
||||
"$CONTENT/{deployment,service,secret,kustomization}.yaml"
|
||||
```
|
||||
|
||||
### Create kustomization.yaml
|
||||
Create a new kustomization with two bases:
|
||||
|
||||
<!-- @createKustomization @test -->
|
||||
```
|
||||
cat <<EOF >$DEMO_HOME/kustomization.yaml
|
||||
bases:
|
||||
- wordpress
|
||||
- mysql
|
||||
namePrefix: demo-
|
||||
patchesStrategicMerge:
|
||||
- patch.yaml
|
||||
EOF
|
||||
```
|
||||
|
||||
### Download patch for WordPress
|
||||
In the new kustomization, apply a patch for wordpress deployment. The patch does two things
|
||||
- Add an initial container to show the mysql service name
|
||||
- Add environment variable that allow wordpress to find the mysql database
|
||||
|
||||
<!-- @downloadPatch @test -->
|
||||
```
|
||||
CONTENT="https://raw.githubusercontent.com\
|
||||
/kubernetes-sigs/kustomize\
|
||||
/master/examples/wordpress"
|
||||
|
||||
curl -s -o "$DEMO_HOME/#1.yaml" \
|
||||
"$CONTENT/{patch}.yaml"
|
||||
```
|
||||
The patch has following content
|
||||
> ```
|
||||
> apiVersion: apps/v1beta2
|
||||
> kind: Deployment
|
||||
> metadata:
|
||||
> name: wordpress
|
||||
> spec:
|
||||
> template:
|
||||
> spec:
|
||||
> initContainers:
|
||||
> - name: init-command
|
||||
> image: debian
|
||||
> command:
|
||||
> - "echo $(WORDPRESS_SERVICE)"
|
||||
> - "echo $(MYSQL_SERVICE)"
|
||||
> containers:
|
||||
> - name: wordpress
|
||||
> env:
|
||||
> - name: WORDPRESS_DB_HOST
|
||||
> value: $(MYSQL_SERVICE)
|
||||
> - name: WORDPRESS_DB_PASSWORD
|
||||
> valueFrom:
|
||||
> secretKeyRef:
|
||||
> name: mysql-pass
|
||||
> key: password
|
||||
> ```
|
||||
The init container's command requires information that depends on k8s resource object fields, represented by the placeholder variables
|
||||
$(WORDPRESS_SERVICE) and $(MYSQL_SERVICE).
|
||||
|
||||
### Bind the Variables to k8s Object Fields
|
||||
|
||||
<!-- @addVarRef @test -->
|
||||
```
|
||||
cat <<EOF >>$DEMO_HOME/kustomization.yaml
|
||||
vars:
|
||||
- name: WORDPRESS_SERVICE
|
||||
objref:
|
||||
kind: Service
|
||||
name: wordpress
|
||||
apiVersion: v1
|
||||
fieldref:
|
||||
fieldpath: metadata.name
|
||||
- name: MYSQL_SERVICE
|
||||
objref:
|
||||
kind: Service
|
||||
name: mysql
|
||||
apiVersion: v1
|
||||
EOF
|
||||
```
|
||||
`WORDPRESS_SERVICE` is from the field `metadata.name` of Service `wordpress`. If we don't specify `fieldref`, the default is `metadata.name`. So `MYSQL_SERVICE` is from the field `metadata.name` of Service `mysql`.
|
||||
|
||||
### Substitution
|
||||
Confirm the variable substitution:
|
||||
|
||||
<!-- @kustomizeBuild @test -->
|
||||
```
|
||||
kustomize build $DEMO_HOME
|
||||
```
|
||||
|
||||
Expect this in the output:
|
||||
|
||||
> ```
|
||||
> (truncated)
|
||||
> ...
|
||||
> initContainers:
|
||||
> - command:
|
||||
> - echo demo-wordpress
|
||||
> - echo demo-mysql
|
||||
> image: debian
|
||||
> name: init-command
|
||||
>
|
||||
> ```
|
||||
19
examples/wordpress/kustomization.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
bases:
|
||||
- wordpress
|
||||
- mysql
|
||||
patchesStrategicMerge:
|
||||
- patch.yaml
|
||||
namePrefix: demo-
|
||||
|
||||
vars:
|
||||
- name: WORDPRESS_SERVICE
|
||||
objref:
|
||||
kind: Service
|
||||
name: wordpress
|
||||
apiVersion: v1
|
||||
- name: MYSQL_SERVICE
|
||||
objref:
|
||||
kind: Service
|
||||
name: mysql
|
||||
apiVersion: v1
|
||||
|
||||
35
examples/wordpress/mysql/deployment.yaml
Normal file
@@ -0,0 +1,35 @@
|
||||
apiVersion: apps/v1beta2 # for versions before 1.9.0 use apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: mysql
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
containers:
|
||||
- image: mysql:5.6
|
||||
name: mysql
|
||||
env:
|
||||
- name: MYSQL_ROOT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mysql-pass
|
||||
key: password
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
name: mysql
|
||||
volumeMounts:
|
||||
- name: mysql-persistent-storage
|
||||
mountPath: /var/lib/mysql
|
||||
volumes:
|
||||
- name: mysql-persistent-storage
|
||||
emptyDir: {}
|
||||
4
examples/wordpress/mysql/kustomization.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
- secret.yaml
|
||||
8
examples/wordpress/mysql/secret.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: mysql-pass
|
||||
type: Opaque
|
||||
data:
|
||||
# Default password is "admin".
|
||||
password: YWRtaW4=
|
||||
11
examples/wordpress/mysql/service.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: mysql
|
||||
labels:
|
||||
app: mysql
|
||||
spec:
|
||||
ports:
|
||||
- port: 3306
|
||||
selector:
|
||||
app: mysql
|
||||
23
examples/wordpress/patch.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
apiVersion: apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: wordpress
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
initContainers:
|
||||
- name: init-command
|
||||
image: debian
|
||||
command:
|
||||
- "echo $(WORDPRESS_SERVICE)"
|
||||
- "echo $(MYSQL_SERVICE)"
|
||||
containers:
|
||||
- name: wordpress
|
||||
env:
|
||||
- name: WORDPRESS_DB_HOST
|
||||
value: $(MYSQL_SERVICE)
|
||||
- name: WORDPRESS_DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mysql-pass
|
||||
key: password
|
||||
29
examples/wordpress/wordpress/deployment.yaml
Normal file
@@ -0,0 +1,29 @@
|
||||
apiVersion: apps/v1beta2 # for versions before 1.9.0 use apps/v1beta2
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: wordpress
|
||||
labels:
|
||||
app: wordpress
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: wordpress
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: wordpress
|
||||
spec:
|
||||
containers:
|
||||
- image: wordpress:4.8-apache
|
||||
name: wordpress
|
||||
ports:
|
||||
- containerPort: 80
|
||||
name: wordpress
|
||||
volumeMounts:
|
||||
- name: wordpress-persistent-storage
|
||||
mountPath: /var/www/html
|
||||
volumes:
|
||||
- name: wordpress-persistent-storage
|
||||
emptyDir: {}
|
||||
3
examples/wordpress/wordpress/kustomization.yaml
Normal file
@@ -0,0 +1,3 @@
|
||||
resources:
|
||||
- deployment.yaml
|
||||
- service.yaml
|
||||
12
examples/wordpress/wordpress/service.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: wordpress
|
||||
labels:
|
||||
app: wordpress
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
selector:
|
||||
app: wordpress
|
||||
type: LoadBalancer
|
||||