Compare commits
2167 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4dd537066d | |||
| 9db19fb922 | |||
| 171f7e570c | |||
| e87745da8d | |||
| b1737a87a7 | |||
| 29e8f27983 | |||
| 1e35724ca0 | |||
| 7827c02b8e | |||
| b1bacf38e2 | |||
| 1ef330fe33 | |||
| e43e7523f5 | |||
| f98830bd39 | |||
| f5229ca882 | |||
| ae43ec1bfe | |||
| 6675a04821 | |||
| 4700d78095 | |||
| df6cb680e7 | |||
| 4e9df579f1 | |||
| a39553d328 | |||
| 2c4f453203 | |||
| 5d8a406419 | |||
| 734db472e2 | |||
| 43b2e77275 | |||
| a4aa4613cd | |||
| 9b94f198c3 | |||
| 2c66264fab | |||
| 4af87260d3 | |||
| 828a1bb210 | |||
| a54e81ece4 | |||
| 756c2fd8bc | |||
| 25f168f2f6 | |||
| 977ba2e810 | |||
| 8ff25b3f5e | |||
| da58c71c2a | |||
| 31efd0ad3a | |||
| 1f9ceb003d | |||
| c9b44f094f | |||
| 0d82d2df06 | |||
| 1fe6f70f5d | |||
| ae772a5a42 | |||
| 08e0981775 | |||
| c2b38df06f | |||
| 8ec133b06f | |||
| e3a4ff9b17 | |||
| bcd6bc07ce | |||
| ada25d09e0 | |||
| 9a311f4c3a | |||
| 828806b973 | |||
| 120f24ee25 | |||
| 02ef010015 | |||
| f21c56522a | |||
| 4d330619dd | |||
| 715af519d7 | |||
| 2b457e1612 | |||
| 08c735ecc6 | |||
| d534f730cf | |||
| ef350169a9 | |||
| 73a030236d | |||
| a6741614c2 | |||
| 89c6cff35d | |||
| 9ff9f5dd16 | |||
| d818691764 | |||
| a850ca2fc2 | |||
| 4915d216aa | |||
| 3ac2177603 | |||
| 97d371bcf7 | |||
| 575bd04640 | |||
| c45c0357fc | |||
| 2aa0117550 | |||
| 1e0c138fad | |||
| 4bfd5a6acd | |||
| be9926dff4 | |||
| 0df45a7130 | |||
| 1c15c9167e | |||
| 4778f62f07 | |||
| 3b7a5610ca | |||
| f470819727 | |||
| de0457df9a | |||
| 1a2e20268a | |||
| ddf3002561 | |||
| abeaf3e5ea | |||
| d567014251 | |||
| aaf9833b32 | |||
| 401690d7b5 | |||
| 54090324e2 | |||
| bb26915575 | |||
| 527f15ee47 | |||
| b40d3f54ad | |||
| 55d33c1311 | |||
| 6db181178f | |||
| f68907cdb5 | |||
| 601c5b2b9b | |||
| 60d8eaf339 | |||
| 8f67e373eb | |||
| 8d55192ee4 | |||
| 04a907ccc7 | |||
| 5c84822a9e | |||
| 83be6d3193 | |||
| 55a6fd2539 | |||
| d071289f7e | |||
| 80815add70 | |||
| 6fc10eaaa8 | |||
| f7c51d8db5 | |||
| 651a0c2183 | |||
| 8ceaf4daef | |||
| 5cab9ac7a0 | |||
| 380c92b7a6 | |||
| c5c8dd48b3 | |||
| 3e806911c0 | |||
| 728b13d7fd | |||
| bfaca72736 | |||
| 2fe20a8ac4 | |||
| c76841a40a | |||
| 475da9d22a | |||
| 0f8a345218 | |||
| 0b0b85b6ed | |||
| a30ecd33e2 | |||
| 65ec6fb144 | |||
| fe931e0d30 | |||
| 8e8328b585 | |||
| 583bc39de7 | |||
| 1e9582afc3 | |||
| 3c4f5639c1 | |||
| 05ae3dab2b | |||
| d3cbcb4539 | |||
| eedecdc685 | |||
| 818def30ed | |||
| a6edadd674 | |||
| de9db22f9e | |||
| d078b427b8 | |||
| 85868d8fcc | |||
| 1a5c82baf7 | |||
| ba22677b4c | |||
| 4226eb76c6 | |||
| 15d601f1fd | |||
| 71a5a6a303 | |||
| 526f0d2972 | |||
| 1bc3b21ed4 | |||
| 498647c438 | |||
| e4d7ffb6d6 | |||
| 45698e8c40 | |||
| 0466dcf49d | |||
| 09903e156f | |||
| 2153412d4e | |||
| b2084c9928 | |||
| de41be399f | |||
| 26748e36b0 | |||
| 4aa2b6df61 | |||
| 2ab22a83ce | |||
| 403dbdcc15 | |||
| f06b6241a5 | |||
| 8c47137784 | |||
| 9c7d7dcdf6 | |||
| ddfd37581a | |||
| 777fe8e420 | |||
| e3f2a445bc | |||
| 959d0c759b | |||
| 9fb15a8382 | |||
| 74cbcc4ae3 | |||
| b567e32edc | |||
| d4184d45cb | |||
| 7a8389ccc2 | |||
| ee312ddc56 | |||
| b078e4916e | |||
| 552ac504a1 | |||
| 29504f7de0 | |||
| a3b42b55ed | |||
| 8d5b42e580 | |||
| bc05d880e3 | |||
| f7688691e1 | |||
| 626b101340 | |||
| 0ef9001c5e | |||
| 8bd5598f3d | |||
| 9eb90fddd8 | |||
| d095a148f2 | |||
| 68c66893ab | |||
| 59fd8e2493 | |||
| 1779ade51b | |||
| b734ae26cc | |||
| 723cb63929 | |||
| 71fd082bad | |||
| e92c299996 | |||
| 98a52cdede | |||
| 72af5fdf2f | |||
| 77cca2346f | |||
| 7145fb89d6 | |||
| dfd2edc70c | |||
| 0ef4ca477a | |||
| 9c61f34abd | |||
| 0d3ee7d869 | |||
| b690338f07 | |||
| 4cffdf8c57 | |||
| f6cfb5e591 | |||
| 3d02876f69 | |||
| fd4bb39482 | |||
| 11ca5f06dc | |||
| d439e57224 | |||
| f466d7f27d | |||
| 4c52c1b763 | |||
| cd66d836ee | |||
| d3fd592447 | |||
| 30e5eeb862 | |||
| e8b498ee14 | |||
| 1454c2abf0 | |||
| c2b7ee8bfe | |||
| bd39651298 | |||
| 52bc988bb2 | |||
| 9c5d9e55f1 | |||
| c80e5640da | |||
| 528a65c634 | |||
| 79684f8771 | |||
| 5c2ef8054c | |||
| bed9e2c5d6 | |||
| 44ed2f78ca | |||
| 3f6b8a17e3 | |||
| b5a718a9a6 | |||
| 9aced1d40a | |||
| 54f69ca1f8 | |||
| 9021c7470f | |||
| e632f8fb9c | |||
| c40c3f500d | |||
| e683359a2d | |||
| e76f7a72cb | |||
| 7623013796 | |||
| 23aafddd82 | |||
| 59b4b7f494 | |||
| 0a3c4c98dc | |||
| 00cb19d3f9 | |||
| be30472ac0 | |||
| 77067866e2 | |||
| 6f1ecf9855 | |||
| 98b355fa2b | |||
| 7f732fcb01 | |||
| 6d273bda2f | |||
| 0d57c5dffa | |||
| 27e5f9fedc | |||
| d415f62dd2 | |||
| 027eb249af | |||
| bff0e68efa | |||
| 8ff3213727 | |||
| cbc3d89fef | |||
| cd25f73d73 | |||
| d405225415 | |||
| 51c621a6ba | |||
| e71a7ffcae | |||
| 44bdc8767f | |||
| f4a8ecf31d | |||
| 782e6264de | |||
| 5b988bd661 | |||
| c8841ce552 | |||
| 470af7fdee | |||
| 4359612f85 | |||
| b6f952a00b | |||
| 40b183cea3 | |||
| cabea71972 | |||
| 909916aecf | |||
| 5f4a3fff9e | |||
| 30c671fdc7 | |||
| 6493a185ff | |||
| b0a27053d2 | |||
| 3dd33ef107 | |||
| 0ca94eebab | |||
| 46987cf0e9 | |||
| 5f8fdc6abb | |||
| d77ab6d2b9 | |||
| 85d8b843d3 | |||
| bef5681585 | |||
| 7095fcce17 | |||
| da677ad55d | |||
| 85cc70b333 | |||
| cc9011a42c | |||
| 23c6fea4c1 | |||
| 4d77af2dc4 | |||
| b03eb840b1 | |||
| f91fa01d10 | |||
| d4c540fb31 | |||
| bcdbf80e70 | |||
| fe7771aeac | |||
| 36df19e1d5 | |||
| 95bd61612d | |||
| 0e06c4f6cd | |||
| 98cdc3685f | |||
| 2ba49ba415 | |||
| 9693458ae2 | |||
| 2c5fabeeaf | |||
| 50cb3d3441 | |||
| b158496435 | |||
| 25de96863d | |||
| 9d0d213814 | |||
| 131632c58e | |||
| 1b90286094 | |||
| f3b0b30840 | |||
| 7146318713 | |||
| 484dc86ddf | |||
| 0473573924 | |||
| 6e9e8b2b2d | |||
| 0609536064 | |||
| e5cb74ba69 | |||
| f8ee06c41f | |||
| 506ee6ff68 | |||
| fcdb99341c | |||
| f65f046cb5 | |||
| fa8b7be065 | |||
| 91f9871225 | |||
| e14fd8eccc | |||
| 020dbf091f | |||
| d5c7714da9 | |||
| 397edb91f7 | |||
| b536f0d214 | |||
| 757298d1d6 | |||
| d7e735710f | |||
| 30c6cec1ba | |||
| d59c77f647 | |||
| 2c02aeb43a | |||
| 9296fc4ff0 | |||
| 7aa360d29f | |||
| 442a1bf172 | |||
| b1573ad314 | |||
| 0732592a13 | |||
| 542118b8f4 | |||
| b0a48af6f7 | |||
| c994376007 | |||
| 1cee24265b | |||
| f522a71e5e | |||
| 7790ca7dc3 | |||
| 2934244ebf | |||
| 63d1cec41e | |||
| 4f104d6355 | |||
| 96d89ba3f4 | |||
| a9d9e81460 | |||
| 137690980d | |||
| 875b67c219 | |||
| 286c1b1b72 | |||
| 2616547b98 | |||
| 670116cc39 | |||
| 9f501d0f73 | |||
| b4864367c5 | |||
| 0e43a37046 | |||
| 4d991d52f4 | |||
| fdcc9de6fe | |||
| 9fedbf68ea | |||
| dc8bfd3cbb | |||
| 8783a78004 | |||
| bdcd2f373e | |||
| 2c9ebb38f2 | |||
| 477383508c | |||
| d2db54fbb7 | |||
| adf0e0f9ff | |||
| cfca8c2f89 | |||
| e9d3e72b74 | |||
| 878194b52f | |||
| 64fe06a642 | |||
| eb902b9ba8 | |||
| 94b1216dfd | |||
| 642732a98f | |||
| 8e737b26da | |||
| 571adf73bb | |||
| 14d3118a01 | |||
| d519007384 | |||
| 07627bd7d3 | |||
| 5d1384635e | |||
| 0606d22bae | |||
| 9946750ae2 | |||
| e13a8fbba0 | |||
| 041870e849 | |||
| 45f69e5f7c | |||
| 7a85763a8e | |||
| 6c542e88c2 | |||
| dd443f0238 | |||
| 6e6c1f8920 | |||
| 1fd7c9cbd3 | |||
| 83e289d27f | |||
| 2b97646e39 | |||
| 374bb0547a | |||
| 0696f6181a | |||
| 3f21885d6b | |||
| e4615a2ffb | |||
| 3dcead4f68 | |||
| 4b1df4d306 | |||
| fb7bdd52db | |||
| 993e3e9104 | |||
| aa7acf8aea | |||
| c56459a402 | |||
| fbc0bf209e | |||
| 4976105f3a | |||
| 74ac7a96f6 | |||
| bb7066c46a | |||
| caf5e53e72 | |||
| 4a893a2cb3 | |||
| 59843f7d49 | |||
| cb831d7c94 | |||
| 865bb4612c | |||
| 2ba16150ec | |||
| ad5afa3dfa | |||
| 1542bedae4 | |||
| 81086664f1 | |||
| 081c5fa7aa | |||
| 7e732774ca | |||
| c4f7026b4e | |||
| a879763872 | |||
| ee0f03c755 | |||
| 3c7ed800d0 | |||
| 7202c68a9e | |||
| a2c3d64a1e | |||
| e36837e3a3 | |||
| df71479a6e | |||
| 4222cb1b46 | |||
| 3de9fc63e4 | |||
| a64769c54f | |||
| 7f1385f8f8 | |||
| 752122089d | |||
| a909bd7a74 | |||
| e284bf7d9d | |||
| f7c96a4c00 | |||
| 1fac17f532 | |||
| 792093b37c | |||
| d7da6f8af8 | |||
| 338139971f | |||
| 1d89bc1763 | |||
| 59fd242de4 | |||
| 437e2a74f8 | |||
| 077f0ca38f | |||
| 20eea3b75b | |||
| c146f271a3 | |||
| 134900b658 | |||
| 15b64da3dd | |||
| 81c92e134e | |||
| 2ebbdd6a1e | |||
| 35d30bda8a | |||
| 85adb64d72 | |||
| 9ab5a710e9 | |||
| 0c5a2e06da | |||
| 4809013f75 | |||
| b05de02eaa | |||
| d169f75ce3 | |||
| f0bc1f3ef7 | |||
| 09fb71126c | |||
| ca1f9bd689 | |||
| 88275eab73 | |||
| cb2db15312 | |||
| 97e1fb57bf | |||
| 2f282de8ae | |||
| 63405a399a | |||
| d295c65929 | |||
| a0c1002334 | |||
| 84fea74349 | |||
| 85ce997d58 | |||
| b83dc6c8e6 | |||
| c4127ad8d2 | |||
| 956eb48e72 | |||
| 495cbf0260 | |||
| 14efc9881b | |||
| a22cab7aed | |||
| 0742545417 | |||
| e7cdc8df51 | |||
| 71d17c3f68 | |||
| b5810b18d9 | |||
| 02d056eef8 | |||
| 4fb2fe8449 | |||
| 1ae373813f | |||
| f18ccaa622 | |||
| 3469c12794 | |||
| 25f3914b41 | |||
| 0d6ae289a9 | |||
| 4efba9b18a | |||
| 812e3fbb03 | |||
| a7de73262a | |||
| b6578e7223 | |||
| 5bb8db31ad | |||
| 92d859d14d | |||
| d9f11f3b19 | |||
| 5f6f123db7 | |||
| 8bd82af7c7 | |||
| 4c2d853003 | |||
| 49cb396eaa | |||
| e87ee3e927 | |||
| 4560e5e9b9 | |||
| 34b701c10f | |||
| 729414f650 | |||
| 1f42a30967 | |||
| a0cab7282a | |||
| 0b3ee6bbd5 | |||
| db84fe3ab9 | |||
| 21ef3efaa1 | |||
| f5f8af8373 | |||
| a5e12d04df | |||
| 1000c4c263 | |||
| ecd4652de1 | |||
| d9aad165a3 | |||
| 4740c728ab | |||
| a83f5ef666 | |||
| 04557972f1 | |||
| ce5dd40bac | |||
| e1c89a54f1 | |||
| 3da18a272e | |||
| 23c35836dd | |||
| 7f09fb0073 | |||
| 703468bb5b | |||
| 9452773b4a | |||
| 66d4431eb8 | |||
| 2648f1f73c | |||
| 3cc8f3fec8 | |||
| 55d2aa3b03 | |||
| aad34c5acf | |||
| fe940d9263 | |||
| 3e1a0eb1e6 | |||
| fc95bc68f8 | |||
| 2d0363fdaa | |||
| 1e2fc4d599 | |||
| c889d48477 | |||
| 538bf40eb3 | |||
| 0a0b8859e3 | |||
| 7045fc791d | |||
| 49b6a8a721 | |||
| db0e59cbb0 | |||
| 28a2d58c14 | |||
| a2e36cc335 | |||
| 8af5744ea3 | |||
| ec138ea002 | |||
| b2e77eb52b | |||
| 32ff99fd16 | |||
| 1be01b1aff | |||
| 21f7528b75 | |||
| dbda7491c2 | |||
| 955208da74 | |||
| 2b5b50394b | |||
| 7dd160fd3f | |||
| 8b5fb9939b | |||
| 3f5a3fe6ed | |||
| 6ebdc7cd11 | |||
| 6a415432d6 | |||
| c8a98bb13c | |||
| 1dbbb785ae | |||
| 8021449588 | |||
| 2d5ac7d2bd | |||
| b16c4c9391 | |||
| aae3f87682 | |||
| 6caa9bd535 | |||
| 3ccaf3a0b7 | |||
| 3495e6c4a2 | |||
| d26f9ac045 | |||
| 6f3bd1e71a | |||
| 94096723f3 | |||
| d6a0e9b332 | |||
| 74d913a919 | |||
| 86984f220e | |||
| 0d89aeb02e | |||
| ea8c49dbb9 | |||
| b089cf0376 | |||
| 91afafd592 | |||
| dabee46b88 | |||
| 7f6a77efe8 | |||
| ac9f04cd14 | |||
| 09d368cec6 | |||
| 9f3e905ea6 | |||
| 76b7f9fd3f | |||
| c3ed460bed | |||
| ce75bce0fb | |||
| b6f66c941b | |||
| 955ae25dd3 | |||
| 286cf8f763 | |||
| d22f387f7c | |||
| a162b01911 | |||
| 626aaffb2c | |||
| be1f5e6b35 | |||
| 2fe21477b4 | |||
| 45d5e25b6c | |||
| a7c82a6308 | |||
| 8b789a73de | |||
| 487cdfa07e | |||
| 57d21c6975 | |||
| dcd6cd5793 | |||
| 5eb9ded91a | |||
| 4b656ff45a | |||
| 6ad9c33963 | |||
| 7b22f1a134 | |||
| d5feed3ed7 | |||
| d10cd6ee48 | |||
| 94a460352a | |||
| 620e11f499 | |||
| 5d4f35d5eb | |||
| 0e7810ad04 | |||
| 860fd15404 | |||
| dc8882da98 | |||
| cafede5fb9 | |||
| c88edba662 | |||
| ae1ae50454 | |||
| 4600715899 | |||
| 6cc9bf8293 | |||
| c5e229eea9 | |||
| 0709b30d05 | |||
| a09d4ec1cf | |||
| 8c9e504d75 | |||
| 1c673f0679 | |||
| 869ce6a75a | |||
| 6b324fe12f | |||
| 5fb3176087 | |||
| 836838e77f | |||
| e93092524a | |||
| 8fc4e07ff6 | |||
| c4d103bf8e | |||
| ce87d890da | |||
| d18d8d857e | |||
| c6bf5d13c8 | |||
| 6d0d8c0d7d | |||
| 8b3528af61 | |||
| cdfdd3eda3 | |||
| e3676f5e16 | |||
| 38f3e13c57 | |||
| 731f028586 | |||
| 024f281db4 | |||
| 984846e53f | |||
| 682912bc67 | |||
| 018e445c7b | |||
| 8f27660e8f | |||
| af4a9c3783 | |||
| 5cfba9ebb2 | |||
| e315da8f11 | |||
| 5288513b58 | |||
| 1757f4b148 | |||
| b626b80b47 | |||
| 045ed2d8c5 | |||
| 2305affb8c | |||
| 9d06dc7cdb | |||
| 227d2b1271 | |||
| 7168e4d691 | |||
| f670a7ac90 | |||
| 94d89c5f4c | |||
| 7c256aa07e | |||
| 2fb4914100 | |||
| 4bcb8545e8 | |||
| 959356a46a | |||
| f36d230101 | |||
| f193a5fdf6 | |||
| ee11c6c331 | |||
| 03571b445d | |||
| 47de513a89 | |||
| 6c32a72d0e | |||
| 55cc56b8b3 | |||
| 99a0502665 | |||
| 9b49165995 | |||
| 936d7987f2 | |||
| 022dcfb716 | |||
| 8f00a636fc | |||
| 4677721c52 | |||
| e0738eba63 | |||
| 21ca9a224f | |||
| 12c57e6683 | |||
| 037456870f | |||
| 64a7157643 | |||
| bfdb9654a2 | |||
| e33dea35ce | |||
| e26ff03d29 | |||
| 1b931a4a24 | |||
| 284389853d | |||
| 6f204508ae | |||
| ad1d8799fc | |||
| 08a8887464 | |||
| 7ac583a56a | |||
| 1782fb440e | |||
| 04d0c72c32 | |||
| 3548f2852f | |||
| ffab78891c | |||
| 673671b741 | |||
| 307ae699c3 | |||
| f0f957ff21 | |||
| c2d7782e5a | |||
| 604e271204 | |||
| e61d14939d | |||
| 1850ddc30c | |||
| 0a38260ecb | |||
| feecbcba66 | |||
| eca7226dfb | |||
| 93a1a281b9 | |||
| e10996a1d7 | |||
| 2876a43a35 | |||
| 6df48cef0e | |||
| b2e5fcd51f | |||
| 391459b11f | |||
| 7f15418fae | |||
| ba20879546 | |||
| 837e1c672e | |||
| 67ce826dc4 | |||
| da31234d5d | |||
| b3aef35da7 | |||
| e38d549721 | |||
| 0aef916e81 | |||
| ba4287421c | |||
| 69c9e63e9f | |||
| 4bb1fc1f8c | |||
| 3ca34b9a3b | |||
| 95842c3a4e | |||
| fabc5cf65f | |||
| 419234f427 | |||
| 53da9dfa2a | |||
| 49e1c4b579 | |||
| a5bff81f7f | |||
| 4f138528b6 | |||
| 588d7ef7ca | |||
| 9ae9f5336d | |||
| bba18acd4e | |||
| e1288a9129 | |||
| bf00b72c79 | |||
| 909caa59a5 | |||
| 93dcf864e2 | |||
| 41e3265567 | |||
| f67b8ffab9 | |||
| c4123fe383 | |||
| 53e0c4c1af | |||
| 2c7d774239 | |||
| 8152a75765 | |||
| e6459692d2 | |||
| 5dfcf92490 | |||
| 584097ebfa | |||
| 46c2fb6c98 | |||
| ddd130c375 | |||
| ff0018b97e | |||
| e3f54e0089 | |||
| 1df00698d4 | |||
| 51b0bc1874 | |||
| c3d5c69126 | |||
| 480a5f737f | |||
| 620cdbb677 | |||
| 80a84f68a0 | |||
| 304bf1bc53 | |||
| aa0890d2c4 | |||
| 4943d46433 | |||
| dd347e353b | |||
| 3c1787a4d8 | |||
| c73d473cca | |||
| df2457c093 | |||
| 9d6baceb49 | |||
| e9703497a1 | |||
| cd30245ed5 | |||
| b7fa9ef8f2 | |||
| 79c2fe1ad2 | |||
| 58f3a9c300 | |||
| 414dbf2ecc | |||
| 56272ef4d9 | |||
| feff516812 | |||
| ede15be105 | |||
| 16b5435c62 | |||
| 7d4ed843f0 | |||
| fd331f35df | |||
| e27888a089 | |||
| 5a5c96b2cc | |||
| 11afd156d2 | |||
| 1ae5374fa0 | |||
| b065416e1c | |||
| 482b53e3df | |||
| 42af0d2f58 | |||
| 3501c3b9c4 | |||
| cc5ca4f049 | |||
| c2a5b2b39a | |||
| 09b838fa6c | |||
| b66f9a0115 | |||
| 1096e3bcd5 | |||
| 3529fc6ebb | |||
| 45a1150178 | |||
| 46045cf53a | |||
| 51ccd736f5 | |||
| 84a6862a2a | |||
| e5b5f45e7c | |||
| 75b274a915 | |||
| e7600828eb | |||
| 701fe1d733 | |||
| 6fae06b5c8 | |||
| 3d35f770d0 | |||
| e31b30576b | |||
| 1fabeed318 | |||
| b4fc266671 | |||
| efafee8ee0 | |||
| 939f7d0c80 | |||
| cad573d5fa | |||
| ae18bd4806 | |||
| ef178c5a3e | |||
| 9a611b2e2a | |||
| 3a74cb7275 | |||
| e60c68f756 | |||
| 5aab352c81 | |||
| ad177b2e71 | |||
| 79e049b028 | |||
| 2d46bfb913 | |||
| 6731e5cb15 | |||
| 6594729f5d | |||
| 8282ae39a9 | |||
| 7d61e15524 | |||
| ad93c9a6ef | |||
| 15dba8f975 | |||
| 8a8427ef5e | |||
| d92c9f2a74 | |||
| 8789b66345 | |||
| 4267616e07 | |||
| fa912fe62e | |||
| 6039c1b32e | |||
| 91bab67e80 | |||
| 126e636fb5 | |||
| 43f8f63809 | |||
| 2b097d494a | |||
| ea83fa8ec4 | |||
| 7aabb11bbb | |||
| 7332187091 | |||
| c2234e1154 | |||
| 83117ce20b | |||
| bdeeed8266 | |||
| c03963607a | |||
| 6a3ea501e0 | |||
| 191506a9f8 | |||
| 3540214344 | |||
| 7bdab6f121 | |||
| d6a5fb221b | |||
| 588f6c2e0b | |||
| 314179dd37 | |||
| 0bad7d1e06 | |||
| dbb0ecab79 | |||
| d456e9c403 | |||
| cacad0e02e | |||
| 97a453a505 | |||
| 2a03ddea27 | |||
| 1f1d15f4d0 | |||
| 494c825656 | |||
| 1f6e7cc742 | |||
| c623e2c233 | |||
| 30b9889f01 | |||
| eaafee93a4 | |||
| b7364a4df6 | |||
| 63a94667e8 | |||
| b2ee46c93d | |||
| 21555751e4 | |||
| 2f6acf7b2d | |||
| 05245d8757 | |||
| bcc64ffb7e | |||
| 8986c56dfb | |||
| 69cf8dd710 | |||
| ba734d4412 | |||
| 8c580b8c72 | |||
| 858e73a417 | |||
| 1e402f834d | |||
| c18c0acb38 | |||
| 79447ed22b | |||
| 38291299be | |||
| 94b1fd0c11 | |||
| df1aa0728b | |||
| c1858c6134 | |||
| 038b2b99a7 | |||
| 595962652b | |||
| deba5807c9 | |||
| 3762e01c6d | |||
| 2f4a570f0c | |||
| 5582a91e4b | |||
| 0295ca4f9e | |||
| 36a464b5f4 | |||
| 969706c388 | |||
| fd3422a561 | |||
| 94b2004b82 | |||
| 03d885ebc0 | |||
| ae45ec249e | |||
| c3624aba96 | |||
| f44e3ff8c8 | |||
| 44eea9958e | |||
| 23122963bc | |||
| 7f0111d68a | |||
| 1e50590bc4 | |||
| 86597ed556 | |||
| 765877ac7c | |||
| f9d249b415 | |||
| b22d548851 | |||
| cbc503206a | |||
| 9a303171a6 | |||
| ddc67b8114 | |||
| 6852192fc4 | |||
| 0bf3cb6b6c | |||
| 676da1fe64 | |||
| 181cdb0f1d | |||
| d1fa1547e7 | |||
| 869c5c04ca | |||
| 32dbaaaaea | |||
| fbab5a864d | |||
| af063002a9 | |||
| df7088934e | |||
| 4f62d70405 | |||
| 6efa69b3fd | |||
| fa66b1c724 | |||
| db7be243a4 | |||
| fc82534c5b | |||
| b38fe10b73 | |||
| 8d40a8560c | |||
| 745e62c4d6 | |||
| d2f5f92e8b | |||
| aa4e715c26 | |||
| 3c69a21f23 | |||
| 2801962020 | |||
| b7dc57f73d | |||
| 58fc28ecb8 | |||
| c73d0510b9 | |||
| 5cf02fde98 | |||
| e4dde86ce2 | |||
| 3874ee3a96 | |||
| 4502d3b438 | |||
| c787c02b81 | |||
| baf379436b | |||
| 454ebcfd48 | |||
| 6bbe2ff4e9 | |||
| 55f1b0a4b9 | |||
| 8980a7d339 | |||
| b8978f5906 | |||
| edac091e45 | |||
| f0c13220f1 | |||
| 8c4b1d3e86 | |||
| 1a33732455 | |||
| 20c11beb32 | |||
| 7b4b91831e | |||
| 36dd47fa60 | |||
| 2ca47a8e94 | |||
| 8fee2a9ae9 | |||
| cfa387a2df | |||
| ade29b7f44 | |||
| 04ea603058 | |||
| 1f70fdbf44 | |||
| ed7eb19f8b | |||
| d0689c9937 | |||
| b54f8b02d4 | |||
| 892a71113d | |||
| 56dbcd6731 | |||
| 9f8abfadd0 | |||
| b3c36f6b5e | |||
| 7a02a387dc | |||
| 57b22c21d5 | |||
| c60ea43c62 | |||
| 4b624fb8ad | |||
| 2193b58d86 | |||
| 9d00e14cd1 | |||
| 2de5a5b6d0 | |||
| 698187e97b | |||
| 31d86b7ce4 | |||
| 71a20e6e3e | |||
| 498ad04207 | |||
| d9f1f90b78 | |||
| bd7a705b3b | |||
| cd04c8a1f6 | |||
| dce880dc42 | |||
| 8dfb6f9276 | |||
| df5ece0a1d | |||
| 4bdc9057aa | |||
| 13349883d1 | |||
| fade58afbf | |||
| 0893e5b1cc | |||
| beabc4a7e1 | |||
| 905619a79b | |||
| 8d50647fdb | |||
| 4c111df415 | |||
| 104ec65282 | |||
| 612ebcc559 | |||
| 1564cafee6 | |||
| b03254526f | |||
| 5736e480db | |||
| a64a4fd2f5 | |||
| 207ba045e4 | |||
| 662bedc113 | |||
| 05c1eb0030 | |||
| 5bd85f4969 | |||
| 77c019e97b | |||
| cf2d39aae9 | |||
| 316667729c | |||
| bdcc6cf1f0 | |||
| c848390b05 | |||
| edb849a725 | |||
| dfaefa54aa | |||
| f0be2cf9a5 | |||
| dbca4e41b7 | |||
| 8f4dea0311 | |||
| fe81c57bee | |||
| af5cd5cf5f | |||
| 50395fca0d | |||
| 19187d0b72 | |||
| 85965ec8d0 | |||
| 7f3e885e0d | |||
| 88018a88f2 | |||
| e10fada007 | |||
| 5e27d2ee60 | |||
| 1ada7f1a26 | |||
| 64558544ec | |||
| 80076c421c | |||
| 5e269e1069 | |||
| f7741ccf6d | |||
| d761a2433d | |||
| fa890d945f | |||
| 091a926bbd | |||
| 1b09f57bec | |||
| 66d856101e | |||
| 252cdaa736 | |||
| c0d1bef1b1 | |||
| d2dd0b0545 | |||
| 7ebb227122 | |||
| 428e30e521 | |||
| c671224d1d | |||
| beb78354d6 | |||
| 89027bd963 | |||
| 64ac9c4530 | |||
| b8ed7e2298 | |||
| 9f09fe0e94 | |||
| 23dbe3823b | |||
| 6e1ac284da | |||
| 7f4281ebb3 | |||
| 29e7f7c045 | |||
| 590d07f922 | |||
| 9c1a5245b0 | |||
| 34b3f3de11 | |||
| 11bc6b4efc | |||
| f007e221ba | |||
| dcb54be0e1 | |||
| 1a3e0e3c13 | |||
| 57cb82ed38 | |||
| 6fea231c1c | |||
| 9991e07af3 | |||
| d3217b35d5 | |||
| eaa215eee1 | |||
| b3e9ecd9fc | |||
| 1563603a9d | |||
| c765642679 | |||
| 44acf9c33a | |||
| d60462e1cc | |||
| 5a44baf9bd | |||
| 70d80a89e6 | |||
| 942368b7da | |||
| e63a5de42d | |||
| 918e3f7382 | |||
| c7e1728499 | |||
| bac00a3e3c | |||
| 9187109138 | |||
| 7af03687a0 | |||
| a9fb2d35d0 | |||
| fbd727dfe1 | |||
| d31ed578ed | |||
| 8b8a6b26ad | |||
| 40b6ae6b0f | |||
| 610835108f | |||
| 1383eb4900 | |||
| 46e509c4aa | |||
| abce898833 | |||
| a7de342b39 | |||
| a8c99f3268 | |||
| c8322dccd1 | |||
| d23870fa26 | |||
| 8c4a748db1 | |||
| da6f537703 | |||
| 3020b23c49 | |||
| f9b2c8c932 | |||
| 96a1f1ea45 | |||
| b33e1aec19 | |||
| 3564a5fd99 | |||
| 4bbd560602 | |||
| 3e27190477 | |||
| 86fa9cff43 | |||
| a45df4e2a9 | |||
| 1da4203c47 | |||
| ac63e4c22a | |||
| 3532f1f4dc | |||
| 7187bda229 | |||
| db776acfca | |||
| 51f154c7c8 | |||
| d6640e32ed | |||
| 796adb952f | |||
| 147f321e69 | |||
| 1fb1251db9 | |||
| 779b6cad72 | |||
| 6e75f25d04 | |||
| 32a97a9989 | |||
| 9d5c3d4798 | |||
| 95d0cc621a | |||
| 1f822ba7c7 | |||
| dfe4b47bbe | |||
| bf608bdb6b | |||
| 7d2fb1e5fe | |||
| 66e8a19e78 | |||
| 5fba7a91da | |||
| 1001806b01 | |||
| 43cee67f88 | |||
| 333b04b12f | |||
| f1ae3ed632 | |||
| 0a7120a939 | |||
| e9ad987d02 | |||
| 381a07528c | |||
| 40e305ac9d | |||
| 496bccbe4f | |||
| 38977dfa71 | |||
| bff31ff2b4 | |||
| 99f542cbae | |||
| 0a3ee58cb4 | |||
| d54878ec75 | |||
| 131c3a313e | |||
| d763553fc3 | |||
| 158cf877a5 | |||
| 5695c69a14 | |||
| 67afbe3b8f | |||
| dbf41bf41b | |||
| 67c7ab0c4d | |||
| 6916aea2d5 | |||
| e03702f13b | |||
| 7376d834cb | |||
| dd05e6211d | |||
| b2dbcdceee | |||
| 47a137594b | |||
| 6145b61f00 | |||
| 5709cb1e6a | |||
| 487e9324b6 | |||
| 259bdd2848 | |||
| 14de2197f6 | |||
| 3b55463123 | |||
| 8df153c37b | |||
| 779c3fac9f | |||
| 2b227b6b07 | |||
| c56839e403 | |||
| 16b3301da9 | |||
| 4e6a6b8965 | |||
| e4550dc620 | |||
| aa2be37048 | |||
| ccc61c87fc | |||
| 4efbf939cc | |||
| 086f663970 | |||
| 8f8b147e52 | |||
| 991bb00b59 | |||
| 91f613e3ae | |||
| d398b75e19 | |||
| b181193907 | |||
| 51e4200a67 | |||
| e72b6ace24 | |||
| 0b826545e8 | |||
| 726587e8ad | |||
| c1d5b91a11 | |||
| 1a89995f57 | |||
| 46a0fb74a8 | |||
| 2021adac4a | |||
| 0103741138 | |||
| 5bcadad345 | |||
| 097292f485 | |||
| 006fbf6486 | |||
| a0ef54f24d | |||
| 5da03f2aee | |||
| a2c1fd7617 | |||
| 39796d1481 | |||
| 8bdc23cf82 | |||
| 5dee7af9de | |||
| 631bfd574a | |||
| ec6b53143b | |||
| 43de76853a | |||
| 96c83e7ec5 | |||
| 6803d4dc80 | |||
| c5457e0b4f | |||
| 6a2b65d85d | |||
| b80558fe4a | |||
| 836fb1c8d1 | |||
| 5d2f1a317c | |||
| 1b0151039e | |||
| 1dcae361ea | |||
| 8ac8d358e6 | |||
| cafc10704d | |||
| 5cd82a6ff8 | |||
| 2a80c6d052 | |||
| 08df1089e1 | |||
| fcefe0776a | |||
| ef49d66139 | |||
| a7e39ecdb0 | |||
| 249731705d | |||
| 5dd5d61366 | |||
| bf40d496c1 | |||
| 465b7860f8 | |||
| e233f16855 | |||
| 7dfc7f8567 | |||
| 731cd8c138 | |||
| 99dbe4a628 | |||
| fc048b3d86 | |||
| d541be6473 | |||
| 4219d77e90 | |||
| a4f7ed2a38 | |||
| 0bb7c6f713 | |||
| 5bb726ba16 | |||
| a63b896950 | |||
| 7f9817161c | |||
| fb45be31e9 | |||
| b26563c314 | |||
| cd80215e9b | |||
| 0e265010e5 | |||
| 30ec372a49 | |||
| 923b19e533 | |||
| 9a7f807474 | |||
| 1f1c57cf8e | |||
| 39e22bec23 | |||
| 415468a1a3 | |||
| 3a8af16d57 | |||
| 11e20bc617 | |||
| cb45398881 | |||
| ee0a4261a4 | |||
| e75e654c93 | |||
| 1416b65c64 | |||
| b423476587 | |||
| 4ee94306f2 | |||
| d4146d2384 | |||
| ceddffeb1e | |||
| cb161cfdc8 | |||
| 2ef52e596d | |||
| b37d82a0a3 | |||
| c44acaba89 | |||
| 4f669fd2e3 | |||
| 706627109d | |||
| daa72d0622 | |||
| 1753d09792 | |||
| c576c3a3ee | |||
| adf144cf58 | |||
| d2025e448c | |||
| 4bb8737568 | |||
| 81aa62d9ff | |||
| 941f5d51cd | |||
| 0885df43c5 | |||
| b8ab5835b9 | |||
| dcd2dd4852 | |||
| c315df3c0f | |||
| 89e642d082 | |||
| 29c0554d70 | |||
| 42313ab058 | |||
| 4795d7fe35 | |||
| 1638e3543f | |||
| 94da19ea23 | |||
| 6b7072e507 | |||
| 44d3c6e83d | |||
| b0b88679d4 | |||
| 6a0f974f7b | |||
| df00b046cd | |||
| e43de9ad16 | |||
| 3ca030c235 | |||
| 4dfabc001b | |||
| 2c959326a6 | |||
| 31ad97deca | |||
| 4da06b0930 | |||
| c184f20f76 | |||
| f20d3f0d88 | |||
| 1c846aa427 | |||
| b2245f8f34 | |||
| faa06b802a | |||
| 285db949a4 | |||
| eb0fbf236b | |||
| e3c8fb1313 | |||
| 2b38c750b1 | |||
| bd64e3170b | |||
| b0e4cecea4 | |||
| 906cd26032 | |||
| cbb5e9e181 | |||
| af94b0a118 | |||
| 61b73cede4 | |||
| d299e40f1e | |||
| 6845b647bb | |||
| ebb393c74e | |||
| 45f36649ab | |||
| 36f5cd1a38 | |||
| 7edf890373 | |||
| 0e8b3e4aa8 | |||
| ee1361dc0d | |||
| e751578e85 | |||
| 8b0f2648e2 | |||
| 434ef0f844 | |||
| c7ed3bcef3 | |||
| dbb559e655 | |||
| add60400f8 | |||
| 939f0881ab | |||
| d31ac9b884 | |||
| c860159ea8 | |||
| 743b5d5db8 | |||
| 134054fbae | |||
| 44d85c5241 | |||
| a71c8e7943 | |||
| ff54f29762 | |||
| 6db449cdab | |||
| c994e3376e | |||
| 98ae77bdd6 | |||
| 448df54521 | |||
| e29d5bc601 | |||
| d38ee44df4 | |||
| a359a21959 | |||
| 4d897b6f24 | |||
| b1818fd1b5 | |||
| 1075bd437d | |||
| 2b25d78d23 | |||
| 7a2e319df4 | |||
| 10196aa04a | |||
| 76cf998148 | |||
| dc89e82de6 | |||
| 78300a5ca3 | |||
| ed0efa8b3e | |||
| 578e65eeb4 | |||
| 677bee3bd4 | |||
| 9ba6ac6167 | |||
| dacc1edb63 | |||
| 6f498cfeb9 | |||
| acf2e99652 | |||
| 63a207a6a8 | |||
| 3384dbf998 | |||
| 452d678c0b | |||
| d21abd1f96 | |||
| 11eda2afb6 | |||
| d05cbcad63 | |||
| e40332300f | |||
| 50925540a9 | |||
| 5ced863bec | |||
| c2473247c1 | |||
| 198179e78a | |||
| 5015aa2cea | |||
| cb894d47f2 | |||
| 8293a8e162 | |||
| b39c2dd460 | |||
| 2de4710a29 | |||
| 8bec0c8954 | |||
| d37edc7ffa | |||
| 6bbd467e4d | |||
| 2ac91aaa59 | |||
| 9141b5762f | |||
| e7920ea134 | |||
| b0f9d9f074 | |||
| 30c5e76f34 | |||
| 3976df3d12 | |||
| e084eefad6 | |||
| 50a5dbb21d | |||
| f0dbc2bc12 | |||
| fdb56e4070 | |||
| 41b62a9305 | |||
| a46bdc27e1 | |||
| f9cf8c9fff | |||
| e7d3e273f2 | |||
| e5c2404c19 | |||
| 79cab9e10e | |||
| 7a2baf6865 | |||
| 377d27d0ff | |||
| bca8c4b6e5 | |||
| 38371d43e6 | |||
| 38374a03b0 | |||
| 8819bdc0ac | |||
| cd2f0e6e05 | |||
| e567d3c825 | |||
| 3316bae823 | |||
| 1b28f5e054 | |||
| 82ba7beda1 | |||
| 8136093d92 | |||
| d29693f1d9 | |||
| 3a31285ac6 | |||
| e2dfeef40a | |||
| c186321f60 | |||
| d52a4a314f | |||
| 040720a465 | |||
| dd9fa36afd | |||
| 2117217f62 | |||
| b02027a57c | |||
| f4981f1ad6 | |||
| a80c2fc05f | |||
| 17a77fba0e | |||
| 115dfd288a | |||
| f174e793e9 | |||
| 0ac1ac4e3d | |||
| c47bc83e41 | |||
| d17a261c0e | |||
| d3fd7174c7 | |||
| c9ac54c054 | |||
| 895d59124e | |||
| 27e7aace35 | |||
| 7f0557afd6 | |||
| 4201120ebd | |||
| 919cafa2c0 | |||
| e654c368a7 | |||
| 390de57ebf | |||
| b06f904b16 | |||
| 58eb81b27e | |||
| cf43ee61f5 | |||
| 170304e282 | |||
| e0d4e72342 | |||
| 8d64954d36 | |||
| ddeb64c71d | |||
| 03a7aae773 | |||
| f575864cdc | |||
| c4f1225b26 | |||
| 493dae7a2c | |||
| a6ab6dca21 | |||
| 3525da7f76 | |||
| 11f1b6b8e9 | |||
| 43fcebde32 | |||
| 83589d3ffb | |||
| 4657f11dbf | |||
| 9d84de7fe4 | |||
| e2b3564d10 | |||
| bd89e37865 | |||
| 6accd1f03a | |||
| 94e88298ea | |||
| fa884fbe50 | |||
| d9de7214d1 | |||
| 6be4218ea6 | |||
| 7746f7935e | |||
| 24fd0d4749 | |||
| 6559ec281c | |||
| e97efe5fd9 | |||
| 1e7eb181d2 | |||
| 8e23b38608 | |||
| 5768efbb9f | |||
| 1607e18655 | |||
| 411b1dd73d | |||
| d5f160df09 | |||
| d82bfa7639 | |||
| 8b7b499e0b | |||
| 341a7a0913 | |||
| f11258448a | |||
| 138c826b80 | |||
| 36503e7125 | |||
| e0fbc55dd6 | |||
| b252d1b6a7 | |||
| 1490968ef1 | |||
| af1879144e | |||
| ef94e12887 | |||
| 1f28ec0961 | |||
| 932d25ee87 | |||
| 68298d1871 | |||
| 5eeff70c00 | |||
| 1a7ffeae25 | |||
| af860986bd | |||
| 7703a4a738 | |||
| 1abb1e0a10 | |||
| 3940c9d065 | |||
| 628a4d0d84 | |||
| bb0ddd647e | |||
| 68ffddb065 | |||
| 93b0b74a65 | |||
| fd7f463c45 | |||
| f465af8de0 | |||
| e2845d936e | |||
| 68f40a267f | |||
| 65a5f83483 | |||
| 14c3dc1968 | |||
| 9e7587eae5 | |||
| dbdbf49b49 | |||
| 210775f691 | |||
| 9511387ffb | |||
| cd3ccb1f8b | |||
| c8ce9801a5 | |||
| fa520b399c | |||
| 1493c20caa | |||
| 74b73d6ae2 | |||
| 979ffdf355 | |||
| ad547539b7 | |||
| 81a65c335c | |||
| 78fe45c35a | |||
| 37b120d0b9 | |||
| 37ea6e0bf5 | |||
| d2db81bb16 | |||
| 6ee5ce4f6e | |||
| 7499d8de03 | |||
| 68033869bf | |||
| 553e907708 | |||
| 074cc20ce3 | |||
| fe2e63d8e8 | |||
| d84c67a3ec | |||
| 2ce78eb94a | |||
| b91aa03fe4 | |||
| 0d5774778c | |||
| cdbad092a4 | |||
| 2644caf717 | |||
| 5019acd822 | |||
| c4438bdce2 | |||
| 4203b524b8 | |||
| a22aa8fd4f | |||
| 65d18f9229 | |||
| 6338d1b811 | |||
| e28f3ce2ff | |||
| f4606d4d8d | |||
| fb49858f5a | |||
| 99adc0b2b1 | |||
| c942a7f2d2 | |||
| 0e2b857282 | |||
| e7545c97dc | |||
| 5deefdaa9d | |||
| 544d3c2fb7 | |||
| 582d97b964 | |||
| a3861c0ed1 | |||
| bae064d3b5 | |||
| 11725dfc5f | |||
| 87364a0983 | |||
| f0f5efe4f4 | |||
| e225ab37c5 | |||
| aa78e834c3 | |||
| ccc5f5a340 | |||
| 1c9b7844a2 | |||
| cb99b9d6c0 | |||
| 6a38fb4f2d | |||
| 7dda1ca2e7 | |||
| 539836d023 | |||
| 1869573927 | |||
| 678bb72c35 | |||
| abc537afe5 | |||
| cbbd860de8 | |||
| 2d68a9283f | |||
| db2c895065 | |||
| b0ad9ff416 | |||
| 40e7940be2 | |||
| 06e7be5ff3 | |||
| c8b33f8ecf | |||
| 0e8792c2f7 | |||
| 80a91d7b6b | |||
| 11537e99c6 | |||
| a4e4d58c85 | |||
| 8f312c4439 | |||
| e8a94147fe | |||
| 03ab264919 | |||
| 05507e4fcf | |||
| 1e3a357f47 | |||
| 17f688f533 | |||
| 38ad80e5e1 | |||
| d3dc94bd48 | |||
| 37a6668fb2 | |||
| 12e000d41a | |||
| 5718ce3bc4 | |||
| f302697380 | |||
| 104029df89 | |||
| 0833b40005 | |||
| dd60f06954 | |||
| 27b2611cbc | |||
| 33b26a4d3e | |||
| 2318028ec4 | |||
| 16c4fa7977 | |||
| 67169986e8 | |||
| f587b87116 | |||
| bcbe20fd99 | |||
| c32a119468 | |||
| 8cbee312b4 | |||
| 0b3359c72a | |||
| 65b92fbebf | |||
| 12d358d9af | |||
| 9435ef2fba | |||
| 9b92eae5f0 | |||
| 4522ec629b | |||
| 8a6dfd5ab4 | |||
| b39ff2f587 | |||
| d9136417cd | |||
| b7eb2c0eb6 | |||
| 0c07d4f5bb | |||
| 1c7979d7d7 | |||
| d18f80d6ba | |||
| 977e8fedda | |||
| 0b64e26b14 | |||
| 764c26c875 | |||
| ea7c79ff0e | |||
| d267504833 | |||
| d399f843a8 | |||
| a69e49803d | |||
| f6a316edbd | |||
| 13b38c4826 | |||
| 08b8930751 | |||
| 04a13f15e5 | |||
| 76d4faf38f | |||
| 145acad1f7 | |||
| 03c1683d18 | |||
| 03b2eb8066 | |||
| c39539ab82 | |||
| c94f9a14c1 | |||
| 52713e0f9e | |||
| fa03770588 | |||
| 783f50ff44 | |||
| 9ae0f93af1 | |||
| 975099e8db | |||
| 0144259494 | |||
| 5e861498b1 | |||
| 290dc26dba | |||
| c4f5535d47 | |||
| 1878107fa2 | |||
| 1035d3c13e | |||
| 2d528707cd | |||
| 2ed8cff100 | |||
| 87dd022604 | |||
| 72a6293f5e | |||
| 3b8786e63b | |||
| 248e051a94 | |||
| 26b23e8020 | |||
| 3711ce6d5b | |||
| dc77f26c4a | |||
| 579dbbae1b | |||
| b073f3ee73 | |||
| 184ca96330 | |||
| b6d23c7aba | |||
| 8151441171 | |||
| 1cb5c0e9de | |||
| 8de0976826 | |||
| 2fed8ee042 | |||
| 9b300a4f4f | |||
| 6f617aa649 | |||
| d20a57cf17 | |||
| 3d0e81a673 | |||
| 8924074b37 | |||
| c60e30f745 | |||
| 2cdf96e165 | |||
| 8b74996be2 | |||
| 2a3b36fc33 | |||
| bde33edc57 | |||
| baff0490a3 | |||
| 5065bf948f | |||
| 51c5704571 | |||
| f7a3863970 | |||
| d5f3d74072 | |||
| 8a3d7acf03 | |||
| 4f319fd5ab | |||
| 25066196e3 | |||
| 4beb4d2a2f | |||
| d9ea2d6e27 | |||
| 81ad8e29b6 | |||
| fb86b14b50 | |||
| fc661952b2 | |||
| c2584f705a | |||
| 9a276e404c | |||
| 6dde516acf | |||
| 5afd907492 | |||
| 17e771732e | |||
| ddeda12f56 | |||
| 011473b66e | |||
| 4eb22b3cba | |||
| b3789ee1e6 | |||
| e20241aaed | |||
| 4af6992e5e | |||
| a56745e73c | |||
| ead725522a | |||
| 3c4f1f6b67 | |||
| b52ecebc28 | |||
| deb5b7e9f0 | |||
| 97d68dc053 | |||
| a5d016d83e | |||
| c164107bf3 | |||
| fe490032c2 | |||
| 1be0da68da | |||
| d2412d2e0b | |||
| 7e6f951695 | |||
| e5d8b13406 | |||
| 5030bbad03 | |||
| 1909f03620 | |||
| ea9da2a7a6 | |||
| 9c854c6b7b | |||
| 1eb58b7ea1 | |||
| 1dc0e0fcc4 | |||
| 8fde623f8a | |||
| 59b166ed89 | |||
| ef35a91437 | |||
| 5f306a0d34 | |||
| c74981b0d4 | |||
| 5fd397e1ee | |||
| c76c3784aa | |||
| 3599c03929 | |||
| 49d6abde91 | |||
| 2d9e266963 | |||
| 9952037d79 | |||
| ae197690de | |||
| d342d4d9fe | |||
| 58bb9f67e2 | |||
| 0ad04c6f8e | |||
| 9b6bba40be | |||
| f156e9eb6e | |||
| 34d914fce3 | |||
| 371c74a6ae | |||
| 21a2715031 | |||
| 1aad050bab | |||
| b924fdfba5 | |||
| e9ad6b2fb9 | |||
| fbd15c7176 | |||
| 1c72e79a49 | |||
| a6934a6f2b | |||
| 804181b0d8 | |||
| 47a3422cc5 | |||
| 8c6d2905fe | |||
| df213b8437 | |||
| 59f54e8fd0 | |||
| 9c670268db | |||
| 76174c4d65 | |||
| 69dd10b2ae | |||
| c6cef1db1a | |||
| 9511002caa | |||
| 1fd1b1ee94 | |||
| fdcc5d6f9d | |||
| 3100379bcd | |||
| 9b70b8464a | |||
| aefbe96edd | |||
| c6bbcf3765 | |||
| 1b45149b53 | |||
| 140c76462d | |||
| b329defb0d | |||
| ba0db04a8f | |||
| 0b49a9b9ed | |||
| 47b3add6fc | |||
| c1a4a5044b | |||
| f1349a26bb | |||
| ce1f628732 | |||
| c338cba3ea | |||
| 7b046958fd | |||
| b7db2dd163 | |||
| c6d3383cb2 | |||
| f310ad9004 | |||
| e781346731 | |||
| 418e9f779e | |||
| c1026c7bd6 | |||
| 0262d08cd7 | |||
| ee806e7cb1 | |||
| 3ee03e4409 | |||
| acfea6f2ef | |||
| 52a5e4f718 | |||
| a38531234f | |||
| 21bf5f96bc | |||
| a88d09c6ab | |||
| 1d3134793a | |||
| 5ff0d819e7 | |||
| 2e226432af | |||
| 85d95733c2 | |||
| 94b78144ab | |||
| 18ec3f432f | |||
| 8b122de457 | |||
| 7f8147adc4 | |||
| ef338793a3 | |||
| 0c70674e07 | |||
| f7a0a0a951 | |||
| 98a20fb123 | |||
| 36d5eb8ec8 | |||
| b4603846d2 | |||
| 17e45d842c | |||
| fd7a2cb5bc | |||
| 59a0ba9bc4 | |||
| d1e6a6fd24 | |||
| 9458e2d6df | |||
| fe4aba8153 | |||
| 9c64caed1d | |||
| ea724f0841 | |||
| 65d2faf50c | |||
| f4eace5b91 | |||
| e24733c05a | |||
| 5032568e5b | |||
| 61cf431d1b | |||
| 0349ac0035 | |||
| fe133b5bc5 | |||
| ce8b182a6e | |||
| 839722d85b | |||
| 2ec89f253c | |||
| 0fdc9cc00a | |||
| f94b9bf6b3 | |||
| 7c77d75a81 | |||
| 94f219280b | |||
| ffc05a5041 | |||
| 0818c300e7 | |||
| fa42c3cd77 | |||
| 79f786664d | |||
| 47691b509c | |||
| 6af095a263 | |||
| bb6faa16a6 | |||
| 8f0424d057 | |||
| f0d53f9f79 | |||
| dba84db815 | |||
| af5a179182 | |||
| 343269000d | |||
| ac4c223422 | |||
| 280496cd6d | |||
| 9905824cc3 | |||
| 1eddc8bfed | |||
| 66e7ce1e03 | |||
| 9746343f95 | |||
| f3ffc37352 | |||
| 991352090a | |||
| 120c02aa09 | |||
| 4f4716f42d | |||
| 419d6ce391 | |||
| 732d118ea4 | |||
| 3dcdd86486 | |||
| 2e46f99d03 | |||
| b14bb6faec | |||
| 2ee8037261 | |||
| 2c3ece825f | |||
| 436c37fd98 | |||
| c4a3ec97ea | |||
| f83f87fe57 | |||
| 3ca6bc04ce | |||
| 2b2a89cf47 | |||
| 02099e2dd3 | |||
| 7ecb5e309a | |||
| 6e1b8d8b2d | |||
| 18bc5496fa | |||
| b04d764a22 | |||
| a2e42f79d2 | |||
| 12883afcdf | |||
| de812122a6 | |||
| 28d522427a | |||
| e277d032ef | |||
| d5c73abd52 | |||
| 049c832f33 | |||
| fb9823b9ec | |||
| 6725d2888d | |||
| 8aa8acf64e | |||
| 1605036c40 | |||
| a7175d4d35 | |||
| 370c659ddc | |||
| c2f183b357 | |||
| 80508e60c7 | |||
| ec9c46b309 | |||
| 0db9ae6f52 | |||
| 41a8b15dc2 | |||
| eb558e2442 | |||
| 9dd42da09e | |||
| 5d949f9e5b | |||
| 0bfee99fa4 | |||
| cbe453b9c9 | |||
| 83e6a37fb6 | |||
| 9713a00e3c | |||
| 6f0674ef19 | |||
| fb4e0c4066 | |||
| 5db5305f5e | |||
| 6d512380a4 | |||
| 937f848340 | |||
| c5bab50caf | |||
| d6589e0ce3 | |||
| 6214d89445 | |||
| d2c9a40139 | |||
| ff6aa6e3b4 | |||
| 9fd3fea70d | |||
| 393816b750 | |||
| e955fd5d0f | |||
| 7f48e95d65 | |||
| a5c84d959f | |||
| 5fe92f22b6 | |||
| 2c46bee938 | |||
| 323331be2a | |||
| 82ce01ad00 | |||
| 22a0e39486 | |||
| 0538117f10 | |||
| 4ac8d9785b | |||
| 9e490b7f2d | |||
| 969a3db923 | |||
| a71ba8d63b | |||
| 1add12a4bd | |||
| aa7d13a5bf | |||
| 7fde0426df | |||
| 72a12351f2 | |||
| bed23cd47e | |||
| 0241569e92 | |||
| e5278754ae | |||
| 0c988b2dcb | |||
| 73aec8eb5c | |||
| 678f09c736 | |||
| 6453dc58c0 | |||
| 6cb679e9ec | |||
| 47df9fdab0 | |||
| 4119fcd608 | |||
| ed08bbfbb6 | |||
| 108149fa2f | |||
| 30c6e773e2 | |||
| 9f3f3cfcd8 | |||
| 17df75df36 | |||
| 965aa51daf | |||
| 4079e58822 | |||
| 8dbf6671db | |||
| 1ecc9948aa | |||
| c854d9e027 | |||
| 81a1865fd5 | |||
| 2aad79cd3d | |||
| ce2509a5ea | |||
| 4aa5723cfc | |||
| 668e47312f | |||
| eab8f5361c | |||
| 88275ce3fe | |||
| 2b822af36a | |||
| bbf394c010 | |||
| b4c10cf1eb | |||
| dfaf833582 | |||
| 029c885a1b | |||
| c9ca131355 | |||
| d2e3851109 | |||
| 21f41f2d18 | |||
| a5f6961507 | |||
| a2f0abd847 | |||
| 5baf9fb48a | |||
| bb5aa9589d | |||
| 0783316117 | |||
| 021dc964b3 | |||
| 26338b84cc | |||
| 31270a1b19 | |||
| 7d84f93f06 | |||
| d2bf43be4d | |||
| e3d9f76bff | |||
| 5d0031cbdd | |||
| 5401a7ae75 | |||
| a68cd7345f | |||
| f7943d8048 | |||
| f8d72bb3b3 | |||
| 0bfff0bc5c | |||
| 6c935b6f90 | |||
| adbf10dbfe | |||
| 8f913ba982 | |||
| 90c9da9c86 | |||
| 453736593b | |||
| 1a1cc25f15 | |||
| 4f774e3175 | |||
| cfc66c0f85 | |||
| dc413834ea | |||
| edd432194f | |||
| 8cadfc4ffd | |||
| bfa3449b05 | |||
| b9ec368cfc | |||
| 66cb8f917d | |||
| 41fc5cb78e | |||
| eea1c895ac | |||
| f03e3aca62 | |||
| 1c42751367 | |||
| c8acfdd5fb | |||
| 4bef3eec56 | |||
| d9bdc192a7 | |||
| 12b9296906 | |||
| 72d48798b0 | |||
| b4f485a6b0 | |||
| c50b15e440 | |||
| f9bacb20ae | |||
| bc9a3a215e | |||
| 9f72dcd127 | |||
| f6d44d37ac | |||
| 0565b3bca4 | |||
| fea85c8611 | |||
| c8c2227d8c | |||
| a11be7c52d | |||
| 9edbda7e81 | |||
| de3843cc72 | |||
| c3af732d1a | |||
| fd721b8e95 | |||
| cc783cebd4 | |||
| 063edc95c7 | |||
| a7fdd13090 | |||
| 4750af556d | |||
| 09755e69af | |||
| b0f761598a | |||
| e7a3482b6a | |||
| 05cae37d56 | |||
| 0d2a4c7d1b | |||
| 8a5f21633d | |||
| a8adf49a78 | |||
| 2e75edcfdc | |||
| 1e64fb0a48 | |||
| d341b96fb3 | |||
| 6da498d196 | |||
| 7ffeac6a58 | |||
| 50d19e7d30 | |||
| aea393a0d0 | |||
| 87852360b3 | |||
| 87707ab956 | |||
| d7f2720616 | |||
| bf2cfd8dc3 | |||
| 04cece56ae | |||
| e9dcfe9952 | |||
| a67181d429 | |||
| 5ee23f2c7c | |||
| b8a717edf1 | |||
| fcfcc73a00 | |||
| 469b890e6c | |||
| 81b8394561 | |||
| 194fe99532 | |||
| 55d9b9d1ab | |||
| 02721989d8 | |||
| 3c1216c7ce | |||
| 6a3c783af6 | |||
| 645a98218b | |||
| ba7aced52b | |||
| 4c9d2d7841 | |||
| 2fd1799846 | |||
| d90858eacd | |||
| 927b5af65f | |||
| 3105d524e3 | |||
| ca046d9b1f | |||
| b8be2e723c | |||
| dba902447c | |||
| ea0c1bb04b | |||
| 31dcd91c9f | |||
| 9442bf8bbd | |||
| 80391efa7e | |||
| 50b14656e2 | |||
| 7a461e5f13 | |||
| 9ae3e5c8c9 | |||
| c9916c8713 | |||
| 5a6c4244c4 | |||
| 3d7aaefe21 | |||
| 88e88a4c83 | |||
| 6abcc1c457 | |||
| b222a13525 | |||
| 4f0fa3b008 | |||
| a8ebc3c3f6 | |||
| 3a13282d77 | |||
| 32438c4dc6 | |||
| 9ad6f7a17f | |||
| b07e515787 | |||
| d53aef4047 | |||
| 4538d24527 | |||
| 502742296d | |||
| 02afb71016 | |||
| 6adc893ffa | |||
| c6f0215796 | |||
| 24eba8b613 | |||
| d419e162ad | |||
| a198e2de6f | |||
| 4021005745 | |||
| 290a652991 | |||
| cd61594559 | |||
| 414584ba0c | |||
| 5927f96029 | |||
| e4041be591 | |||
| 81be1fe0f6 | |||
| 119233c47b | |||
| d0544c2f64 | |||
| 9579f11882 | |||
| 05a1c75567 | |||
| fddac2d84d | |||
| 4871b02de8 | |||
| b7e69634b1 | |||
| 62e83f84a0 | |||
| 7cde096625 | |||
| 15b5e44680 | |||
| 669322a78c | |||
| 4c5130519c | |||
| 352e776eed | |||
| bb2f640858 | |||
| 8b0ea3ef42 | |||
| b2bc2fe7c2 | |||
| 885d5faf51 | |||
| 9d56683e8b | |||
| 7afd404212 | |||
| 014e124b48 | |||
| c565179b1c | |||
| 10162f7776 | |||
| 46af548df0 | |||
| 09cf80c310 | |||
| e705244732 | |||
| 1df5ca8f51 | |||
| d0bf292379 | |||
| 3f5dfb6b9a | |||
| b5bc2f0817 | |||
| 4cff5d40c7 | |||
| bfb10f4d5e | |||
| 035907a06d | |||
| 04c41cb89f | |||
| 4dcbe54fb6 | |||
| c38ea8fdd8 | |||
| 136cc5ee0e | |||
| c78dbec7ae | |||
| 64b95a5255 | |||
| 538a43689a | |||
| 0418941fb3 | |||
| b1ed2166e7 | |||
| c2df21af41 | |||
| 552566fcfa | |||
| 3773ed06a1 | |||
| 2627976c95 | |||
| eb02d49740 | |||
| c966085b81 | |||
| ec5b641a38 | |||
| 2b18c86f24 | |||
| 57ade89fb0 | |||
| 11b5df1932 | |||
| 12bc83471f | |||
| b9c6c57377 | |||
| 045265b044 | |||
| 2ce5be4377 | |||
| 745b68888d | |||
| 45793339dd | |||
| f9025a7c4a | |||
| a3c287b6d0 | |||
| fb40272991 | |||
| 7388103e17 | |||
| a34b9fc015 | |||
| e74dda6472 | |||
| 10d808362d | |||
| 95f897b7f8 | |||
| f4dee4c08b | |||
| be14fc367d | |||
| ae80ffb29f | |||
| d65300986f | |||
| 1fbbac1888 | |||
| 91e45afd0d | |||
| f7e5f7cae0 | |||
| 84c530bffb | |||
| 58c9ddd24e | |||
| 56fa6f6211 | |||
| cf19c5d74b | |||
| 02b50e1a33 | |||
| 74b2a80ef2 | |||
| f2464dcc5f | |||
| 31c5e7bce2 | |||
| 2edc0b8e59 | |||
| 0b32f897b2 | |||
| b9576494e9 | |||
| 3e9a73f7c2 | |||
| 5fcc8b2961 | |||
| 07c5dbcbca | |||
| 172de26c54 | |||
| 6b8f15bd22 | |||
| ce4d342369 | |||
| 1e77a684c2 | |||
| 8bd82abd9f | |||
| 16793b7e7f | |||
| 9ac0ee9665 | |||
| a65f9ac6f4 | |||
| 70096affc5 | |||
| 99e46a58b4 | |||
| a81e470720 | |||
| 7d5cd32070 | |||
| 60935ce8cc | |||
| 235509450a | |||
| 5829a5d958 | |||
| 21b1e83147 | |||
| bb9f8ebd77 | |||
| f5aaf40e88 | |||
| 31777fa6b5 | |||
| d8aa7224dd | |||
| 3e7055c27f | |||
| 0d3e8f4a71 | |||
| 5ecbc682e1 | |||
| 48bd9a6a44 | |||
| 2300a73210 | |||
| a3986feedd | |||
| 77f868eb13 | |||
| 5b3eedc8c2 | |||
| a381d88fe2 | |||
| 3188c43241 | |||
| dc86d66648 | |||
| 69ee6318a5 | |||
| eeb8c0b45e | |||
| ecd25dfefb | |||
| e1acd19b60 | |||
| 7359ee72d3 | |||
| bc023f265c | |||
| 65de0bda77 | |||
| c0bb986cd6 | |||
| 05e03289a9 | |||
| b709953493 | |||
| a799505a5e | |||
| 363545ef96 | |||
| a0d509156d | |||
| 57f12c3660 | |||
| 0f455192c1 | |||
| 6e1ce26bf2 | |||
| 736139e3e7 | |||
| ce2e5f8796 | |||
| fd116f4187 | |||
| 99c69c1bcc | |||
| 29520dbf08 | |||
| 5b127f0761 | |||
| f65f808fb2 | |||
| 12dd36ef3d | |||
| f523dad040 | |||
| bfcea97d39 | |||
| 507dc0aa20 | |||
| d7d113abb7 | |||
| c111b4ac62 | |||
| 7f0610d9c2 | |||
| 0b69091aff | |||
| 99aa654d8b | |||
| 90cc7f10d4 | |||
| e260cf84c5 | |||
| ca55b23e89 | |||
| f213353b30 | |||
| dc75539de0 | |||
| f315f45435 | |||
| abef338c9d | |||
| 14d97e0177 | |||
| eab220050a | |||
| 83879e9f7d | |||
| e4ac283321 | |||
| ba1020e7cf | |||
| afc46b4134 | |||
| 968512ada1 | |||
| 5eadf77b14 |
@@ -11,7 +11,7 @@
|
||||
For overall help on editing and submitting pull requests, visit:
|
||||
https://kubernetes.io/docs/contribute/start/#improve-existing-content
|
||||
|
||||
Use the default base branch, “master”, if you're documenting existing
|
||||
Use the default base branch, “main”, if you're documenting existing
|
||||
features in the English localization.
|
||||
|
||||
If you're working on a different localization (not English), see
|
||||
|
||||
@@ -33,4 +33,8 @@ resources/
|
||||
# Netlify Functions build output
|
||||
package-lock.json
|
||||
functions/
|
||||
node_modules/
|
||||
node_modules/
|
||||
|
||||
# Generated files when building with make container-build
|
||||
.config/
|
||||
.npm/
|
||||
|
||||
@@ -6,8 +6,9 @@ NETLIFY_FUNC = $(NODE_BIN)/netlify-lambda
|
||||
# but this can be overridden when calling make, e.g.
|
||||
# CONTAINER_ENGINE=podman make container-image
|
||||
CONTAINER_ENGINE ?= docker
|
||||
IMAGE_REGISTRY ?= gcr.io/k8s-staging-sig-docs
|
||||
IMAGE_VERSION=$(shell scripts/hash-files.sh Dockerfile Makefile | cut -c 1-12)
|
||||
CONTAINER_IMAGE = kubernetes-hugo:v$(HUGO_VERSION)-$(IMAGE_VERSION)
|
||||
CONTAINER_IMAGE = $(IMAGE_REGISTRY)/k8s-website-hugo:v$(HUGO_VERSION)-$(IMAGE_VERSION)
|
||||
CONTAINER_RUN = $(CONTAINER_ENGINE) run --rm --interactive --tty --volume $(CURDIR):/src
|
||||
|
||||
CCRED=\033[0;31m
|
||||
@@ -19,7 +20,11 @@ help: ## Show this help.
|
||||
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {sub("\\\\n",sprintf("\n%22c"," "), $$2);printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
|
||||
|
||||
module-check:
|
||||
@git submodule status --recursive | awk '/^[+-]/ {printf "\033[31mWARNING\033[0m Submodule not initialized: \033[34m%s\033[0m\n",$$2}' 1>&2
|
||||
@git submodule status --recursive | awk '/^[+-]/ {err = 1; printf "\033[31mWARNING\033[0m Submodule not initialized: \033[34m%s\033[0m\n",$$2} END { if (err != 0) print "You need to run \033[32mmake module-init\033[0m to initialize missing modules first"; exit err }' 1>&2
|
||||
|
||||
module-init:
|
||||
@echo "Initializing submodules..." 1>&2
|
||||
@git submodule update --init --recursive --depth 1
|
||||
|
||||
all: build ## Build site with production settings and put deliverables in ./public
|
||||
|
||||
@@ -68,7 +73,7 @@ container-build: module-check
|
||||
$(CONTAINER_RUN) --read-only --mount type=tmpfs,destination=/tmp,tmpfs-mode=01777 $(CONTAINER_IMAGE) sh -c "npm ci && hugo --minify"
|
||||
|
||||
container-serve: module-check ## Boot the development server using container. Run `make container-image` before this.
|
||||
$(CONTAINER_RUN) --read-only --mount type=tmpfs,destination=/tmp,tmpfs-mode=01777 -p 1313:1313 $(CONTAINER_IMAGE) hugo server --buildFuture --bind 0.0.0.0 --destination /tmp/hugo --cleanDestinationDir
|
||||
$(CONTAINER_RUN) --cap-drop=ALL --cap-add=AUDIT_WRITE --read-only --mount type=tmpfs,destination=/tmp,tmpfs-mode=01777 -p 1313:1313 $(CONTAINER_IMAGE) hugo server --buildFuture --bind 0.0.0.0 --destination /tmp/hugo --cleanDestinationDir
|
||||
|
||||
test-examples:
|
||||
scripts/test_examples.sh install
|
||||
@@ -91,4 +96,4 @@ clean-api-reference: ## Clean all directories in API reference directory, preser
|
||||
|
||||
api-reference: clean-api-reference ## Build the API reference pages. go needed
|
||||
cd api-ref-generator/gen-resourcesdocs && \
|
||||
go run cmd/main.go kwebsite --config-dir config/v1.20/ --file api/v1.20/swagger.json --output-dir ../../content/en/docs/reference/kubernetes-api --templates templates
|
||||
go run cmd/main.go kwebsite --config-dir config/v1.21/ --file api/v1.21/swagger.json --output-dir ../../content/en/docs/reference/kubernetes-api --templates templates
|
||||
|
||||
@@ -11,7 +11,7 @@ emeritus_approvers:
|
||||
# - jaredbhatti, commented out to disable PR assignments
|
||||
# - steveperry-53, commented out to disable PR assignments
|
||||
- stewart-yu
|
||||
- zacharysarah
|
||||
# - zacharysarah, commented out to disable PR assignments
|
||||
|
||||
labels:
|
||||
- sig/docs
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
aliases:
|
||||
sig-docs-blog-owners: # Approvers for blog content
|
||||
- castrojo
|
||||
- kbarnard10
|
||||
- onlydole
|
||||
- zacharysarah
|
||||
- mrbobbytables
|
||||
sig-docs-blog-reviewers: # Reviewers for blog content
|
||||
- castrojo
|
||||
- kbarnard10
|
||||
- mrbobbytables
|
||||
- onlydole
|
||||
@@ -28,13 +25,11 @@ aliases:
|
||||
- kbarnard10
|
||||
- kbhawkey
|
||||
- onlydole
|
||||
- pi-victor
|
||||
- reylejano
|
||||
- savitharaghunathan
|
||||
- sftim
|
||||
- steveperry-53
|
||||
- tengqm
|
||||
- zacharysarah
|
||||
- zparnold
|
||||
sig-docs-en-reviews: # PR reviews for English content
|
||||
- bradtopol
|
||||
- celestehorgan
|
||||
@@ -45,16 +40,12 @@ aliases:
|
||||
- onlydole
|
||||
- rajeshdeshpande02
|
||||
- sftim
|
||||
- steveperry-53
|
||||
- tengqm
|
||||
- zparnold
|
||||
sig-docs-es-owners: # Admins for Spanish content
|
||||
- raelga
|
||||
- alexbrand
|
||||
- electrocucaracha
|
||||
sig-docs-es-reviews: # PR reviews for Spanish content
|
||||
- raelga
|
||||
- alexbrand
|
||||
# glo-pena
|
||||
- electrocucaracha
|
||||
sig-docs-fr-owners: # Admins for French content
|
||||
- remyleone
|
||||
@@ -141,10 +132,11 @@ aliases:
|
||||
- ClaudiaJKang
|
||||
- gochist
|
||||
- ianychoi
|
||||
- seokho-son
|
||||
- ysyukr
|
||||
- jihoon-seo
|
||||
- pjhwa
|
||||
- seokho-son
|
||||
- yoonian
|
||||
- ysyukr
|
||||
sig-docs-leads: # Website chairs and tech leads
|
||||
- irvifa
|
||||
- jimangel
|
||||
@@ -166,8 +158,10 @@ aliases:
|
||||
# zhangxiaoyu-zidif
|
||||
sig-docs-zh-reviews: # PR reviews for Chinese content
|
||||
- chenrui333
|
||||
- chenxuc
|
||||
- howieyuen
|
||||
- idealhack
|
||||
- mengjiao-liu
|
||||
- pigletfly
|
||||
- SataQiu
|
||||
- tanjunchen
|
||||
@@ -236,3 +230,30 @@ aliases:
|
||||
- mrbobbytables
|
||||
- nikhita
|
||||
- parispittman
|
||||
# authoritative source: https://git.k8s.io/sig-release/OWNERS_ALIASES
|
||||
sig-release-leads:
|
||||
- cpanato # SIG Technical Lead
|
||||
- hasheddan # SIG Technical Lead
|
||||
- jeremyrickard # SIG Technical Lead
|
||||
- justaugustus # SIG Chair
|
||||
- LappleApple # SIG Program Manager
|
||||
- puerco # SIG Technical Lead
|
||||
- saschagrunert # SIG Chair
|
||||
release-engineering-approvers:
|
||||
- cpanato # Release Manager
|
||||
- hasheddan # subproject owner / Release Manager
|
||||
- puerco # Release Manager
|
||||
- saschagrunert # subproject owner / Release Manager
|
||||
- justaugustus # subproject owner / Release Manager
|
||||
- xmudrii # Release Manager
|
||||
release-engineering-reviewers:
|
||||
- ameukam # Release Manager Associate
|
||||
- jimangel # Release Manager Associate
|
||||
- markyjackson-taulia # Release Manager Associate
|
||||
- mkorbi # Release Manager Associate
|
||||
- palnabarun # Release Manager Associate
|
||||
- onlydole # Release Manager Associate
|
||||
- sethmccombs # Release Manager Associate
|
||||
- thejoycekung # Release Manager Associate
|
||||
- verolop # Release Manager Associate
|
||||
- wilsonehusin # Release Manager Associate
|
||||
@@ -9,7 +9,7 @@ Herzlich willkommen! Dieses Repository enthält alle Assets, die zur Erstellung
|
||||
|
||||
Sie können auf die Schaltfläche **Fork** im oberen rechten Bereich des Bildschirms klicken, um eine Kopie dieses Repositorys in Ihrem GitHub-Konto zu erstellen. Diese Kopie wird als *Fork* bezeichnet. Nehmen Sie die gewünschten Änderungen an Ihrem Fork vor. Wenn Sie bereit sind, diese Änderungen an uns zu senden, gehen Sie zu Ihrem Fork und erstellen Sie eine neue Pull-Anforderung, um uns darüber zu informieren.
|
||||
|
||||
Sobald Ihre Pull-Anfrage erstellt wurde, übernimmt ein Rezensent von Kubernetes die Verantwortung für klares, umsetzbares Feedback. Als Eigentümer des Pull-Request **liegt es in Ihrer Verantwortung Ihren Pull-Reqest enstsprechend des Feedbacks, dass Sie vom Kubernetes-Reviewer erhalten haben abzuändern.** Beachten Sie auch, dass Sie am Ende mehr als einen Rezensenten von Kubernetes erhalten, der Ihnen Feedback gibt, oder dass Sie Rückmeldungen von einem Rezensenten von Kubernetes erhalten, der sich von demjenigen unterscheidet, der ursprünglich für das Feedback zugewiesen wurde. In einigen Fällen kann es vorkommen, dass einer Ihrer Prüfer bei Bedarf eine technische Überprüfung von einem [Kubernetes Tech-Reviewer](https://github.com/kubernetes/website/wiki/tech-reviewers) anfordert. Reviewer geben ihr Bestes, um zeitnah Feedback zu geben, die Antwortzeiten können jedoch je nach den Umständen variieren.
|
||||
Sobald Ihre Pull-Anfrage erstellt wurde, übernimmt ein Rezensent von Kubernetes die Verantwortung für klares, umsetzbares Feedback. Als Eigentümer des Pull-Request **liegt es in Ihrer Verantwortung Ihren Pull-Reqest entsprechend des Feedbacks, dass Sie vom Kubernetes-Reviewer erhalten haben abzuändern.** Beachten Sie auch, dass Sie am Ende mehr als einen Rezensenten von Kubernetes erhalten, der Ihnen Feedback gibt, oder dass Sie Rückmeldungen von einem Rezensenten von Kubernetes erhalten, der sich von demjenigen unterscheidet, der ursprünglich für das Feedback zugewiesen wurde. In einigen Fällen kann es vorkommen, dass einer Ihrer Prüfer bei Bedarf eine technische Überprüfung von einem [Kubernetes Tech-Reviewer](https://github.com/kubernetes/website/wiki/tech-reviewers) anfordert. Reviewer geben ihr Bestes, um zeitnah Feedback zu geben, die Antwortzeiten können jedoch je nach den Umständen variieren.
|
||||
|
||||
Weitere Informationen zum Beitrag zur Kubernetes-Dokumentation finden Sie unter:
|
||||
|
||||
@@ -37,6 +37,13 @@ Um die Kubernetes-Website lokal laufen zu lassen, empfiehlt es sich, ein speziel
|
||||
|
||||
> Wenn Sie die Website lieber lokal ohne Docker ausführen möchten, finden Sie weitere Informationen unter [Website lokal mit Hugo ausführen](#Die-Site-lokal-mit-Hugo-ausführen).
|
||||
|
||||
Das benötigte [Docsy Hugo theme](https://github.com/google/docsy#readme) muss als git submodule installiert werden:
|
||||
|
||||
```
|
||||
#Füge das Docsy submodule hinzu
|
||||
git submodule update --init --recursive --depth 1
|
||||
```
|
||||
|
||||
Wenn Sie Docker [installiert](https://www.docker.com/get-started) haben, erstellen Sie das Docker-Image `kubernetes-hugo` lokal:
|
||||
|
||||
```bash
|
||||
@@ -55,9 +62,18 @@ make container-serve
|
||||
|
||||
Hugo-Installationsanweisungen finden Sie in der [offiziellen Hugo-Dokumentation](https://gohugo.io/getting-started/installing/). Stellen Sie sicher, dass Sie die Hugo-Version installieren, die in der Umgebungsvariablen `HUGO_VERSION` in der Datei [`netlify.toml`](netlify.toml#L9) angegeben ist.
|
||||
|
||||
Das benötigte [Docsy Hugo theme](https://github.com/google/docsy#readme) muss als git submodule installiert werden:
|
||||
|
||||
```
|
||||
#Füge das Docsy submodule hinzu
|
||||
git submodule update --init --recursive --depth 1
|
||||
```
|
||||
|
||||
So führen Sie die Site lokal aus, wenn Sie Hugo installiert haben:
|
||||
|
||||
```bash
|
||||
# Installieren der JavaScript Abhängigkeiten
|
||||
npm ci
|
||||
make serve
|
||||
```
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Kubernetesのドキュメント
|
||||
|
||||
[](https://app.netlify.com/sites/kubernetes-io-master-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
[](https://app.netlify.com/sites/kubernetes-io-main-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
|
||||
このリポジトリには、[KubernetesのWebサイトとドキュメント](https://kubernetes.io/)をビルドするために必要な全アセットが格納されています。貢献に興味を持っていただきありがとうございます!
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# 쿠버네티스 문서화
|
||||
|
||||
[](https://app.netlify.com/sites/kubernetes-io-master-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
[](https://app.netlify.com/sites/kubernetes-io-main-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
|
||||
이 저장소에는 [쿠버네티스 웹사이트 및 문서](https://kubernetes.io/)를 빌드하는 데 필요한 자산이 포함되어 있습니다. 기여해주셔서 감사합니다!
|
||||
|
||||
|
||||
@@ -1,60 +1,45 @@
|
||||
# Dokumentacja projektu Kubernetes
|
||||
|
||||
[](https://travis-ci.org/kubernetes/website)
|
||||
[](https://github.com/kubernetes/website/releases/latest)
|
||||
|
||||
Witamy!
|
||||
[](https://app.netlify.com/sites/kubernetes-io-main-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
|
||||
W tym repozytorium znajdziesz wszystko, czego potrzebujesz do zbudowania [strony internetowej Kubernetesa wraz z dokumentacją](https://kubernetes.io/). Bardzo nam miło, że chcesz wziąć udział w jej współtworzeniu!
|
||||
|
||||
## Twój wkład w dokumentację
|
||||
+ [Twój wkład w dokumentację](#twój-wkład-w-dokumentację)
|
||||
+ [Informacje o wersjach językowych](#informacje-o-wersjach-językowych)
|
||||
|
||||
Możesz kliknąć w przycisk **Fork** w prawym górnym rogu ekranu, aby stworzyć kopię tego repozytorium na swoim koncie GitHub. Taki rodzaj kopii (odgałęzienia) nazywa się *fork*. Zmieniaj w nim, co chcesz, a kiedy będziesz już gotowy/a przesłać te zmiany do nas, przejdź do swojej kopii i stwórz nowy *pull request*, abyśmy zostali o tym poinformowani.
|
||||
# Jak używać tego repozytorium
|
||||
|
||||
Po stworzeniu *pull request*, jeden z recenzentów projektu Kubernetes podejmie się przekazania jasnych wskazówek pozwalających podjąć następne działania. Na Tobie, jako właścicielu *pull requesta*, **spoczywa odpowiedzialność za wprowadzenie poprawek zgodnie z uwagami recenzenta.** Może też się zdarzyć, że swoje uwagi zgłosi więcej niż jeden recenzent, lub że recenzję będzie robił ktoś inny, niż ten, kto został przydzielony na początku. W niektórych przypadkach, jeśli zajdzie taka potrzeba, recenzent może poprosić dodatkowo o recenzję jednego z [recenzentów technicznych](https://github.com/kubernetes/website/wiki/Tech-reviewers). Recenzenci zrobią wszystko, aby odpowiedzieć sprawnie, ale konkretny czas odpowiedzi zależy od wielu czynników.
|
||||
Możesz uruchomić serwis lokalnie poprzez Hugo (Extended version) lub ze środowiska kontenerowego. Zdecydowanie zalecamy korzystanie z kontenerów, bo dzięki temu lokalna wersja będzie spójna z tym, co jest na oficjalnej stronie.
|
||||
|
||||
Więcej informacji na temat współpracy przy tworzeniu dokumentacji znajdziesz na stronach:
|
||||
## Wymagania wstępne
|
||||
|
||||
* [Jak rozpocząć współpracę](https://kubernetes.io/docs/contribute/start/)
|
||||
* [Podgląd wprowadzanych zmian w dokumentacji](http://kubernetes.io/docs/contribute/intermediate#view-your-changes-locally)
|
||||
* [Szablony stron](https://kubernetes.io/docs/contribute/style/page-content-types/)
|
||||
* [Styl pisania dokumentacji](http://kubernetes.io/docs/contribute/style/style-guide/)
|
||||
* [Lokalizacja dokumentacji Kubernetes](https://kubernetes.io/docs/contribute/localization/)
|
||||
Aby móc skorzystać z tego repozytorium, musisz lokalnie zainstalować:
|
||||
|
||||
## Różne wersje językowe `README.md`
|
||||
- [npm](https://www.npmjs.com/)
|
||||
- [Go](https://golang.org/)
|
||||
- [Hugo (Extended version)](https://gohugo.io/)
|
||||
- Środowisko obsługi kontenerów, np. [Docker-a](https://www.docker.com/).
|
||||
|
||||
| | |
|
||||
|----------------------------------------|----------------------------------------|
|
||||
| [README po angielsku](README.md) | [README po francusku](README-fr.md) |
|
||||
| [README po koreańsku](README-ko.md) | [README po niemiecku](README-de.md) |
|
||||
| [README po portugalsku](README-pt.md) | [README w hindi](README-hi.md) |
|
||||
| [README po hiszpańsku](README-es.md) | [README po indonezyjsku](README-id.md) |
|
||||
| [README po chińsku](README-zh.md) | [README po japońsku](README-ja.md) |
|
||||
| [README po wietnamsku](README-vi.md) | [README po rosyjsku](README-ru.md) |
|
||||
| [README po włosku](README-it.md) | [README po ukraińsku](README-uk.md) |
|
||||
| | |
|
||||
Przed rozpoczęciem zainstaluj niezbędne zależności. Sklonuj repozytorium i przejdź do odpowiedniego katalogu:
|
||||
|
||||
## Jak uruchomić lokalną kopię strony przy pomocy Dockera?
|
||||
|
||||
Zalecaną metodą uruchomienia serwisu internetowego Kubernetesa lokalnie jest użycie specjalnego obrazu [Dockera](https://docker.com), który zawiera generator stron statycznych [Hugo](https://gohugo.io).
|
||||
|
||||
> Użytkownicy Windows będą potrzebowali dodatkowych narzędzi, które mogą zainstalować przy pomocy [Chocolatey](https://chocolatey.org).
|
||||
|
||||
```bash
|
||||
choco install make
|
||||
```
|
||||
git clone https://github.com/kubernetes/website.git
|
||||
cd website
|
||||
```
|
||||
|
||||
> Jeśli wolisz uruchomić serwis lokalnie bez Dockera, przeczytaj [jak uruchomić serwis lokalnie przy pomocy Hugo](#jak-uruchomić-lokalną-kopię-strony-przy-pomocy-hugo) poniżej.
|
||||
Strona Kubernetesa używa [Docsy Hugo theme](https://github.com/google/docsy#readme). Nawet jeśli planujesz uruchomić serwis w środowisku kontenerowym, zalecamy pobranie podmodułów i innych zależności za pomocą polecenia:
|
||||
|
||||
Jeśli [zainstalowałeś i uruchomiłeś](https://www.docker.com/get-started) już Dockera, zbuduj obraz `kubernetes-hugo` lokalnie:
|
||||
```
|
||||
# pull in the Docsy submodule
|
||||
git submodule update --init --recursive --depth 1
|
||||
```
|
||||
|
||||
```bash
|
||||
## Uruchomienie serwisu w kontenerze
|
||||
|
||||
Aby zbudować i uruchomić serwis wewnątrz środowiska kontenerowego, wykonaj następujące polecenia:
|
||||
|
||||
```
|
||||
make container-image
|
||||
```
|
||||
|
||||
Po zbudowaniu obrazu, możesz uruchomić serwis lokalnie:
|
||||
|
||||
```bash
|
||||
make container-serve
|
||||
```
|
||||
|
||||
@@ -62,29 +47,106 @@ Aby obejrzeć zawartość serwisu otwórz w przeglądarce adres http://localhost
|
||||
|
||||
## Jak uruchomić lokalną kopię strony przy pomocy Hugo?
|
||||
|
||||
Zajrzyj do [oficjalnej dokumentacji Hugo](https://gohugo.io/getting-started/installing/) po instrukcję instalacji. Upewnij się, że instalujesz rozszerzoną wersję Hugo, określoną przez zmienną środowiskową `HUGO_VERSION` w pliku [`netlify.toml`](netlify.toml#L9).
|
||||
Upewnij się, że zainstalowałeś odpowiednią wersję Hugo "extended", określoną przez zmienną środowiskową `HUGO_VERSION` w pliku [`netlify.toml`](netlify.toml#L10).
|
||||
|
||||
Aby uruchomić serwis lokalnie po instalacji Hugo, napisz:
|
||||
Aby uruchomić i przetestować serwis lokalnie, wykonaj:
|
||||
|
||||
```bash
|
||||
# install dependencies
|
||||
npm ci
|
||||
make serve
|
||||
```
|
||||
|
||||
Zostanie uruchomiony lokalny serwer Hugo na porcie 1313. Otwórz w przeglądarce adres http://localhost:1313, aby obejrzeć zawartość serwisu. Po każdej zmianie plików źródłowych, Hugo automatycznie aktualizuje stronę i odświeża jej widok w przeglądarce.
|
||||
|
||||
## Społeczność, listy dyskusyjne, uczestnictwo i wsparcie
|
||||
## Budowanie dokumentacji źródłowej API
|
||||
|
||||
Zajrzyj na stronę [społeczności](http://kubernetes.io/community/), aby dowiedzieć się, jak możesz zaangażować się w jej działania.
|
||||
Budowanie dokumentacji źródłowej API zostało opisane w [angielskiej wersji pliku README.md](README.md#building-the-api-reference-pages).
|
||||
|
||||
## Rozwiązywanie problemów
|
||||
### error: failed to transform resource: TOCSS: failed to transform "scss/main.scss" (text/x-scss): this feature is not available in your current Hugo version
|
||||
|
||||
Z przyczyn technicznych, Hugo jest rozprowadzany w dwóch wersjach. Aktualny serwis używa tylko wersji **Hugo Extended**. Na stronie z [wydaniami](https://github.com/gohugoio/hugo/releases) poszukaj archiwum z `extended` w nazwie. Dla potwierdzenia, uruchom `hugo version` i poszukaj słowa `extended`.
|
||||
|
||||
### Błąd w środowisku macOS: "too many open files"
|
||||
|
||||
Jeśli po uruchomieniu `make serve` na macOS widzisz następujący błąd:
|
||||
|
||||
```
|
||||
ERROR 2020/08/01 19:09:18 Error: listen tcp 127.0.0.1:1313: socket: too many open files
|
||||
make: *** [serve] Error 1
|
||||
```
|
||||
|
||||
sprawdź aktualny limit otwartych plików:
|
||||
|
||||
`launchctl limit maxfiles`
|
||||
|
||||
Uruchom następujące polecenia: (na podstawie https://gist.github.com/tombigel/d503800a282fcadbee14b537735d202c):
|
||||
|
||||
```shell
|
||||
#!/bin/sh
|
||||
|
||||
# These are the original gist links, linking to my gists now.
|
||||
# curl -O https://gist.githubusercontent.com/a2ikm/761c2ab02b7b3935679e55af5d81786a/raw/ab644cb92f216c019a2f032bbf25e258b01d87f9/limit.maxfiles.plist
|
||||
# curl -O https://gist.githubusercontent.com/a2ikm/761c2ab02b7b3935679e55af5d81786a/raw/ab644cb92f216c019a2f032bbf25e258b01d87f9/limit.maxproc.plist
|
||||
|
||||
curl -O https://gist.githubusercontent.com/tombigel/d503800a282fcadbee14b537735d202c/raw/ed73cacf82906fdde59976a0c8248cce8b44f906/limit.maxfiles.plist
|
||||
curl -O https://gist.githubusercontent.com/tombigel/d503800a282fcadbee14b537735d202c/raw/ed73cacf82906fdde59976a0c8248cce8b44f906/limit.maxproc.plist
|
||||
|
||||
sudo mv limit.maxfiles.plist /Library/LaunchDaemons
|
||||
sudo mv limit.maxproc.plist /Library/LaunchDaemons
|
||||
|
||||
sudo chown root:wheel /Library/LaunchDaemons/limit.maxfiles.plist
|
||||
sudo chown root:wheel /Library/LaunchDaemons/limit.maxproc.plist
|
||||
|
||||
sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist
|
||||
```
|
||||
|
||||
Przedstawiony sposób powinien działać dla MacOS w wersji Catalina i Mojave.
|
||||
|
||||
|
||||
# Zaangażowanie w prace SIG Docs
|
||||
|
||||
O społeczności SIG Docs i terminach spotkań dowiesz z [jej strony](https://github.com/kubernetes/community/tree/master/sig-docs#meetings).
|
||||
|
||||
Możesz kontaktować się z gospodarzami projektu za pomocą:
|
||||
|
||||
* [Komunikatora Slack](https://kubernetes.slack.com/messages/sig-docs)
|
||||
* [List dyskusyjnych](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
|
||||
- [Komunikatora Slack](https://kubernetes.slack.com/messages/sig-docs) [Tutaj możesz dostać zaproszenie do tej grupy Slack-a](https://slack.k8s.io/)
|
||||
- [List dyskusyjnych](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
|
||||
|
||||
### Zasady postępowania
|
||||
# Twój wkład w dokumentację
|
||||
|
||||
Udział w działaniach społeczności Kubernetes jest regulowany przez [Kodeks postępowania](code-of-conduct.md).
|
||||
Możesz kliknąć w przycisk **Fork** w prawym górnym rogu ekranu, aby stworzyć kopię tego repozytorium na swoim koncie GitHub. Taki rodzaj kopii (odgałęzienia) nazywa się *fork*. Zmieniaj w nim, co chcesz, a kiedy będziesz już gotowy/a przesłać te zmiany do nas, przejdź do swojej kopii i stwórz nowy *pull request*, abyśmy zostali o tym poinformowani.
|
||||
|
||||
## Dziękujemy!
|
||||
Po stworzeniu *pull request*, jeden z recenzentów projektu Kubernetes podejmie się przekazania jasnych wskazówek pozwalających podjąć następne działania. Na Tobie, jako właścicielu *pull requesta*, **spoczywa odpowiedzialność za wprowadzenie poprawek zgodnie z uwagami recenzenta.**
|
||||
|
||||
Może też się zdarzyć, że swoje uwagi zgłosi więcej niż jeden recenzent, lub że recenzję będzie robił ktoś inny, niż ten, kto został przydzielony na początku.
|
||||
|
||||
W niektórych przypadkach, jeśli zajdzie taka potrzeba, recenzent może poprosić dodatkowo o recenzję jednego z [recenzentów technicznych](https://github.com/kubernetes/website/wiki/Tech-reviewers). Recenzenci zrobią wszystko, aby odpowiedzieć sprawnie, ale konkretny czas odpowiedzi zależy od wielu czynników.
|
||||
|
||||
Więcej informacji na temat współpracy przy tworzeniu dokumentacji znajdziesz na stronach:
|
||||
|
||||
* [Udział w rozwijaniu dokumentacji](https://kubernetes.io/docs/contribute/)
|
||||
* [Rodzaje stron](https://kubernetes.io/docs/contribute/style/page-content-types/)
|
||||
* [Styl pisania dokumentacji](http://kubernetes.io/docs/contribute/style/style-guide/)
|
||||
* [Lokalizacja dokumentacji Kubernetes](https://kubernetes.io/docs/contribute/localization/)
|
||||
|
||||
# Różne wersje językowe `README.md`
|
||||
|
||||
| Język | Język |
|
||||
|---|---|
|
||||
| [angielski](README.md) | [francuski](README-fr.md) |
|
||||
| [koreański](README-ko.md) | [niemiecki](README-de.md) |
|
||||
| [portugalski](README-pt.md) | [hindi](README-hi.md) |
|
||||
| [hiszpański](README-es.md) | [indonezyjski](README-id.md) |
|
||||
| [chiński](README-zh.md) | [japoński](README-ja.md) |
|
||||
| [wietnamski](README-vi.md) | [rosyjski](README-ru.md) |
|
||||
| [włoski](README-it.md) | [ukraiński](README-uk.md) |
|
||||
|
||||
# Zasady postępowania
|
||||
|
||||
Udział w działaniach społeczności Kubernetesa jest regulowany przez [Kodeks postępowania CNCF](https://github.com/cncf/foundation/blob/master/code-of-conduct-languages/pl.md).
|
||||
|
||||
# Dziękujemy!
|
||||
|
||||
Kubernetes rozkwita dzięki zaangażowaniu społeczności — doceniamy twój wkład w tworzenie naszego serwisu i dokumentacji!
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# A documentação do Kubernetes
|
||||
|
||||
[](https://app.netlify.com/sites/kubernetes-io-master-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
[](https://app.netlify.com/sites/kubernetes-io-main-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
|
||||
Bem-vindos! Este repositório contém todos os recursos necessários para criar o [website e documentação do Kubernetes](https://kubernetes.io/). Estamos muito satisfeitos por você querer contribuir!
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<!-- # The Kubernetes documentation -->
|
||||
# Документація Kubernetes
|
||||
|
||||
[](https://app.netlify.com/sites/kubernetes-io-master-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
[](https://app.netlify.com/sites/kubernetes-io-main-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
|
||||
<!-- This repository contains the assets required to build the [Kubernetes website and documentation](https://kubernetes.io/). We're glad that you want to contribute! -->
|
||||
Вітаємо! В цьому репозиторії міститься все необхідне для роботи над [сайтом і документацією Kubernetes](https://kubernetes.io/). Ми щасливі, що ви хочете зробити свій внесок!
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# The Kubernetes documentation
|
||||
-->
|
||||
|
||||
[](https://app.netlify.com/sites/kubernetes-io-master-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
[](https://app.netlify.com/sites/kubernetes-io-main-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
|
||||
<!--
|
||||
This repository contains the assets required to build the [Kubernetes website and documentation](https://kubernetes.io/). We're glad that you want to contribute!
|
||||
@@ -174,7 +174,7 @@ Learn more about SIG Docs Kubernetes community and meetings on the [community pa
|
||||
|
||||
You can also reach the maintainers of this project at:
|
||||
|
||||
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
|
||||
- [Slack](https://kubernetes.slack.com/messages/sig-docs) [Get an invite for this Slack](https://slack.k8s.io/)
|
||||
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
|
||||
-->
|
||||
# 参与 SIG Docs 工作
|
||||
@@ -184,7 +184,7 @@ You can also reach the maintainers of this project at:
|
||||
|
||||
你也可以通过以下渠道联系本项目的维护人员:
|
||||
|
||||
- [Slack](https://kubernetes.slack.com/messages/sig-docs)
|
||||
- [Slack](https://kubernetes.slack.com/messages/sig-docs) [加入Slack](https://slack.k8s.io/)
|
||||
- [邮件列表](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
|
||||
|
||||
<!--
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
# The Kubernetes documentation
|
||||
|
||||
[](https://app.netlify.com/sites/kubernetes-io-master-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
[](https://app.netlify.com/sites/kubernetes-io-main-staging/deploys) [](https://github.com/kubernetes/website/releases/latest)
|
||||
|
||||
This repository contains the assets required to build the [Kubernetes website and documentation](https://kubernetes.io/). We're glad that you want to contribute!
|
||||
|
||||
+ [Contributing to the docs](#contributing-to-the-docs)
|
||||
+ [Localization ReadMes](#localization-readmemds)
|
||||
- [Contributing to the docs](#contributing-to-the-docs)
|
||||
- [Localization ReadMes](#localization-readmemds)
|
||||
|
||||
# Using this repository
|
||||
## Using this repository
|
||||
|
||||
You can run the website locally using Hugo (Extended version), or you can run it in a container runtime. We strongly recommend using the container runtime, as it gives deployment consistency with the live website.
|
||||
|
||||
@@ -22,14 +22,14 @@ To use this repository, you need the following installed locally:
|
||||
|
||||
Before you start, install the dependencies. Clone the repository and navigate to the directory:
|
||||
|
||||
```
|
||||
```bash
|
||||
git clone https://github.com/kubernetes/website.git
|
||||
cd website
|
||||
```
|
||||
|
||||
The Kubernetes website uses the [Docsy Hugo theme](https://github.com/google/docsy#readme). Even if you plan to run the website in a container, we strongly recommend pulling in the submodule and other development dependencies by running the following:
|
||||
|
||||
```
|
||||
```bash
|
||||
# pull in the Docsy submodule
|
||||
git submodule update --init --recursive --depth 1
|
||||
```
|
||||
@@ -38,12 +38,14 @@ git submodule update --init --recursive --depth 1
|
||||
|
||||
To build the site in a container, run the following to build the container image and run it:
|
||||
|
||||
```
|
||||
```bash
|
||||
make container-image
|
||||
make container-serve
|
||||
```
|
||||
|
||||
Open up your browser to http://localhost:1313 to view the website. As you make changes to the source files, Hugo updates the website and forces a browser refresh.
|
||||
If you see errors, it probably means that the hugo container did not have enough computing resources available. To solve it, increase the amount of allowed CPU and memory usage for Docker on your machine ([MacOSX](https://docs.docker.com/docker-for-mac/#resources) and [Windows](https://docs.docker.com/docker-for-windows/#resources)).
|
||||
|
||||
Open up your browser to <http://localhost:1313> to view the website. As you make changes to the source files, Hugo updates the website and forces a browser refresh.
|
||||
|
||||
## Running the website locally using Hugo
|
||||
|
||||
@@ -57,54 +59,55 @@ npm ci
|
||||
make serve
|
||||
```
|
||||
|
||||
This will start the local Hugo server on port 1313. Open up your browser to http://localhost:1313 to view the website. As you make changes to the source files, Hugo updates the website and forces a browser refresh.
|
||||
This will start the local Hugo server on port 1313. Open up your browser to <http://localhost:1313> to view the website. As you make changes to the source files, Hugo updates the website and forces a browser refresh.
|
||||
|
||||
## Building the API reference pages
|
||||
|
||||
The API reference pages located in `content/en/docs/reference/kubernetes-api` are built from the Swagger specification, using https://github.com/kubernetes-sigs/reference-docs/tree/master/gen-resourcesdocs.
|
||||
The API reference pages located in `content/en/docs/reference/kubernetes-api` are built from the Swagger specification, using <https://github.com/kubernetes-sigs/reference-docs/tree/master/gen-resourcesdocs>.
|
||||
|
||||
To update the reference pages for a new Kubernetes release (replace v1.20 in the following examples with the release to update to):
|
||||
|
||||
1. Pull the `kubernetes-resources-reference` submodule:
|
||||
|
||||
```
|
||||
git submodule update --init --recursive --depth 1
|
||||
```
|
||||
```bash
|
||||
git submodule update --init --recursive --depth 1
|
||||
```
|
||||
|
||||
2. Create a new API revision into the submodule, and add the Swagger specification:
|
||||
|
||||
```
|
||||
mkdir api-ref-generator/gen-resourcesdocs/api/v1.20
|
||||
curl 'https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json' > api-ref-generator/gen-resourcesdocs/api/v1.20/swagger.json
|
||||
```
|
||||
```bash
|
||||
mkdir api-ref-generator/gen-resourcesdocs/api/v1.20
|
||||
curl 'https://raw.githubusercontent.com/kubernetes/kubernetes/master/api/openapi-spec/swagger.json' > api-ref-generator/gen-resourcesdocs/api/v1.20/swagger.json
|
||||
```
|
||||
|
||||
3. Copy the table of contents and fields configuration for the new release from a previous one:
|
||||
|
||||
```
|
||||
mkdir api-ref-generator/gen-resourcesdocs/api/v1.20
|
||||
cp api-ref-generator/gen-resourcesdocs/api/v1.19/* api-ref-generator/gen-resourcesdocs/api/v1.20/
|
||||
```
|
||||
```bash
|
||||
mkdir api-ref-generator/gen-resourcesdocs/api/v1.20
|
||||
cp api-ref-generator/gen-resourcesdocs/api/v1.19/* api-ref-generator/gen-resourcesdocs/api/v1.20/
|
||||
```
|
||||
|
||||
4. Adapt the files `toc.yaml` and `fields.yaml` to reflect the changes between the two releases
|
||||
|
||||
5. Next, build the pages:
|
||||
|
||||
```
|
||||
make api-reference
|
||||
```
|
||||
```bash
|
||||
make api-reference
|
||||
```
|
||||
|
||||
You can test the results locally by making and serving the site from a container image:
|
||||
You can test the results locally by making and serving the site from a container image:
|
||||
|
||||
```
|
||||
make container-image
|
||||
make container-serve
|
||||
```
|
||||
```bash
|
||||
make container-image
|
||||
make container-serve
|
||||
```
|
||||
|
||||
In a web browser, go to http://localhost:1313/docs/reference/kubernetes-api/ to view the API reference.
|
||||
In a web browser, go to <http://localhost:1313/docs/reference/kubernetes-api/> to view the API reference.
|
||||
|
||||
6. When all changes of the new contract are reflected into the configuration files `toc.yaml` and `fields.yaml`, create a Pull Request with the newly generated API reference pages.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### error: failed to transform resource: TOCSS: failed to transform "scss/main.scss" (text/x-scss): this feature is not available in your current Hugo version
|
||||
|
||||
Hugo is shipped in two set of binaries for technical reasons. The current website runs based on the **Hugo Extended** version only. In the [release page](https://github.com/gohugoio/hugo/releases) look for archives with `extended` in the name. To confirm, run `hugo version` and look for the word `extended`.
|
||||
@@ -113,7 +116,7 @@ Hugo is shipped in two set of binaries for technical reasons. The current websit
|
||||
|
||||
If you run `make serve` on macOS and receive the following error:
|
||||
|
||||
```
|
||||
```bash
|
||||
ERROR 2020/08/01 19:09:18 Error: listen tcp 127.0.0.1:1313: socket: too many open files
|
||||
make: *** [serve] Error 1
|
||||
```
|
||||
@@ -122,7 +125,7 @@ Try checking the current limit for open files:
|
||||
|
||||
`launchctl limit maxfiles`
|
||||
|
||||
Then run the following commands (adapted from https://gist.github.com/tombigel/d503800a282fcadbee14b537735d202c):
|
||||
Then run the following commands (adapted from <https://gist.github.com/tombigel/d503800a282fcadbee14b537735d202c>):
|
||||
|
||||
```shell
|
||||
#!/bin/sh
|
||||
@@ -145,8 +148,7 @@ sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist
|
||||
|
||||
This works for Catalina as well as Mojave macOS.
|
||||
|
||||
|
||||
# Get involved with SIG Docs
|
||||
## Get involved with SIG Docs
|
||||
|
||||
Learn more about SIG Docs Kubernetes community and meetings on the [community page](https://github.com/kubernetes/community/tree/master/sig-docs#meetings).
|
||||
|
||||
@@ -155,39 +157,39 @@ You can also reach the maintainers of this project at:
|
||||
- [Slack](https://kubernetes.slack.com/messages/sig-docs) [Get an invite for this Slack](https://slack.k8s.io/)
|
||||
- [Mailing List](https://groups.google.com/forum/#!forum/kubernetes-sig-docs)
|
||||
|
||||
# Contributing to the docs
|
||||
## Contributing to the docs
|
||||
|
||||
You can click the **Fork** button in the upper-right area of the screen to create a copy of this repository in your GitHub account. This copy is called a *fork*. Make any changes you want in your fork, and when you are ready to send those changes to us, go to your fork and create a new pull request to let us know about it.
|
||||
You can click the **Fork** button in the upper-right area of the screen to create a copy of this repository in your GitHub account. This copy is called a _fork_. Make any changes you want in your fork, and when you are ready to send those changes to us, go to your fork and create a new pull request to let us know about it.
|
||||
|
||||
Once your pull request is created, a Kubernetes reviewer will take responsibility for providing clear, actionable feedback. As the owner of the pull request, **it is your responsibility to modify your pull request to address the feedback that has been provided to you by the Kubernetes reviewer.**
|
||||
Once your pull request is created, a Kubernetes reviewer will take responsibility for providing clear, actionable feedback. As the owner of the pull request, **it is your responsibility to modify your pull request to address the feedback that has been provided to you by the Kubernetes reviewer.**
|
||||
|
||||
Also, note that you may end up having more than one Kubernetes reviewer provide you feedback or you may end up getting feedback from a Kubernetes reviewer that is different than the one initially assigned to provide you feedback.
|
||||
|
||||
Furthermore, in some cases, one of your reviewers might ask for a technical review from a Kubernetes tech reviewer when needed. Reviewers will do their best to provide feedback in a timely fashion but response time can vary based on circumstances.
|
||||
Furthermore, in some cases, one of your reviewers might ask for a technical review from a Kubernetes tech reviewer when needed. Reviewers will do their best to provide feedback in a timely fashion but response time can vary based on circumstances.
|
||||
|
||||
For more information about contributing to the Kubernetes documentation, see:
|
||||
|
||||
* [Contribute to Kubernetes docs](https://kubernetes.io/docs/contribute/)
|
||||
* [Page Content Types](https://kubernetes.io/docs/contribute/style/page-content-types/)
|
||||
* [Documentation Style Guide](https://kubernetes.io/docs/contribute/style/style-guide/)
|
||||
* [Localizing Kubernetes Documentation](https://kubernetes.io/docs/contribute/localization/)
|
||||
- [Contribute to Kubernetes docs](https://kubernetes.io/docs/contribute/)
|
||||
- [Page Content Types](https://kubernetes.io/docs/contribute/style/page-content-types/)
|
||||
- [Documentation Style Guide](https://kubernetes.io/docs/contribute/style/style-guide/)
|
||||
- [Localizing Kubernetes Documentation](https://kubernetes.io/docs/contribute/localization/)
|
||||
|
||||
# Localization `README.md`'s
|
||||
## Localization `README.md`'s
|
||||
|
||||
| Language | Language |
|
||||
|---|---|
|
||||
|[Chinese](README-zh.md)|[Korean](README-ko.md)|
|
||||
|[French](README-fr.md)|[Polish](README-pl.md)|
|
||||
|[German](README-de.md)|[Portuguese](README-pt.md)|
|
||||
|[Hindi](README-hi.md)|[Russian](README-ru.md)|
|
||||
|[Indonesian](README-id.md)|[Spanish](README-es.md)|
|
||||
|[Italian](README-it.md)|[Ukrainian](README-uk.md)|
|
||||
|[Japanese](README-ja.md)|[Vietnamese](README-vi.md)|
|
||||
| Language | Language |
|
||||
| -------------------------- | -------------------------- |
|
||||
| [Chinese](README-zh.md) | [Korean](README-ko.md) |
|
||||
| [French](README-fr.md) | [Polish](README-pl.md) |
|
||||
| [German](README-de.md) | [Portuguese](README-pt.md) |
|
||||
| [Hindi](README-hi.md) | [Russian](README-ru.md) |
|
||||
| [Indonesian](README-id.md) | [Spanish](README-es.md) |
|
||||
| [Italian](README-it.md) | [Ukrainian](README-uk.md) |
|
||||
| [Japanese](README-ja.md) | [Vietnamese](README-vi.md) |
|
||||
|
||||
# Code of conduct
|
||||
## Code of conduct
|
||||
|
||||
Participation in the Kubernetes community is governed by the [CNCF Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md).
|
||||
|
||||
# Thank you!
|
||||
## Thank you
|
||||
|
||||
Kubernetes thrives on community participation, and we appreciate your contributions to our website and our documentation!
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "{{ replace .Name "-" " " | title }}"
|
||||
date: {{ .Date }}
|
||||
draft: true
|
||||
slug: <seo-friendly-version-of-title-separated-by-dashes>
|
||||
---
|
||||
|
||||
**Author:** <your name> (<your organization name>), <another author's name> (<their organization>)
|
||||
|
||||
<!--
|
||||
Instructions:
|
||||
- Replace these instructions and the following text with your content.
|
||||
- Replace `<angle bracket placeholders>` with actual values. For example, you would update `date: <yyyy>-<mm>-<dd>` to look something like `date: 2021-10-21`.
|
||||
- For convenience, use third-party tools to author and collaborate on your content.
|
||||
- To save time and effort in reviews, check your content's spelling, grammar, and style before contributing.
|
||||
- Feel free to ask for assistance in the Kubernetes Slack channel, [#sig-docs-blog](https://kubernetes.slack.com/archives/CJDHVD54J).
|
||||
-->
|
||||
|
||||
Replace this first line of your content with one to three sentences that summarize the blog post.
|
||||
|
||||
## This is a section heading
|
||||
|
||||
To help the reader, organize your content into sections that contain about three to six paragraphs.
|
||||
|
||||
If you're documenting commands, separate the commands from the outputs, like this:
|
||||
|
||||
1. Verify that the Secret exists by running the following command:
|
||||
|
||||
```shell
|
||||
kubectl get secrets
|
||||
```
|
||||
|
||||
The response should be like this:
|
||||
|
||||
```shell
|
||||
NAME TYPE DATA AGE
|
||||
mysql-pass-c57bb4t7mf Opaque 1 9s
|
||||
```
|
||||
|
||||
You're free to create any sections you like. Below are a few common patterns we see at the end of blog posts.
|
||||
|
||||
## What’s next?
|
||||
|
||||
This optional section describes the future of the thing you've just described in the post.
|
||||
|
||||
## How can I learn more?
|
||||
|
||||
This optional section provides links to more information. Please avoid promoting and over-represent your organization.
|
||||
|
||||
## How do I get involved?
|
||||
|
||||
An optional section that links to resources for readers to get involved, and acknowledgments of individual contributors, such as:
|
||||
|
||||
* [The name of a channel on Slack, #a-channel](https://<a-workspace>.slack.com/messages/<a-channel>)
|
||||
|
||||
* [A link to a "contribute" page with more information](<https://github.com/kubernetes/community/blob/master/sig-storage/README.md#contact>).
|
||||
|
||||
* Acknowledgements and thanks to the contributors. <person's name> ([<github id>](https://github.com/<github id>)) who did X, Y, and Z.
|
||||
|
||||
* Those interested in getting involved with the design and development of <project>, join the [<name of the SIG>](https://github.com/project/community/tree/master/<sig-group>). We’re rapidly growing and always welcome new contributors.
|
||||
@@ -444,7 +444,7 @@ body.cid-community > #deprecation-warning > .deprecation-warning > * {
|
||||
.td-sidebar__inner {
|
||||
form.td-sidebar__search {
|
||||
|
||||
button.td-sidebar__toggle {
|
||||
.td-sidebar__toggle {
|
||||
&:hover {
|
||||
color: #000000;
|
||||
}
|
||||
@@ -482,10 +482,6 @@ main.content {
|
||||
|
||||
.td-blog {
|
||||
|
||||
.td-sidebar-nav {
|
||||
max-height: calc(100vh - 8rem);
|
||||
}
|
||||
|
||||
.widget-link {
|
||||
margin-bottom: 1rem;
|
||||
|
||||
|
||||
@@ -77,7 +77,6 @@ $feature-box-div-width: 45%;
|
||||
position: relative;
|
||||
clear: both;
|
||||
display: table;
|
||||
height: 160px;
|
||||
|
||||
.content {
|
||||
display: table-cell;
|
||||
@@ -124,6 +123,7 @@ $feature-box-div-width: 45%;
|
||||
position: relative;
|
||||
display: block;
|
||||
float: none;
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# See https://cloud.google.com/cloud-build/docs/build-config
|
||||
|
||||
# this must be specified in seconds. If omitted, defaults to 600s (10 mins)
|
||||
timeout: 1200s
|
||||
# this prevents errors if you don't use both _GIT_TAG and _PULL_BASE_REF,
|
||||
# or any new substitutions added in the future.
|
||||
options:
|
||||
substitution_option: ALLOW_LOOSE
|
||||
steps:
|
||||
# It's fine to bump the tag to a recent version, as needed
|
||||
- name: "gcr.io/k8s-testimages/gcb-docker-gcloud:v20190906-745fed4"
|
||||
entrypoint: make
|
||||
env:
|
||||
- DOCKER_CLI_EXPERIMENTAL=enabled
|
||||
- TAG=$_GIT_TAG
|
||||
- BASE_REF=$_PULL_BASE_REF
|
||||
args:
|
||||
- container-image
|
||||
substitutions:
|
||||
# _GIT_TAG will be filled with a git-based tag for the image, of the form vYYYYMMDD-hash, and
|
||||
# can be used as a substitution
|
||||
_GIT_TAG: "12345"
|
||||
# _PULL_BASE_REF will contain the ref that was pushed to to trigger this build -
|
||||
# a branch like 'master' or 'release-0.2', or a tag like 'v0.2'.
|
||||
_PULL_BASE_REF: "master"
|
||||
@@ -138,12 +138,12 @@ time_format_default = "January 02, 2006 at 3:04 PM PST"
|
||||
description = "Production-Grade Container Orchestration"
|
||||
showedit = true
|
||||
|
||||
latest = "v1.21"
|
||||
latest = "v1.22"
|
||||
|
||||
fullversion = "v1.20.5"
|
||||
version = "v1.20"
|
||||
githubbranch = "v1.20.5"
|
||||
docsbranch = "release-1.20"
|
||||
fullversion = "v1.21.4"
|
||||
version = "v1.21"
|
||||
githubbranch = "release-1.21"
|
||||
docsbranch = "release-1.21"
|
||||
deprecated = true
|
||||
currentUrl = "https://kubernetes.io/docs/home/"
|
||||
nextUrl = "https://kubernetes-io-vnext-staging.netlify.com/"
|
||||
@@ -178,41 +178,40 @@ js = [
|
||||
]
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.21.0"
|
||||
version = "v1.21"
|
||||
githubbranch = "v1.21.0"
|
||||
docsbranch = "master"
|
||||
fullversion = "v1.22.0"
|
||||
version = "v1.22"
|
||||
githubbranch = "v1.22.0"
|
||||
docsbranch = "main"
|
||||
url = "https://kubernetes.io"
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.20.5"
|
||||
fullversion = "v1.21.4"
|
||||
version = "v1.21"
|
||||
githubbranch = "v1.21.4"
|
||||
docsbranch = "release-1.21"
|
||||
url = "https://v1-21.docs.kubernetes.io"
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.20.10"
|
||||
version = "v1.20"
|
||||
githubbranch = "v1.20.5"
|
||||
githubbranch = "v1.20.10"
|
||||
docsbranch = "release-1.20"
|
||||
url = "https://v1-20.docs.kubernetes.io"
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.19.9"
|
||||
fullversion = "v1.19.14"
|
||||
version = "v1.19"
|
||||
githubbranch = "v1.19.9"
|
||||
githubbranch = "v1.19.14"
|
||||
docsbranch = "release-1.19"
|
||||
url = "https://v1-19.docs.kubernetes.io"
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.18.17"
|
||||
fullversion = "v1.18.20"
|
||||
version = "v1.18"
|
||||
githubbranch = "v1.18.17"
|
||||
githubbranch = "v1.18.20"
|
||||
docsbranch = "release-1.18"
|
||||
url = "https://v1-18.docs.kubernetes.io"
|
||||
|
||||
[[params.versions]]
|
||||
fullversion = "v1.17.17"
|
||||
version = "v1.17"
|
||||
githubbranch = "v1.17.17"
|
||||
docsbranch = "release-1.17"
|
||||
url = "https://v1-17.docs.kubernetes.io"
|
||||
|
||||
|
||||
# User interface configuration
|
||||
[params.ui]
|
||||
# Enable to show the side bar menu in its compact state.
|
||||
@@ -399,15 +398,15 @@ time_format_blog = "02.01.2006"
|
||||
# A list of language codes to look for untranslated content, ordered from left to right.
|
||||
language_alternatives = ["en"]
|
||||
|
||||
[languages.pt]
|
||||
[languages.pt-br]
|
||||
title = "Kubernetes"
|
||||
description = "Orquestração de contêineres em nível de produção"
|
||||
languageName ="Português"
|
||||
weight = 9
|
||||
contentDir = "content/pt"
|
||||
contentDir = "content/pt-br"
|
||||
languagedirection = "ltr"
|
||||
|
||||
[languages.pt.params]
|
||||
[languages.pt-br.params]
|
||||
time_format_blog = "02.01.2006"
|
||||
# A list of language codes to look for untranslated content, ordered from left to right.
|
||||
language_alternatives = ["en"]
|
||||
|
||||
@@ -147,7 +147,8 @@ Die zweite ist, die interne Node-Liste des Node Controllers mit der Liste der ve
|
||||
Wenn ein Node in einer Cloud-Umgebung ausgeführt wird und sich in einem schlechten Zustand befindet, fragt der Node Controller den Cloud-Anbieter, ob die virtuelle Maschine für diesen Node noch verfügbar ist. Wenn nicht, löscht der Node Controller den Node aus seiner Node-Liste.
|
||||
|
||||
Der dritte ist die Überwachung des Zustands der Nodes. Der Node Controller ist dafür verantwortlich,
|
||||
die NodeReady-Bedingung von NodeStatus auf ConditionUnknown zu aktualisieren, wenn ein wenn ein Node unerreichbar wird (der Node Controller empfängt aus irgendeinem Grund keine Herzschläge mehr, z.B. weil der Node heruntergefahren ist) und später alle Pods aus dem Node zu entfernen (und diese ordnungsgemäss zu beenden), wenn der Node weiterhin unzugänglich ist. (Die Standard-Timeouts sind 40s, um ConditionUnknown zu melden und 5 Minuten, um mit der Evakuierung der Pods zu beginnen).
|
||||
die NodeReady-Bedingung von NodeStatus auf ConditionUnknown zu aktualisieren, wenn ein Node unerreichbar wird (der Node Controller empfängt aus irgendeinem Grund keine Herzschläge mehr, z.B. weil der Node heruntergefahren ist) und später alle Pods aus dem Node zu entfernen (und diese ordnungsgemäss zu beenden), wenn der Node weiterhin unzugänglich ist. (Die Standard-Timeouts sind 40s, um ConditionUnknown zu melden und 5 Minuten, um mit der Evakuierung der Pods zu beginnen).
|
||||
|
||||
Der Node Controller überprüft den Zustand jedes Nodes alle `--node-monitor-period` Sekunden.
|
||||
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ Die Add-Ons in den einzelnen Kategorien sind alphabetisch sortiert - Die Reihenf
|
||||
* [CNI-Genie](https://github.com/Huawei-PaaS/CNI-Genie) ermöglicht das nahtlose Verbinden von Kubernetes mit einer Reihe an CNI-Plugins wie z.B. Calico, Canal, Flannel, Romana, oder Weave.
|
||||
* [Contiv](http://contiv.github.io) bietet konfigurierbares Networking (Native L3 auf BGP, Overlay mit vxlan, Klassisches L2, Cisco-SDN/ACI) für verschiedene Anwendungszwecke und auch umfangreiches Policy-Framework. Das Contiv-Projekt ist vollständig [Open Source](http://github.com/contiv). Der [installer](http://github.com/contiv/install) bietet sowohl kubeadm als auch nicht-kubeadm basierte Installationen.
|
||||
* [Contrail](http://www.juniper.net/us/en/products-services/sdn/contrail/contrail-networking/), basierend auf [Tungsten Fabric](https://tungsten.io), ist eine Open Source, multi-Cloud Netzwerkvirtualisierungs- und Policy-Management Plattform. Contrail und Tungsten Fabric sind mit Orechstratoren wie z.B. Kubernetes, OpenShift, OpenStack und Mesos integriert und bieten Isolationsmodi für Virtuelle Maschinen, Container (bzw. Pods) und Bare Metal workloads.
|
||||
* [Flannel](https://github.com/coreos/flannel/blob/master/Documentation/kubernetes.md) ist ein Overlay-Network-Provider der mit Kubernetes genutzt werden kann.
|
||||
* [Flannel](https://github.com/flannel-io/flannel#deploying-flannel-manually) ist ein Overlay-Network-Provider der mit Kubernetes genutzt werden kann.
|
||||
* [Knitter](https://github.com/ZTE/Knitter/) ist eine Network-Lösung die Mehrfach-Network in Kubernetes ermöglicht.
|
||||
* [Multus](https://github.com/Intel-Corp/multus-cni) ist ein Multi-Plugin für Mehrfachnetzwerk-Unterstützung um alle CNI-Plugins (z.B. Calico, Cilium, Contiv, Flannel), zusätzlich zu SRIOV-, DPDK-, OVS-DPDK- und VPP-Basierten Workloads in Kubernetes zu unterstützen.
|
||||
* [NSX-T](https://docs.vmware.com/en/VMware-NSX-T/2.0/nsxt_20_ncp_kubernetes.pdf) Container Plug-in (NCP) bietet eine Integration zwischen VMware NSX-T und einem Orchestator wie z.B. Kubernetes. Außerdem bietet es eine Integration zwischen NSX-T und Containerbasierten CaaS/PaaS-Plattformen wie z.B. Pivotal Container Service (PKS) und OpenShift.
|
||||
|
||||
@@ -0,0 +1,369 @@
|
||||
---
|
||||
title: Pods
|
||||
content_type: concept
|
||||
weight: 10
|
||||
no_list: true
|
||||
card:
|
||||
name: concepts
|
||||
weight: 60
|
||||
---
|
||||
|
||||
<!-- overview -->
|
||||
|
||||
_Pods_ sind die kleinsten einsetzbaren Einheiten, die in Kubernetes
|
||||
erstellt und verwaltet werden können.
|
||||
|
||||
Ein _Pod_ (übersetzt Gruppe/Schote, wie z. B. eine Gruppe von Walen oder eine
|
||||
Erbsenschote) ist eine Gruppe von einem oder mehreren
|
||||
{{< glossary_tooltip text="Containern" term_id="container" >}} mit gemeinsam
|
||||
genutzten Speicher- und Netzwerkressourcen und einer Spezifikation für die
|
||||
Ausführung der Container. Die Ressourcen eines Pods befinden sich immer auf dem
|
||||
gleichen (virtuellen) Server, werden gemeinsam geplant und in einem
|
||||
gemeinsamen Kontext ausgeführt. Ein Pod modelliert einen anwendungsspezifischen
|
||||
"logischen Server": Er enthält eine oder mehrere containerisierte Anwendungen,
|
||||
die relativ stark voneinander abhängen.
|
||||
In Nicht-Cloud-Kontexten sind Anwendungen, die auf
|
||||
demselben physischen oder virtuellen Server ausgeführt werden, vergleichbar zu
|
||||
Cloud-Anwendungen, die auf demselben logischen Server ausgeführt werden.
|
||||
|
||||
Ein Pod kann neben Anwendungs-Containern auch sogenannte
|
||||
[Initialisierungs-Container](/docs/concepts/workloads/pods/init-containers/)
|
||||
enthalten, die beim Starten des Pods ausgeführt werden.
|
||||
Es können auch
|
||||
kurzlebige/[ephemere Container](/docs/concepts/workloads/pods/ephemeral-containers/)
|
||||
zum Debuggen gestartet werden, wenn dies der Cluster anbietet.
|
||||
|
||||
<!-- body -->
|
||||
|
||||
## Was ist ein Pod?
|
||||
|
||||
{{< note >}}
|
||||
Obwohl Kubernetes abgesehen von [Docker](https://www.docker.com/) auch andere
|
||||
{{<glossary_tooltip text="Container-Laufzeitumgebungen"
|
||||
term_id="container-runtime">}} unterstützt, ist Docker am bekanntesten und
|
||||
es ist hilfreich, Pods mit der Terminologie von Docker zu beschreiben.
|
||||
{{< /note >}}
|
||||
|
||||
Der gemeinsame Kontext eines Pods besteht aus einer Reihe von Linux-Namespaces,
|
||||
Cgroups und möglicherweise anderen Aspekten der Isolation, also die gleichen
|
||||
Dinge, die einen Dockercontainer isolieren. Innerhalb des Kontexts eines Pods
|
||||
können die einzelnen Anwendungen weitere Unterisolierungen haben.
|
||||
|
||||
Im Sinne von Docker-Konzepten ähnelt ein Pod einer Gruppe von Docker-Containern,
|
||||
die gemeinsame Namespaces und Dateisystem-Volumes nutzen.
|
||||
|
||||
## Pods verwenden
|
||||
|
||||
Normalerweise müssen keine Pods erzeugt werden, auch keine Singleton-Pods.
|
||||
Stattdessen werden sie mit Workload-Ressourcen wie {{<glossary_tooltip
|
||||
text="Deployment" term_id="deployment">}} oder {{<glossary_tooltip
|
||||
text="Job" term_id="job">}} erzeugt. Für Pods, die von einem Systemzustand
|
||||
abhängen, ist die Nutzung von {{<glossary_tooltip text="StatefulSet"
|
||||
term_id="statefulset">}}-Ressourcen zu erwägen.
|
||||
|
||||
Pods in einem Kubernetes-Cluster werden hauptsächlich auf zwei Arten verwendet:
|
||||
|
||||
* **Pods, die einen einzelnen Container ausführen**. Das
|
||||
"Ein-Container-per-Pod"-Modell ist der häufigste Kubernetes-Anwendungsfall. In
|
||||
diesem Fall kannst du dir einen einen Pod als einen Behälter vorstellen, der einen
|
||||
einzelnen Container enthält; Kubernetes verwaltet die Pods anstatt die
|
||||
Container direkt zu verwalten.
|
||||
* **Pods, in denen mehrere Container ausgeführt werden, die zusammenarbeiten
|
||||
müssen**. Wenn eine Softwareanwendung aus co-lokaliserten Containern besteht,
|
||||
die sich gemeinsame Ressourcen teilen und stark voneinander abhängen, kann ein
|
||||
Pod die Container verkapseln.
|
||||
Diese Container bilden eine einzelne zusammenhängende
|
||||
Serviceeinheit, z. B. ein Container, der Daten in einem gemeinsam genutzten
|
||||
Volume öffentlich verfügbar macht, während ein separater _Sidecar_-Container
|
||||
die Daten aktualisiert. Der Pod fasst die Container, die Speicherressourcen
|
||||
und eine kurzlebiges Netzwerk-Identität als eine Einheit zusammen.
|
||||
|
||||
{{< note >}}
|
||||
Das Gruppieren mehrerer gemeinsam lokalisierter und gemeinsam verwalteter
|
||||
Container in einem einzigen Pod ist ein relativ fortgeschrittener
|
||||
Anwendungsfall. Du solltest diese Architektur nur in bestimmten Fällen
|
||||
verwenden, wenn deine Container stark voneinander abhängen.
|
||||
{{< /note >}}
|
||||
|
||||
Jeder Pod sollte eine einzelne Instanz einer gegebenen Anwendung ausführen. Wenn
|
||||
du deine Anwendung horizontal skalieren willst (um mehr Instanzen auszuführen
|
||||
und dadurch mehr Gesamtressourcen bereitstellen), solltest du mehrere Pods
|
||||
verwenden, einen für jede Instanz.
|
||||
In Kubernetes wird dies typischerweise als Replikation bezeichnet.
|
||||
Replizierte Pods werden normalerweise als eine Gruppe durch eine
|
||||
Workload-Ressource und deren
|
||||
{{<glossary_tooltip text="Controller" term_id="controller">}} erstellt
|
||||
und verwaltet.
|
||||
|
||||
Der Abschnitt [Pods und Controller](#pods-und-controller) beschreibt, wie
|
||||
Kubernetes Workload-Ressourcen und deren Controller verwendet, um Anwendungen
|
||||
zu skalieren und zu heilen.
|
||||
|
||||
### Wie Pods mehrere Container verwalten
|
||||
|
||||
Pods unterstützen mehrere kooperierende Prozesse (als Container), die eine
|
||||
zusammenhängende Serviceeinheit bilden. Kubernetes plant und stellt automatisch
|
||||
sicher, dass sich die Container in einem Pod auf demselben physischen oder
|
||||
virtuellen Server im Cluster befinden. Die Container können Ressourcen und
|
||||
Abhängigkeiten gemeinsam nutzen, miteinander kommunizieren und
|
||||
ferner koordinieren wann und wie sie beendet werden.
|
||||
|
||||
Zum Beispiel könntest du einen Container haben, der als Webserver für Dateien in
|
||||
einem gemeinsamen Volume arbeitet. Und ein separater "Sidecar" -Container
|
||||
aktualisiert die Daten von einer externen Datenquelle, siehe folgenden
|
||||
Abbildung:
|
||||
|
||||
{{< figure src="/images/docs/pod.svg" alt="Pod-Beispieldiagramm" width="50%" >}}
|
||||
|
||||
Einige Pods haben sowohl {{<glossary_tooltip text="Initialisierungs-Container"
|
||||
term_id="init-container">}} als auch {{<glossary_tooltip
|
||||
text="Anwendungs-Container" term_id="app-container">}}.
|
||||
Initialisierungs-Container werden gestartet und beendet bevor die
|
||||
Anwendungs-Container gestartet werden.
|
||||
|
||||
Pods stellen standardmäßig zwei Arten von gemeinsam Ressourcen für die
|
||||
enthaltenen Container bereit:
|
||||
[Netzwerk](#pod-netzwerk) und [Speicher](#datenspeicherung-in-pods).
|
||||
|
||||
|
||||
## Mit Pods arbeiten
|
||||
|
||||
Du wirst selten einzelne Pods direkt in Kubernetes erstellen, selbst
|
||||
Singleton-Pods. Das liegt daran, dass Pods als relativ kurzlebige
|
||||
Einweg-Einheiten konzipiert sind. Wann Ein Pod erstellt wird (entweder direkt
|
||||
von Ihnen oder indirekt von einem
|
||||
{{<glossary_tooltip text="Controller" term_id="controller">}}), wird die
|
||||
Ausführung auf einem {{<glossary_tooltip term_id="node">}} in Ihrem Cluster
|
||||
geplant. Der Pod bleibt auf diesem (virtuellen) Server, bis entweder der Pod die
|
||||
Ausführung beendet hat, das Pod-Objekt gelöscht wird, der Pod aufgrund
|
||||
mangelnder Ressourcen *evakuiert* wird oder oder der Node ausfällt.
|
||||
|
||||
{{< note >}}
|
||||
Das Neustarten eines Containers in einem Pod sollte nicht mit dem Neustarten
|
||||
eines Pods verwechselt werden. Ein Pod ist kein Prozess, sondern eine Umgebung
|
||||
zur Ausführung von Containern. Ein Pod bleibt bestehen bis er gelöscht wird.
|
||||
{{< /note >}}
|
||||
|
||||
Stelle beim Erstellen des Manifests für ein Pod-Objekt sicher, dass der
|
||||
angegebene Name ein gültiger
|
||||
[DNS-Subdomain-Name](/docs/concepts/overview/working-with-objects/names#dns-subdomain-names)
|
||||
ist.
|
||||
|
||||
### Pods und Controller
|
||||
|
||||
Mit Workload-Ressourcen kannst du mehrere Pods erstellen und verwalten. Ein
|
||||
Controller für die Ressource kümmert sich um Replikation, Roll-Out sowie
|
||||
automatische Wiederherstellung im Fall von versagenden Pods. Wenn beispielsweise ein Node
|
||||
ausfällt, bemerkt ein Controller, dass die Pods auf dem Node nicht mehr laufen
|
||||
und plant die Ausführung eines Ersatzpods auf einem funktionierenden Node.
|
||||
Hier sind einige Beispiele für Workload-Ressourcen, die einen oder mehrere Pods
|
||||
verwalten:
|
||||
|
||||
* {{< glossary_tooltip text="Deployment" term_id="deployment" >}}
|
||||
* {{< glossary_tooltip text="StatefulSet" term_id="statefulset" >}}
|
||||
* {{< glossary_tooltip text="DaemonSet" term_id="daemonset" >}}
|
||||
|
||||
### Pod Vorlagen
|
||||
|
||||
Controller für
|
||||
{{<glossary_tooltip text="Workload" term_id="workload">}}-Ressourcen
|
||||
erstellen Pods von einer _Pod Vorlage_ und verwalten diese Pods für dich.
|
||||
|
||||
Pod Vorlagen sind Spezifikationen zum Erstellen von Pods und sind in
|
||||
Workload-Ressourcen enthalten wie z. B.
|
||||
[Deployments](/docs/concepts/workloads/controllers/deployment/),
|
||||
[Jobs](/docs/concepts/workloads/controllers/job/), and
|
||||
[DaemonSets](/docs/concepts/workloads/controllers/daemonset/).
|
||||
|
||||
Jeder Controller für eine Workload-Ressource verwendet die Pod Vorlage innerhalb
|
||||
des Workload-Objektes, um Pods zu erzeugen. Die Pod Vorlage ist Teil des
|
||||
gewünschten Zustands der Workload-Ressource, mit der du deine Anwendung
|
||||
ausgeführt hast.
|
||||
|
||||
Das folgende Beispiel ist ein Manifest für einen einfachen Job mit einer
|
||||
`Vorlage`, die einen Container startet. Der Container in diesem Pod druckt
|
||||
eine Nachricht und pausiert dann.
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: hello
|
||||
spec:
|
||||
template:
|
||||
# Dies is the Pod Vorlage
|
||||
spec:
|
||||
containers:
|
||||
- name: hello
|
||||
image: busybox
|
||||
command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
|
||||
restartPolicy: OnFailure
|
||||
# Die Pod Vorlage endet hier
|
||||
```
|
||||
Das Ändern der Pod Vorlage oder der Wechsel zu einer neuen Pod Vorlage hat keine
|
||||
direkten Auswirkungen auf bereits existierende Pods. Wenn du die Pod Vorlage für
|
||||
eine Workload-Ressource änderst, dann muss diese Ressource die Ersatz-Pods
|
||||
erstellen, welche die aktualisierte Vorlage verwenden.
|
||||
|
||||
Beispielsweise stellt der StatefulSet-Controller sicher, dass für jedes
|
||||
StatefulSet-Objekt die ausgeführten Pods mit der aktueller Pod Vorlage
|
||||
übereinstimmen. Wenn du das StatefulSet bearbeitest und die Vorlage änderst,
|
||||
beginnt das StatefulSet mit der Erstellung neuer Pods basierend auf der
|
||||
aktualisierten Vorlage. Schließlich werden alle alten Pods durch neue Pods
|
||||
ersetzt, und das Update ist abgeschlossen.
|
||||
|
||||
Jede Workload-Ressource implementiert eigenen Regeln für die Umsetzung von
|
||||
Änderungen der Pod Vorlage. Wenn du mehr über StatefulSet erfahren möchtest,
|
||||
dann lese die Seite
|
||||
[Update-Strategien](/docs/tutorials/stateful-application/basic-stateful-set/#updating-statefulsets)
|
||||
im Tutorial StatefulSet Basics.
|
||||
|
||||
|
||||
Auf Nodes beobachtet oder verwaltet das
|
||||
{{< glossary_tooltip term_id="kubelet" text="Kubelet" >}}
|
||||
nicht direkt die Details zu Pod Vorlagen und Updates. Diese Details sind
|
||||
abstrahiert. Die Abstraktion und Trennung von Aufgaben vereinfacht die
|
||||
Systemsemantik und ermöglicht so das Verhalten des Clusters zu ändern ohne
|
||||
vorhandenen Code zu ändern.
|
||||
|
||||
## Pod Update und Austausch
|
||||
|
||||
Wie im vorherigen Abschnitt erwähnt, erstellt der Controller neue Pods basierend
|
||||
auf der aktualisierten Vorlage, wenn die Pod Vorlage für eine Workload-Ressource
|
||||
geändert wird anstatt die vorhandenen Pods zu aktualisieren oder zu patchen.
|
||||
|
||||
Kubernetes hindert dich nicht daran, Pods direkt zu verwalten. Es ist möglich,
|
||||
einige Felder eines laufenden Pods zu aktualisieren. Allerdings haben
|
||||
Pod-Aktualisierungsvorgänge wie zum Beispiel
|
||||
[`patch`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#patch-pod-v1-core),
|
||||
und
|
||||
[`replace`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#replace-pod-v1-core)
|
||||
einige Einschränkungen:
|
||||
|
||||
- Die meisten Metadaten zu einem Pod können nicht verändert werden. Zum Beispiel kannst
|
||||
du nicht die Felder `namespace`, `name`, `uid`, oder `creationTimestamp`
|
||||
ändern. Das `generation`-Feld muss eindeutig sein. Es werden nur Aktualisierungen
|
||||
akzeptiert, die den Wert des Feldes inkrementieren.
|
||||
- Wenn das Feld `metadata.deletionTimestamp` gesetzt ist, kann kein neuer
|
||||
Eintrag zur Liste `metadata.finalizers` hinzugefügt werden.
|
||||
- Pod-Updates dürfen keine Felder ändern, die Ausnahmen sind
|
||||
`spec.containers[*].image`,
|
||||
`spec.initContainers[*].image`,` spec.activeDeadlineSeconds` oder
|
||||
`spec.tolerations`. Für `spec.tolerations` kannnst du nur neue Einträge
|
||||
hinzufügen.
|
||||
- Für `spec.activeDeadlineSeconds` sind nur zwei Änderungen erlaubt:
|
||||
|
||||
1. ungesetztes Feld in eine positive Zahl
|
||||
1. positive Zahl in eine kleinere positive Zahl, die nicht negativ ist
|
||||
|
||||
## Gemeinsame Nutzung von Ressourcen und Kommunikation
|
||||
|
||||
Pods ermöglichen den Datenaustausch und die Kommunikation zwischen den
|
||||
Containern, die im Pod enthalten sind.
|
||||
|
||||
### Datenspeicherung in Pods
|
||||
|
||||
Ein Pod kann eine Reihe von gemeinsam genutzten Speicher-
|
||||
{{<glossary_tooltip text="Volumes" term_id="volume">}} spezifizieren. Alle
|
||||
Container im Pod können auf die gemeinsamen Volumes zugreifen und dadurch Daten
|
||||
austauschen. Volumes ermöglichen auch, dass Daten ohne Verlust gespeichert
|
||||
werden, falls einer der Container neu gestartet werden muss.
|
||||
Im Kapitel [Datenspeicherung](/docs/concepts/storage/) findest du weitere
|
||||
Informationen, wie Kubernetes gemeinsam genutzten Speicher implementiert und
|
||||
Pods zur Verfügung stellt.
|
||||
|
||||
### Pod-Netzwerk
|
||||
|
||||
Jedem Pod wird für jede Adressenfamilie eine eindeutige IP-Adresse zugewiesen.
|
||||
Jeder Container in einem Pod nutzt den gemeinsamen Netzwerk-Namespace,
|
||||
einschließlich der IP-Adresse und der Ports. In einem Pod (und **nur** dann)
|
||||
können die Container, die zum Pod gehören, über `localhost` miteinander
|
||||
kommunizieren. Wenn Container in einem Pod mit Entitäten *außerhalb des Pods*
|
||||
kommunizieren, müssen sie koordinieren, wie die gemeinsam genutzten
|
||||
Netzwerkressourcen (z. B. Ports) verwenden werden. Innerhalb eines Pods teilen
|
||||
sich Container eine IP-Adresse und eine Reihe von Ports und können sich
|
||||
gegenseitig über `localhost` finden. Die Container in einem Pod können auch die
|
||||
üblichen Kommunikationsverfahren zwischen Prozessen nutzen, wie z. B.
|
||||
SystemV-Semaphoren oder "POSIX Shared Memory". Container in verschiedenen Pods
|
||||
haben unterschiedliche IP-Adressen und können nicht per IPC ohne
|
||||
[spezielle Konfiguration](/docs/concepts/policy/pod-security-policy/)
|
||||
kommunizieren. Container, die mit einem Container in einem anderen Pod
|
||||
interagieren möchten, müssen IP Netzwerke verwenden.
|
||||
|
||||
Für die Container innerhalb eines Pods stimmt der "hostname" mit dem
|
||||
konfigurierten `Namen` des Pods überein. Mehr dazu im Kapitel
|
||||
[Netzwerke](/docs/concepts/cluster-administration/networking/).
|
||||
|
||||
## Privilegierter Modus für Container
|
||||
|
||||
Jeder Container in einem Pod kann den privilegierten Modus aktivieren, indem
|
||||
das Flag `privileged` im
|
||||
[Sicherheitskontext](/docs/tasks/configure-pod-container/security-context/)
|
||||
der Container-Spezifikation verwendet wird.
|
||||
Dies ist nützlich für Container, die Verwaltungsfunktionen des Betriebssystems
|
||||
verwenden möchten, z. B. das Manipulieren des Netzwerk-Stacks oder den Zugriff
|
||||
auf Hardware. Prozesse innerhalb eines privilegierten Containers erhalten fast
|
||||
die gleichen Rechte wie sie Prozessen außerhalb eines Containers zur Verfügung
|
||||
stehen.
|
||||
|
||||
{{< note >}}
|
||||
Ihre
|
||||
{{<glossary_tooltip text="Container-Umgebung" term_id="container-runtime">}}
|
||||
muss das Konzept eines privilegierten Containers unterstützen, damit diese
|
||||
Einstellung relevant ist.
|
||||
{{< /note >}}
|
||||
|
||||
|
||||
## Statische Pods
|
||||
|
||||
_Statische Pods_ werden direkt vom Kubelet-Daemon auf einem bestimmten Node
|
||||
verwaltet ohne dass sie vom
|
||||
{{<glossary_tooltip text="API Server" term_id="kube-apiserver">}} überwacht
|
||||
werden.
|
||||
|
||||
Die meisten Pods werden von der Kontrollebene verwaltet (z. B.
|
||||
{{< glossary_tooltip text="Deployment" term_id="deployment" >}}). Aber für
|
||||
statische Pods überwacht das Kubelet jeden statischen Pod direkt (und startet
|
||||
ihn neu, wenn er ausfällt).
|
||||
|
||||
Statische Pods sind immer an ein {{<glossary_tooltip term_id="kubelet">}} auf
|
||||
einem bestimmten Node gebunden. Der Hauptanwendungsfall für statische Pods
|
||||
besteht darin, eine selbst gehostete Steuerebene auszuführen. Mit anderen
|
||||
Worten: Das Kubelet dient zur Überwachung der einzelnen
|
||||
[Komponenten der Kontrollebene](/docs/concepts/overview/components/#control-plane-components).
|
||||
|
||||
Das Kubelet versucht automatisch auf dem Kubernetes API-Server für jeden
|
||||
statischen Pod einen spiegelbildlichen Pod
|
||||
(im Englischen: {{<glossary_tooltip text="mirror pod" term_id="mirror-pod">}})
|
||||
zu erstellen.
|
||||
Das bedeutet, dass die auf einem Node ausgeführten Pods auf dem API-Server
|
||||
sichtbar sind jedoch von dort nicht gesteuert werden können.
|
||||
|
||||
## {{% heading "whatsnext" %}}
|
||||
|
||||
* Verstehe den
|
||||
[Lebenszyklus eines Pods](/docs/concepts/workloads/pods/pod-lifecycle/).
|
||||
* Erfahre mehr über [RuntimeClass](/docs/concepts/containers/runtime-class/)
|
||||
und wie du damit verschiedene Pods mit unterschiedlichen
|
||||
Container-Laufzeitumgebungen konfigurieren kannst.
|
||||
* Mehr zum Thema
|
||||
[Restriktionen für die Verteilung von Pods](/docs/concepts/workloads/pods/pod-topology-spread-constraints/).
|
||||
* Lese
|
||||
[Pod-Disruption-Budget](/docs/concepts/workloads/pods/disruptions/)
|
||||
und wie du es verwenden kannst, um die Verfügbarkeit von Anwendungen bei
|
||||
Störungen zu verwalten. Die
|
||||
[Pod](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core)
|
||||
-Objektdefinition beschreibt das Objekt im Detail.
|
||||
* [The Distributed System Toolkit: Patterns for Composite Containers](https://kubernetes.io/blog/2015/06/the-distributed-system-toolkit-patterns)
|
||||
erläutert allgemeine Layouts für Pods mit mehr als einem Container.
|
||||
|
||||
Um den Hintergrund zu verstehen, warum Kubernetes eine gemeinsame Pod-API in
|
||||
andere Ressourcen, wie z. B.
|
||||
{{< glossary_tooltip text="StatefulSets" term_id="statefulset" >}}
|
||||
oder {{< glossary_tooltip text="Deployments" term_id="deployment" >}} einbindet,
|
||||
kannst du Artikel zu früheren Technologien lesen, unter anderem:
|
||||
* [Aurora](https://aurora.apache.org/documentation/latest/reference/configuration/#job-schema)
|
||||
* [Borg](https://research.google.com/pubs/pub43438.html)
|
||||
* [Marathon](https://mesosphere.github.io/marathon/docs/rest-api.html)
|
||||
* [Omega](https://research.google/pubs/pub41684/)
|
||||
* [Tupperware](https://engineering.fb.com/data-center-engineering/tupperware/).
|
||||
@@ -43,12 +43,12 @@ Kubernetes is open source giving you the freedom to take advantage of on-premise
|
||||
<button id="desktopShowVideoButton" onclick="kub.showVideo()">Watch Video</button>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/?utm_source=kubernetes.io&utm_medium=nav&utm_campaign=kccncna20" button id="desktopKCButton">Attend KubeCon NA virtually on November 17-20, 2020</a>
|
||||
<a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/?utm_source=kubernetes.io&utm_medium=nav&utm_campaign=kccncna21" button id="desktopKCButton">Attend KubeCon North America on October 11-15, 2021</a>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<br>
|
||||
<a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/?utm_source=kubernetes.io&utm_medium=nav&utm_campaign=kccnceu21" button id="desktopKCButton">Attend KubeCon EU virtually on May 4 – 7, 2021</a>
|
||||
<a href="https://events.linuxfoundation.org/kubecon-cloudnativecon-europe-2022/?utm_source=kubernetes.io&utm_medium=nav&utm_campaign=kccnceu22" button id="desktopKCButton">Attend KubeCon Europe on May 17-20, 2022</a>
|
||||
</div>
|
||||
<div id="videoPlayer">
|
||||
<iframe data-url="https://www.youtube.com/embed/H06qrNmGqyE?autoplay=1" frameborder="0" allowfullscreen></iframe>
|
||||
@@ -58,4 +58,4 @@ Kubernetes is open source giving you the freedom to take advantage of on-premise
|
||||
|
||||
{{< blocks/kubernetes-features >}}
|
||||
|
||||
{{< blocks/case-studies >}}
|
||||
{{< blocks/case-studies >}}
|
||||
|
||||
@@ -95,7 +95,7 @@ The core workloads API surface is stable, but it’s still software, and softwar
|
||||
--Kenneth Owens, Software Engineer, Google
|
||||
|
||||
|
||||
- [Download](http://get.k8s.io/) Kubernetes
|
||||
- [Download](https://get.k8s.io/) Kubernetes
|
||||
- Get involved with the Kubernetes project on [GitHub](https://github.com/kubernetes/kubernetes)
|
||||
- Post questions (or answer questions) on [Stack Overflow](http://stackoverflow.com/questions/tagged/kubernetes)
|
||||
- Connect with the community on [Slack](http://slack.k8s.io/)
|
||||
|
||||
@@ -140,7 +140,7 @@ The local persistent volume beta feature is not complete by far. Some notable en
|
||||
|
||||
## Complementary features
|
||||
|
||||
[Pod priority and preemption](/docs/concepts/configuration/pod-priority-preemption/) is another Kubernetes feature that is complementary to local persistent volumes. When your application uses local storage, it must be scheduled to the specific node where the local volume resides. You can give your local storage workload high priority so if that node ran out of room to run your workload, Kubernetes can preempt lower priority workloads to make room for it.
|
||||
[Pod priority and preemption](/docs/concepts/scheduling-eviction/pod-priority-preemption/) is another Kubernetes feature that is complementary to local persistent volumes. When your application uses local storage, it must be scheduled to the specific node where the local volume resides. You can give your local storage workload high priority so if that node ran out of room to run your workload, Kubernetes can preempt lower priority workloads to make room for it.
|
||||
|
||||
[Pod disruption budget](/docs/concepts/workloads/pods/disruptions/) is also very important for those workloads that must maintain quorum. Setting a disruption budget for your workload ensures that it does not drop below quorum due to voluntary disruption events, such as node drains during upgrade.
|
||||
|
||||
|
||||
@@ -94,7 +94,7 @@ JOSH BERKUS: That goes into release notes. I mean, keep in mind that one of the
|
||||
|
||||
However, stuff happens, and we do occasionally have to do those. And so far, our main way to identify that to people actually is in the release notes. If you look at [the current release notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG-1.11.md#no-really-you-must-do-this-before-you-upgrade), there are actually two things in there right now that are sort of breaking changes.
|
||||
|
||||
One of them is the bit with [priority and preemption](/docs/concepts/configuration/pod-priority-preemption/) in that preemption being on by default now allows badly behaved users of the system to cause trouble in new ways. I'd actually have to look at the release notes to see what the second one was...
|
||||
One of them is the bit with [priority and preemption](/docs/concepts/scheduling-eviction/pod-priority-preemption/) in that preemption being on by default now allows badly behaved users of the system to cause trouble in new ways. I'd actually have to look at the release notes to see what the second one was...
|
||||
|
||||
TIM PEPPER: The [JSON capitalization case sensitivity](https://github.com/kubernetes/kubernetes/issues/64612).
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ Master and Worker nodes should be protected from overload and resource exhaustio
|
||||
|
||||
Resource consumption by the control plane will correlate with the number of pods and the pod churn rate. Very large and very small clusters will benefit from non-default [settings](/docs/reference/command-line-tools-reference/kube-apiserver/) of kube-apiserver request throttling and memory. Having these too high can lead to request limit exceeded and out of memory errors.
|
||||
|
||||
On worker nodes, [Node Allocatable](/docs/tasks/administer-cluster/reserve-compute-resources/) should be configured based on a reasonable supportable workload density at each node. Namespaces can be created to subdivide the worker node cluster into multiple virtual clusters with resource CPU and memory [quotas](/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/). Kubelet handling of [out of resource](/docs/tasks/administer-cluster/out-of-resource/) conditions can be configured.
|
||||
On worker nodes, [Node Allocatable](/docs/tasks/administer-cluster/reserve-compute-resources/) should be configured based on a reasonable supportable workload density at each node. Namespaces can be created to subdivide the worker node cluster into multiple virtual clusters with resource CPU and memory [quotas](/docs/tasks/administer-cluster/manage-resources/memory-default-namespace/). Kubelet handling of [out of resource](/docs/concepts/scheduling-eviction/node-pressure-eviction/) conditions can be configured.
|
||||
|
||||
## Security
|
||||
|
||||
@@ -166,7 +166,7 @@ Some critical state is held outside etcd. Certificates, container images, and ot
|
||||
* Cloud provider specific account and configuration data
|
||||
|
||||
## Considerations for your production workloads
|
||||
Anti-affinity specifications can be used to split clustered services across backing hosts, but at this time the settings are used only when the pod is scheduled. This means that Kubernetes can restart a failed node of your clustered application, but does not have a native mechanism to rebalance after a fail back. This is a topic worthy of a separate blog, but supplemental logic might be useful to achieve optimal workload placements after host or worker node recoveries or expansions. The [Pod Priority and Preemption feature](/docs/concepts/configuration/pod-priority-preemption/) can be used to specify a preferred triage in the event of resource shortages caused by failures or bursting workloads.
|
||||
Anti-affinity specifications can be used to split clustered services across backing hosts, but at this time the settings are used only when the pod is scheduled. This means that Kubernetes can restart a failed node of your clustered application, but does not have a native mechanism to rebalance after a fail back. This is a topic worthy of a separate blog, but supplemental logic might be useful to achieve optimal workload placements after host or worker node recoveries or expansions. The [Pod Priority and Preemption feature](/docs/concepts/scheduling-eviction/pod-priority-preemption/) can be used to specify a preferred triage in the event of resource shortages caused by failures or bursting workloads.
|
||||
|
||||
For stateful services, external attached volume mounts are the standard Kubernetes recommendation for a non-clustered service (e.g., a typical SQL database). At this time Kubernetes managed snapshots of these external volumes is in the category of a [roadmap feature request](https://docs.google.com/presentation/d/1dgxfnroRAu0aF67s-_bmeWpkM1h2LCxe6lB1l1oS0EQ/edit#slide=id.g3ca07c98c2_0_47), likely to align with the Container Storage Interface (CSI) integration. Thus performing backups of such a service would involve application specific, in-pod activity that is beyond the scope of this document. While awaiting better Kubernetes support for a snapshot and backup workflow, running your database service in a VM rather than a container, and exposing it to your Kubernetes workload may be worth considering.
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ date: 2019-04-16
|
||||
|
||||
Kubernetes is well-known for running scalable workloads. It scales your workloads based on their resource usage. When a workload is scaled up, more instances of the application get created. When the application is critical for your product, you want to make sure that these new instances are scheduled even when your cluster is under resource pressure. One obvious solution to this problem is to over-provision your cluster resources to have some amount of slack resources available for scale-up situations. This approach often works, but costs more as you would have to pay for the resources that are idle most of the time.
|
||||
|
||||
[Pod priority and preemption](https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/) is a scheduler feature made generally available in Kubernetes 1.14 that allows you to achieve high levels of scheduling confidence for your critical workloads without overprovisioning your clusters. It also provides a way to improve resource utilization in your clusters without sacrificing the reliability of your essential workloads.
|
||||
[Pod priority and preemption](/docs/concepts/scheduling-eviction/pod-priority-preemption/) is a scheduler feature made generally available in Kubernetes 1.14 that allows you to achieve high levels of scheduling confidence for your critical workloads without overprovisioning your clusters. It also provides a way to improve resource utilization in your clusters without sacrificing the reliability of your essential workloads.
|
||||
|
||||
## Guaranteed scheduling with controlled cost
|
||||
|
||||
|
||||
@@ -120,7 +120,7 @@ Run the following command to have Docker run the application in a container and
|
||||
```
|
||||
docker run -p 5001:5000 hello-python
|
||||
```
|
||||
Now navigate to http://localhost:5001, and you should see the “Hello form Python!” message.
|
||||
Now navigate to http://localhost:5001, and you should see the “Hello from Python!” message.
|
||||
|
||||
### More info
|
||||
* [Get started with Docker](https://docs.docker.com/get-started/)
|
||||
@@ -201,7 +201,7 @@ kubectl get pods
|
||||
```
|
||||
<img src="/images/blog/get-started-with-kubernetes-using-python/kubectl-get-pods.png" alt="Pod listing" />
|
||||
|
||||
Now navigate to http://localhost:6000, and you should see the “Hello form Python!” message.
|
||||
Now navigate to http://localhost:6000, and you should see the “Hello from Python!” message.
|
||||
|
||||
That’s it! The application is now running in Kubernetes!
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ Take maven project as example, adding the following dependencies into your depen
|
||||
|
||||
Then we can make use of the provided builder libraries to write your own controller.
|
||||
For example, the following one is a simple controller prints out node information
|
||||
on watch notification, see complete example [here](https://github.com/kubernetes-client/java/blob/master/examples/src/main/java/io/kubernetes/client/examples/ControllerExample.java):
|
||||
on watch notification, see complete example [here](https://github.com/kubernetes-client/java/blob/master/examples/examples-release-13/src/main/java/io/kubernetes/client/examples/ControllerExample.java):
|
||||
|
||||
```java
|
||||
...
|
||||
|
||||
@@ -31,9 +31,9 @@ Standard labels are used by Kubernetes components to support some features. For
|
||||
|
||||
The labels are reaching general availability in this release. Kubernetes components have been updated to populate the GA and beta labels and to react to both. However, if you are using the beta labels in your pod specs for features such as node affinity, or in your custom controllers, we recommend that you start migrating them to the new GA labels. You can find the documentation for the new labels here:
|
||||
|
||||
- [node.kubernetes.io/instance-type](https://kubernetes.io/docs/reference/kubernetes-api/labels-annotations-taints/#nodekubernetesioinstance-type)
|
||||
- [topology.kubernetes.io/region](https://kubernetes.io/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesioregion)
|
||||
- [topology.kubernetes.io/zone](https://kubernetes.io/docs/reference/kubernetes-api/labels-annotations-taints/#topologykubernetesiozone)
|
||||
- [node.kubernetes.io/instance-type](/docs/reference/labels-annotations-taints/#nodekubernetesioinstance-type)
|
||||
- [topology.kubernetes.io/region](/docs/reference/labels-annotations-taints/#topologykubernetesioregion)
|
||||
- [topology.kubernetes.io/zone](/docs/reference/labels-annotations-taints/#topologykubernetesiozone)
|
||||
|
||||
## Volume Snapshot Moves to Beta
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ The team has made progress in the last few months that is well worth celebrating
|
||||
|
||||
- The K8s-Infrastructure Working Group released an automated billing report that they start every meeting off by reviewing as a group.
|
||||
- DNS for k8s.io and kubernetes.io are also fully [community-owned](https://groups.google.com/g/kubernetes-dev/c/LZTYJorGh7c/m/u-ydk-yNEgAJ), with community members able to [file issues](https://github.com/kubernetes/k8s.io/issues/new?assignees=&labels=wg%2Fk8s-infra&template=dns-request.md&title=DNS+REQUEST%3A+%3Cyour-dns-record%3E) to manage records.
|
||||
- The container registry [k8s.gcr.io](https://github.com/kubernetes/k8s.io/tree/master/k8s.gcr.io) is also fully community-owned and available for all Kubernetes subprojects to use.
|
||||
- The container registry [k8s.gcr.io](https://github.com/kubernetes/k8s.io/tree/main/k8s.gcr.io) is also fully community-owned and available for all Kubernetes subprojects to use.
|
||||
- The Kubernetes [publishing-bot](https://github.com/kubernetes/publishing-bot) responsible for keeping k8s.io/kubernetes/staging repositories published to their own top-level repos (For example: [kubernetes/api](https://github.com/kubernetes/api)) runs on a community-owned cluster.
|
||||
- The gcsweb.k8s.io service used to provide anonymous access to GCS buckets for kubernetes artifacts runs on a community-owned cluster.
|
||||
- There is also an automated process of promoting all our container images. This includes a fully documented infrastructure, managed by the Kubernetes community, with automated processes for provisioning permissions.
|
||||
|
||||
@@ -325,7 +325,7 @@ Now that we have a way to communicate helpful information to users in context,
|
||||
we're already considering other ways we can use this to improve people's experience with Kubernetes.
|
||||
A couple areas we're looking at next are warning about [known problematic values](http://issue.k8s.io/64841#issuecomment-395141013)
|
||||
we cannot reject outright for compatibility reasons, and warning about use of deprecated fields or field values
|
||||
(like selectors using beta os/arch node labels, [deprecated in v1.14](/docs/reference/kubernetes-api/labels-annotations-taints/#beta-kubernetes-io-arch-deprecated)).
|
||||
(like selectors using beta os/arch node labels, [deprecated in v1.14](/docs/reference/labels-annotations-taints/#beta-kubernetes-io-arch-deprecated)).
|
||||
I'm excited to see progress in this area, continuing to make it easier to use Kubernetes.
|
||||
|
||||
---
|
||||
|
||||
@@ -47,6 +47,15 @@ and other ecosystem groups to ensure a smooth transition and will evaluate thing
|
||||
as the situation evolves.
|
||||
|
||||
|
||||
### Can I still use dockershim after it is removed from Kubernetes?
|
||||
|
||||
Update:
|
||||
Mirantis and Docker have [committed][mirantis] to maintaining the dockershim after
|
||||
it is removed from Kubernetes.
|
||||
|
||||
[mirantis]: https://www.mirantis.com/blog/mirantis-to-take-over-support-of-kubernetes-dockershim-2/
|
||||
|
||||
|
||||
### Will my existing Docker images still work?
|
||||
|
||||
Yes, the images produced from `docker build` will work with all CRI implementations.
|
||||
@@ -178,4 +187,3 @@ discussion of the changes.
|
||||
|
||||
Always and whenever you want! 🤗🤗
|
||||
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ The Kubernetes community has written a [detailed blog post about deprecation](ht
|
||||
|
||||
A longstanding bug regarding exec probe timeouts that may impact existing pod definitions has been fixed. Prior to this fix, the field `timeoutSeconds` was not respected for exec probes. Instead, probes would run indefinitely, even past their configured deadline, until a result was returned. With this change, the default value of `1 second` will be applied if a value is not specified and existing pod definitions may no longer be sufficient if a probe takes longer than one second. A feature gate, called `ExecProbeTimeout`, has been added with this fix that enables cluster operators to revert to the previous behavior, but this will be locked and removed in subsequent releases. In order to revert to the previous behavior, cluster operators should set this feature gate to `false`.
|
||||
|
||||
Please review the updated documentation regarding [configuring probes](docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes) for more details.
|
||||
Please review the updated documentation regarding [configuring probes](/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/#configure-probes) for more details.
|
||||
|
||||
## Other Updates
|
||||
|
||||
|
||||
|
After Width: | Height: | Size: 53 KiB |
@@ -0,0 +1,105 @@
|
||||
---
|
||||
layout: blog
|
||||
title: 'Kubernetes 1.21: CronJob Reaches GA'
|
||||
date: 2021-04-09
|
||||
slug: kubernetes-release-1.21-cronjob-ga
|
||||
---
|
||||
|
||||
**Authors:** Alay Patel (Red Hat), and Maciej Szulik (Red Hat)
|
||||
|
||||
In Kubernetes v1.21, the
|
||||
[CronJob](/docs/concepts/workloads/controllers/cron-jobs/) resource
|
||||
reached general availability (GA). We've also substantially improved the
|
||||
performance of CronJobs since Kubernetes v1.19, by implementing a new
|
||||
controller.
|
||||
|
||||
In Kubernetes v1.20 we launched a revised v2 controller for CronJobs,
|
||||
initially as an alpha feature. Kubernetes 1.21 uses the newer controller by
|
||||
default, and the CronJob resource itself is now GA (group version: `batch/v1`).
|
||||
|
||||
In this article, we'll take you through the driving forces behind this new
|
||||
development, give you a brief description of controller design for core
|
||||
Kubernetes, and we'll outline what you will gain from this improved controller.
|
||||
|
||||
The driving force behind promoting the API was Kubernetes' policy choice to
|
||||
[ensure APIs move beyond beta](/blog/2020/08/21/moving-forward-from-beta/).
|
||||
That policy aims to prevent APIs from being stuck in a “permanent beta” state.
|
||||
Over the years the old CronJob controller implementation had received healthy
|
||||
feedback from the community, with reports of several widely recognized
|
||||
[issues](https://github.com/kubernetes/kubernetes/issues/82659).
|
||||
|
||||
If the beta API for CronJob was to be supported as GA, the existing controller
|
||||
code would need substantial rework. Instead, the SIG Apps community decided
|
||||
to introduce a new controller and gradually replace the old one.
|
||||
|
||||
## How do controllers work?
|
||||
|
||||
Kubernetes [controllers](/docs/concepts/architecture/controller/) are control
|
||||
loops that watch the state of resource(s) in your cluster, then make or
|
||||
request changes where needed. Each controller tries to move part of the
|
||||
current cluster state closer to the desired state.
|
||||
|
||||
The v1 CronJob controller works by performing a periodic poll and sweep of all
|
||||
the CronJob objects in your cluster, in order to act on them. It is a single
|
||||
worker implementation that gets all CronJobs every 10 seconds, iterates over
|
||||
each one of them, and syncs them to their desired state. This was the default
|
||||
way of doing things almost 5 years ago when the controller was initially
|
||||
written. In hindsight, we can certainly say that such an approach can
|
||||
overload the API server at scale.
|
||||
|
||||
These days, every core controller in kubernetes must follow the guidelines
|
||||
described in [Writing Controllers](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/controllers.md#readme).
|
||||
Among many details, that document prescribes using
|
||||
[shared informers](https://www.cncf.io/blog/2019/10/15/extend-kubernetes-via-a-shared-informer/)
|
||||
to “receive notifications of adds, updates, and deletes for a particular
|
||||
resource”. Upon any such events, the related object(s) is placed in a queue.
|
||||
Workers pull items from the queue and process them one at a time. This
|
||||
approach ensures consistency and scalability.
|
||||
|
||||
The picture below shows the flow of information from kubernetes API server,
|
||||
through shared informers and queue, to the main part of a controller - a
|
||||
reconciliation loop which is responsible for performing the core functionality.
|
||||
|
||||

|
||||
|
||||
The CronJob controller V2 uses a queue that implements the DelayingInterface to
|
||||
handle the scheduling aspect. This queue allows processing an element after a
|
||||
specific time interval. Every time there is a change in a CronJob or its related
|
||||
Jobs, the key that represents the CronJob is pushed to the queue. The main
|
||||
handler pops the key, processes the CronJob, and after completion
|
||||
pushes the key back into the queue for the next scheduled time interval. This is
|
||||
immediately a more performant implementation, as it no longer requires a linear
|
||||
scan of all the CronJobs. On top of that, this controller can be scaled by
|
||||
increasing the number of workers processing the CronJobs in parallel.
|
||||
|
||||
## Performance impact of the new controller {#performance-impact}
|
||||
|
||||
In order to test the performance difference of the two controllers a VM instance
|
||||
with 128 GiB RAM and 64 vCPUs was used to set up a single node Kubernetes cluster.
|
||||
Initially, a sample workload was created with 20 CronJob instances with a schedule
|
||||
to run every minute, and 2100 CronJobs running every 20 hours. Additionally,
|
||||
over the next few minutes we added 1000 CronJobs with a schedule to run every
|
||||
20 hours, until we reached a total of 5120 CronJobs.
|
||||
|
||||

|
||||
|
||||
We observed that for every 1000 CronJobs added, the old controller used
|
||||
around 90 to 120 seconds more wall-clock time to schedule 20 Jobs every cycle.
|
||||
That is, at 5120 CronJobs, the old controller took approximately 9 minutes
|
||||
to create 20 Jobs. Hence, during each cycle, about 8 schedules were missed.
|
||||
The new controller, implemented with architectural change explained above,
|
||||
created 20 Jobs without any delay, even when we created an additional batch
|
||||
of 1000 CronJobs reaching a total of 6120.
|
||||
|
||||
As a closing remark, the new controller exposes a histogram metric
|
||||
`cronjob_controller_cronjob_job_creation_skew_duration_seconds` which helps
|
||||
monitor the time difference between when a CronJob is meant to run and when
|
||||
the actual Job is created.
|
||||
|
||||
Hopefully the above description is a sufficient argument to follow the
|
||||
guidelines and standards set in the Kubernetes project, even for your own
|
||||
controllers. As mentioned before, the new controller is on by default starting
|
||||
from Kubernetes v1.21; if you want to check it out in the previous release (1.20),
|
||||
you can enable the `CronJobControllerV2`
|
||||
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
for the kube-controller-manager: `--feature-gate="CronJobControllerV2=true"`.
|
||||
|
After Width: | Height: | Size: 104 KiB |
@@ -0,0 +1,128 @@
|
||||
---
|
||||
layout: blog
|
||||
title: 'Kubernetes 1.21: Power to the Community'
|
||||
date: 2021-04-08
|
||||
slug: kubernetes-1-21-release-announcement
|
||||
---
|
||||
|
||||
**Authors:** [Kubernetes 1.21 Release Team](https://github.com/kubernetes/sig-release/blob/master/releases/release-1.21/release-team.md)
|
||||
|
||||
We’re pleased to announce the release of Kubernetes 1.21, our first release of 2021! This release consists of 51 enhancements: 13 enhancements have graduated to stable, 16 enhancements are moving to beta, 20 enhancements are entering alpha, and 2 features have been deprecated.
|
||||
|
||||
This release cycle, we saw a major shift in ownership of processes around the release team. We moved from a synchronous mode of communication, where we periodically asked the community for inputs, to a mode where the community opts-in to contribute features and/or blogs to the release. These changes have resulted in an increase in collaboration and teamwork across the community. The result of all that is reflected in Kubernetes 1.21 having the most number of features in the recent times.
|
||||
|
||||
## Major Themes
|
||||
|
||||
### CronJobs Graduate to Stable!
|
||||
[CronJobs](/docs/concepts/workloads/controllers/cron-jobs/) (previously ScheduledJobs) has been a beta feature since Kubernetes 1.8! With 1.21 we get to finally see this widely used API graduate to stable.
|
||||
|
||||
CronJobs are meant for performing regular scheduled actions such as backups, report generation, and so on. Each of those tasks should be configured to recur indefinitely (for example: once a day / week / month); you can define the point in time within that interval when the job should start.
|
||||
|
||||
### Immutable Secrets and ConfigMaps
|
||||
[Immutable Secrets](/docs/concepts/configuration/secret/#secret-immutable) and [ConfigMaps](/docs/concepts/configuration/configmap/#configmap-immutable) add a new field to those resource types that will reject changes to those objects if set. Secrets and ConfigMaps by default are mutable which is beneficial for pods that are able to consume changes. Mutating Secrets and ConfigMaps can also cause problems if a bad configuration is pushed for pods that use them.
|
||||
|
||||
By marking Secrets and ConfigMaps as immutable you can be sure your application configuration won't change. If you want to make changes you'll need to create a new, uniquly named Secret or ConfigMap and deploy a new pod to consume that resource. Immutable resources also have scaling benefits because controllers do not need to poll the API server to watch for changes.
|
||||
|
||||
This feature has graduated to stable in Kubernetes 1.21.
|
||||
|
||||
### IPv4/IPv6 dual-stack support
|
||||
IP addresses are a consumable resource that cluster operators and administrators need to make sure are not exhausted. In particular, public IPv4 addresses are now scarce. Having dual-stack support enables native IPv6 routing to pods and services, whilst still allowing your cluster to talk IPv4 where needed. Dual-stack cluster networking also improves a possible scaling limitation for workloads.
|
||||
|
||||
Dual-stack support in Kubernetes means that pods, services, and nodes can get IPv4 addresses and IPv6 addresses. In Kubernetes 1.21 [dual-stack networking](/docs/concepts/services-networking/dual-stack/) has graduated from alpha to beta, and is now enabled by default.
|
||||
|
||||
### Graceful Node Shutdown
|
||||
[Graceful Node shutdown](/docs/concepts/architecture/nodes/#graceful-node-shutdown) also graduated to beta with this release (and will now be available to a much larger group of users)! This is a hugely beneficial feature that allows the kubelet to be aware of node shutdown, and gracefully terminate pods that are scheduled to that node.
|
||||
|
||||
Currently, when a node shuts down, pods do not follow the expected termination lifecycle and are not shut down gracefully. This can introduce problems with a lot of different workloads. Going forward, the kubelet will be able to detect imminent system shutdown through systemd, then inform running pods so they can terminate as gracefully as possible.
|
||||
|
||||
### PersistentVolume Health Monitor
|
||||
Persistent Volumes (PV) are commonly used in applications to get local, file-based storage. They can be used in many different ways and help users migrate applications without needing to re-write storage backends.
|
||||
|
||||
Kubernetes 1.21 has a new alpha feature which allows PVs to be monitored for health of the volume and marked accordingly if the volume becomes unhealthy. Workloads will be able to react to the health state to protect data from being written or read from a volume that is unhealthy.
|
||||
|
||||
### Reducing Kubernetes Build Maintenance
|
||||
Previously Kubernetes has maintained multiple build systems. This has often been a source of friction and complexity for new and current contributors.
|
||||
|
||||
Over the last release cycle, a lot of work has been put in to simplify the build process, and standardize on the native Golang build tools. This should empower broader community maintenance, and lower the barrier to entry for new contributors.
|
||||
|
||||
## Major Changes
|
||||
|
||||
### PodSecurityPolicy Deprecation
|
||||
In Kubernetes 1.21, PodSecurityPolicy is deprecated. As with all Kubernetes feature deprecations, PodSecurityPolicy will continue to be available and fully-functional for several more releases. PodSecurityPolicy, previously in the beta stage, is planned for removal in Kubernetes 1.25.
|
||||
|
||||
What's next? We're developing a new built-in mechanism to help limit Pod privileges, with a working title of “PSP Replacement Policy.” Our plan is for this new mechanism to cover the key PodSecurityPolicy use cases, with greatly improved ergonomics and maintainability. To learn more, read [PodSecurityPolicy Deprecation: Past, Present, and Future](/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future).
|
||||
|
||||
### TopologyKeys Deprecation
|
||||
The Service field `topologyKeys` is now deprecated; all the component features that used this field were previously alpha, and are now also deprecated.
|
||||
We've replaced `topologyKeys` with a way to implement topology-aware routing, called topology-aware hints. Topology-aware hints are an alpha feature in Kubernetes 1.21. You can read more details about the replacement feature in [Topology Aware Hints](/docs/concepts/services-networking/service-topology/); the related [KEP](https://github.com/kubernetes/enhancements/blob/master/keps/sig-network/2433-topology-aware-hints/README.md) explains the context for why we switched.
|
||||
|
||||
## Other Updates
|
||||
|
||||
### Graduated to Stable
|
||||
|
||||
* [EndpointSlice](https://github.com/kubernetes/enhancements/issues/752)
|
||||
* [Add sysctl support](https://github.com/kubernetes/enhancements/issues/34)
|
||||
* [PodDisruptionBudgets](https://github.com/kubernetes/enhancements/issues/85)
|
||||
|
||||
### Notable Feature Updates
|
||||
|
||||
* [External client-go credential providers](https://github.com/kubernetes/enhancements/issues/541) - beta in 1.21
|
||||
* [Structured logging](https://github.com/kubernetes/enhancements/issues/1602) - graduating to beta in 1.22
|
||||
* [TTL after finish cleanup for Jobs and Pods](https://github.com/kubernetes/enhancements/issues/592) - graduated to beta
|
||||
|
||||
# Release notes
|
||||
|
||||
You can check out the full details of the 1.21 release in the [release notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.21.md).
|
||||
|
||||
# Availability of release
|
||||
|
||||
Kubernetes 1.21 is available for [download on GitHub](https://github.com/kubernetes/kubernetes/releases/tag/v1.21.0). There are some great resources out there for getting started with Kubernetes. You can check out some [interactive tutorials](https://kubernetes.io/docs/tutorials/) on the main Kubernetes site, or run a local cluster on your machine using Docker containers with [kind](https://kind.sigs.k8s.io). If you’d like to try building a cluster from scratch, check out the [Kubernetes the Hard Way](https://github.com/kelseyhightower/kubernetes-the-hard-way) tutorial by Kelsey Hightower.
|
||||
|
||||
# Release Team
|
||||
|
||||
This release was made possible by a very dedicated group of individuals, who came together as a team in the midst of a lot of things happening out in the world. A huge thank you to the release lead Nabarun Pal, and to everyone else on the release team for supporting each other, and working so hard to deliver the 1.21 release for the community.
|
||||
|
||||
# Release Logo
|
||||
|
||||

|
||||
|
||||
The Kubernetes 1.21 Release Logo portrays the global nature of the Release Team, with release team members residing in timezones from UTC+8 all the way to UTC-8. The diversity of the release team brought in a lot of challenges, but the team tackled them all by adopting more asynchronous communication practices. The heptagonal globe in the release logo signifies the sheer determination of the community to overcome the challenges as they come. It celebrates the amazing teamwork of the release team over the last 3 months to bring in a fun packed Kubernetes release!
|
||||
|
||||
The logo is designed by [Aravind Sekar](https://www.behance.net/noblebatman), an independent designer based out of India. Aravind helps open source communities like PyCon India in their design efforts.
|
||||
|
||||
# User Highlights
|
||||
|
||||
- CNCF welcomes 47 new organizations across the globe as members to advance Cloud Native technology further at the start of 2021! These [new members](https://www.cncf.io/announcements/2021/02/24/cloud-native-computing-foundation-welcomes-47-new-members-at-the-start-of-2021/) will join CNCF at the upcoming 2021 KubeCon + CloudNativeCon events, including [KubeCon + CloudNativeCom EU – Virtual](https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/) from May 4 – 7, 2021, and [KubeCon + CloudNativeCon NA in Los Angeles](https://events.linuxfoundation.org/kubecon-cloudnativecon-north-america/) from October 12 – 15, 2021.
|
||||
|
||||
# Project Velocity
|
||||
|
||||
The [CNCF K8s DevStats project](https://k8s.devstats.cncf.io/) aggregates a number of interesting data points related to the velocity of Kubernetes and various sub-projects. This includes everything from individual contributions to the number of companies that are contributing, and is a neat illustration of the depth and breadth of effort that goes into evolving this ecosystem.
|
||||
|
||||
In the v1.21 release cycle, which ran for 12 weeks (January 11 to April 8), we saw contributions from [999 companies](https://k8s.devstats.cncf.io/d/9/companies-table?orgId=1&var-period_name=v1.20.0%20-%20now&var-metric=contributions) and [1279 individuals](https://k8s.devstats.cncf.io/d/66/developer-activity-counts-by-companies?orgId=1&var-period_name=v1.20.0%20-%20now&var-metric=contributions&var-repogroup_name=Kubernetes&var-country_name=All&var-companies=All).
|
||||
|
||||
# Ecosystem Updates
|
||||
|
||||
- In the wake of rising racism & attacks on global Asian communities, read the statement from CNCF General Priyanka Sharma on the [CNCF blog](https://www.cncf.io/blog/2021/03/18/statement-from-cncf-general-manager-priyanka-sharma-on-the-unacceptable-attacks-against-aapi-and-asian-communities/) reinstating the community's commitment towards inclusive values & diversity-powered resilience.
|
||||
- We now have a process in place for migration of the default branch from master → main. Learn more about the guidelines [here](k8s.dev/rename)
|
||||
- CNCF and the Linux Foundation have announced the availability of their new training course, [LFS260 – Kubernetes Security Essentials](https://training.linuxfoundation.org/training/kubernetes-security-essentials-lfs260/). In addition to providing skills and knowledge on a broad range of best practices for securing container-based applications and Kubernetes platforms, the course is also a great way to prepare for the recently launched [Certified Kubernetes Security Specialist](https://training.linuxfoundation.org/certification/certified-kubernetes-security-specialist/) certification exam.
|
||||
|
||||
# Event Updates
|
||||
|
||||
- KubeCon + CloudNativeCon Europe 2021 will take place May 4 - 7, 2021! You can find more information about the conference [here](https://events.linuxfoundation.org/kubecon-cloudnativecon-europe/).
|
||||
- [Kubernetes Community Days](https://kubernetescommunitydays.org/) are being relaunched! Q2 2021 will start with Africa and Bengaluru.
|
||||
|
||||
# Upcoming release webinar
|
||||
|
||||
Join the members of the Kubernetes 1.21 release team on May 13th, 2021 to learn about the major features in this release including IPv4/IPv6 dual-stack support, PersistentVolume Health Monitor, Immutable Secrets and ConfigMaps, and many more. Register here: [https://community.cncf.io/events/details/cncf-cncf-online-programs-presents-cncf-live-webinar-kubernetes-121-release/](https://community.cncf.io/events/details/cncf-cncf-online-programs-presents-cncf-live-webinar-kubernetes-121-release/)
|
||||
|
||||
# Get Involved
|
||||
|
||||
If you’re interested in contributing to the Kubernetes community, Special Interest Groups (SIGs) are a great starting point. Many of them may align with your interests! If there are things you’d like to share with the community, you can join the weekly community meeting, or use any of the following channels:
|
||||
|
||||
* Find out more about contributing to Kubernetes at the [Kubernetes Contributor website](https://www.kubernetes.dev/)
|
||||
* Follow us on Twitter [@Kubernetesio](https://twitter.com/kubernetesio) for latest updates
|
||||
* Join the community discussion on [Discuss](https://discuss.kubernetes.io/)
|
||||
* Join the community on [Slack](http://slack.k8s.io/)
|
||||
* Share your Kubernetes [story](https://github.com/cncf/foundation/blob/master/case-study-guidelines.md)
|
||||
* Read more about what’s happening with Kubernetes on the [blog](https://kubernetes.io/blog/)
|
||||
* Learn more about the [Kubernetes Release Team](https://github.com/kubernetes/sig-release/tree/master/release-team)
|
||||
@@ -0,0 +1,110 @@
|
||||
---
|
||||
title: "Introducing Suspended Jobs"
|
||||
date: 2021-04-12
|
||||
slug: introducing-suspended-jobs
|
||||
layout: blog
|
||||
---
|
||||
|
||||
**Author:** Adhityaa Chandrasekar (Google)
|
||||
|
||||
[Jobs](/docs/concepts/workloads/controllers/job/) are a crucial part of
|
||||
Kubernetes' API. While other kinds of workloads such as [Deployments](/docs/concepts/workloads/controllers/deployment/),
|
||||
[ReplicaSets](/docs/concepts/workloads/controllers/replicaset/),
|
||||
[StatefulSets](/docs/concepts/workloads/controllers/statefulset/), and
|
||||
[DaemonSets](/docs/concepts/workloads/controllers/daemonset/)
|
||||
solve use-cases that require Pods to run forever, Jobs are useful when Pods need
|
||||
to run to completion. Commonly used in parallel batch processing, Jobs can be
|
||||
used in a variety of applications ranging from video rendering and database
|
||||
maintenance to sending bulk emails and scientific computing.
|
||||
|
||||
While the amount of parallelism and the conditions for Job completion are
|
||||
configurable, the Kubernetes API lacked the ability to suspend and resume Jobs.
|
||||
This is often desired when cluster resources are limited and a higher priority
|
||||
Job needs to execute in the place of another Job. Deleting the lower priority
|
||||
Job is a poor workaround as Pod completion history and other metrics associated
|
||||
with the Job will be lost.
|
||||
|
||||
With the recent Kubernetes 1.21 release, you will be able to suspend a Job by
|
||||
updating its spec. The feature is currently in **alpha** and requires you to
|
||||
enable the `SuspendJob` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/)
|
||||
on the [API server](/docs/reference/command-line-tools-reference/kube-apiserver/)
|
||||
and the [controller manager](/docs/reference/command-line-tools-reference/kube-controller-manager/)
|
||||
in order to use it.
|
||||
|
||||
## API changes
|
||||
|
||||
We introduced a new boolean field `suspend` into the `.spec` of Jobs. Let's say
|
||||
I create the following Job:
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: my-job
|
||||
spec:
|
||||
suspend: true
|
||||
parallelism: 2
|
||||
completions: 10
|
||||
template:
|
||||
spec:
|
||||
containers:
|
||||
- name: my-container
|
||||
image: busybox
|
||||
command: ["sleep", "5"]
|
||||
restartPolicy: Never
|
||||
```
|
||||
|
||||
Jobs are not suspended by default, so I'm explicitly setting the `suspend` field
|
||||
to _true_ in the `.spec` of the above Job manifest. In the above example, the
|
||||
Job controller will refrain from creating Pods until I'm ready to start the Job,
|
||||
which I can do by updating `suspend` to false.
|
||||
|
||||
As another example, consider a Job that was created with the `suspend` field
|
||||
omitted. The Job controller will happily create Pods to work towards Job
|
||||
completion. However, before the Job completes, if I explicitly set the field to
|
||||
true with a Job update, the Job controller will terminate all active Pods that
|
||||
are running and will wait indefinitely for the flag to be flipped back to false.
|
||||
Typically, Pod termination is done by sending a SIGTERM signal to all container
|
||||
processes in the Pod; the [graceful termination period](/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination)
|
||||
defined in the Pod spec will be honoured. Pods terminated this way will not be
|
||||
counted as failures by the Job controller.
|
||||
|
||||
It is important to understand that succeeded and failed Pods from the past will
|
||||
continue to exist after you suspend a Job. That is, that they will count towards
|
||||
Job completion once you resume it. You can verify this by looking at Job's
|
||||
status before and after suspension.
|
||||
|
||||
Read the [documentation](/docs/concepts/workloads/controllers/job#suspending-a-job)
|
||||
for a full overview of this new feature.
|
||||
|
||||
## Where is this useful?
|
||||
|
||||
Let's say I'm the operator of a large cluster. I have many users submitting Jobs
|
||||
to the cluster, but not all Jobs are created equal — some Jobs are more
|
||||
important than others. Cluster resources aren't infinite either, so all users
|
||||
must share resources. If all Jobs were created in the suspended state and placed
|
||||
in a pending queue, I can achieve priority-based Job scheduling by resuming Jobs
|
||||
in the right order.
|
||||
|
||||
As another motivational use-case, consider a cloud provider where compute
|
||||
resources are cheaper at night than in the morning. If I have a long-running Job
|
||||
that takes multiple days to complete, being able to suspend the Job in the
|
||||
morning and then resume it in the evening every day can reduce costs.
|
||||
|
||||
Since this field is a part of the Job spec, [CronJobs](/docs/concepts/workloads/controllers/cron-jobs/)
|
||||
automatically get this feature for free too.
|
||||
|
||||
## References and next steps
|
||||
|
||||
If you're interested in a deeper dive into the rationale behind this feature and
|
||||
the decisions we have taken, consider reading the [enhancement proposal](https://github.com/kubernetes/enhancements/tree/master/keps/sig-apps/2232-suspend-jobs).
|
||||
There's more detail on suspending and resuming jobs in the documentation for [Job](/docs/concepts/workloads/controllers/job#suspending-a-job).
|
||||
|
||||
As previously mentioned, this feature is currently in alpha and is available
|
||||
only if you explicitly opt-in through the `SuspendJob` [feature gate](/docs/reference/command-line-tools-reference/feature-gates/).
|
||||
If this is a feature you're interested in, please consider testing suspended
|
||||
Jobs in your cluster and providing feedback. You can discuss this enhancement [on GitHub](https://github.com/kubernetes/enhancements/issues/2232).
|
||||
The SIG Apps community also [meets regularly](https://github.com/kubernetes/community/tree/master/sig-apps#meetings)
|
||||
and can be reached through [Slack or the mailing list](https://github.com/kubernetes/community/tree/master/sig-apps#contact).
|
||||
Barring any unexpected changes to the API, we intend to graduate the feature to
|
||||
beta in Kubernetes 1.22, so that the feature becomes available by default.
|
||||
@@ -0,0 +1,45 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "kube-state-metrics goes v2.0"
|
||||
date: 2021-04-13
|
||||
slug: kube-state-metrics-v-2-0
|
||||
---
|
||||
|
||||
**Authors:** Lili Cosic (Red Hat), Frederic Branczyk (Polar Signals), Manuel Rüger (Sony Interactive Entertainment), Tariq Ibrahim (Salesforce)
|
||||
|
||||
## What?
|
||||
|
||||
[kube-state-metrics](https://github.com/kubernetes/kube-state-metrics), a project under the Kubernetes organization, generates Prometheus format metrics based on the current state of the Kubernetes native resources. It does this by listening to the Kubernetes API and gathering information about resources and objects, e.g. Deployments, Pods, Services, and StatefulSets. A full list of resources is available in the [documentation](https://github.com/kubernetes/kube-state-metrics/tree/master/docs) of kube-state-metrics.
|
||||
|
||||
## Why?
|
||||
|
||||
There are numerous useful metrics and insights provided by `kube-state-metrics` right out of the box! These metrics can be used to serve as an insight into your cluster: Either through metrics alone, in the form of dashboards, or through an alerting pipeline. To provide a few examples:
|
||||
|
||||
* `kube_pod_container_status_restarts_total` can be used to alert on a crashing pod.
|
||||
* `kube_deployment_status_replicas` which together with `kube_deployment_status_replicas_available` can be used to alert on whether a deployment is rolled out successfully or stuck.
|
||||
* `kube_pod_container_resource_requests` and `kube_pod_container_resource_limits` can be used in capacity planning dashboards.
|
||||
|
||||
And there are many more metrics available! To learn more about the other metrics and their details, please check out the [documentation](https://github.com/kubernetes/kube-state-metrics/tree/master/docs#readme).
|
||||
|
||||
## What is new in v2.0?
|
||||
|
||||
So now that we know what kube-state-metrics is, we are excited to announce the next release: kube-state-metrics v2.0! This release was long-awaited and started with an alpha release in September 2020. To ease maintenance we removed tech debt and also adjusted some confusing wording around user-facing flags and APIs. We also removed some metrics that caused unnecessarily high cardinality in Prometheus! For the 2.0 release, we took the time to set up scale and performance testing. This allows us to better understand if we hit any issues in large clusters and also to document resource request recommendations for your clusters. In this release (and v1.9.8) container builds providing support for multiple architectures were introduced allowing you to run kube-state-metrics on ARM, ARM64, PPC64 and S390x as well!
|
||||
|
||||
So without further ado, here is the list of more noteworthy user-facing breaking changes. A full list of changes, features and bug fixes is available in the changelog at the end of this post.
|
||||
|
||||
* Flag `--namespace` was renamed to `--namespaces`. If you are using the former, please make sure to update the flag before deploying the latest release.
|
||||
* Flag `--collectors` was renamed to `--resources`.
|
||||
* Flags `--metric-blacklist` and `--metric-whitelist` were renamed to `--metric-denylist` and `--metric-allowlist`.
|
||||
* Flag `--metric-labels-allowlist` allows you to specify a list of Kubernetes labels that get turned into the dimensions of the `kube_<resource-name>_labels` metrics. By default, the metric contains only name and namespace labels.
|
||||
* All metrics with a prefix of `kube_hpa_*` were renamed to `kube_horizontalpodautoscaler_*`.
|
||||
* Metric labels that relate to Kubernetes were converted to snake_case.
|
||||
* If you are importing kube-state-metrics as a library, we have updated our go module path to `k8s.io/kube-state-metrics/v2`
|
||||
* All deprecated stable metrics were removed as per the [notice in the v1.9 release](https://github.com/kubernetes/kube-state-metrics/tree/release-1.9/docs#metrics-deprecation).
|
||||
* `quay.io/coreos/kube-state-metrics` images will no longer be updated. `k8s.gcr.io/kube-state-metrics/kube-state-metrics` is the new canonical location.
|
||||
* The helm chart that is part of the kubernetes/kube-state-metrics repository is deprecated. https://github.com/prometheus-community/helm-charts will be its new location.
|
||||
|
||||
For the full list of v2.0 release changes includes features, bug fixes and other breaking changes see the full [CHANGELOG](https://github.com/kubernetes/kube-state-metrics/blob/master/CHANGELOG.md).
|
||||
|
||||
## Found a problem?
|
||||
|
||||
Thanks to all our users for testing so far and thank you to all our contributors for your issue reports as well as code and documentation changes! If you find any problems, we the [maintainers](https://github.com/kubernetes/kube-state-metrics/blob/master/OWNERS) are more than happy to look into them, so please report them by opening a [GitHub issue](https://github.com/kubernetes/kube-state-metrics/issues/new/choose).
|
||||
@@ -0,0 +1,216 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Local Storage: Storage Capacity Tracking, Distributed Provisioning and Generic Ephemeral Volumes hit Beta"
|
||||
date: 2021-04-14
|
||||
slug: local-storage-features-go-beta
|
||||
---
|
||||
|
||||
**Authors:** Patrick Ohly (Intel)
|
||||
|
||||
The ["generic ephemeral
|
||||
volumes"](/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes)
|
||||
and ["storage capacity
|
||||
tracking"](/docs/concepts/storage/storage-capacity/)
|
||||
features in Kubernetes are getting promoted to beta in Kubernetes
|
||||
1.21. Together with the [distributed provisioning
|
||||
support](https://github.com/kubernetes-csi/external-provisioner#deployment-on-each-node)
|
||||
in the CSI external-provisioner, development and deployment of
|
||||
Container Storage Interface (CSI) drivers which manage storage locally
|
||||
on a node become a lot easier.
|
||||
|
||||
This blog post explains how such drivers worked before and how these
|
||||
features can be used to make drivers simpler.
|
||||
|
||||
## Problems we are solving
|
||||
|
||||
There are drivers for local storage, like
|
||||
[TopoLVM](https://github.com/cybozu-go/topolvm) for traditional disks
|
||||
and [PMEM-CSI](https://intel.github.io/pmem-csi/latest/README.html)
|
||||
for [persistent memory](https://pmem.io/). They work and are ready for
|
||||
usage today also on older Kubernetes releases, but making that possible
|
||||
was not trivial.
|
||||
|
||||
### Central component required
|
||||
|
||||
The first problem is volume provisioning: it is handled through the
|
||||
Kubernetes control plane. Some component must react to
|
||||
[PersistentVolumeClaims](/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims)
|
||||
(PVCs)
|
||||
and create volumes. Usually, that is handled by a central deployment
|
||||
of the [CSI
|
||||
external-provisioner](https://kubernetes-csi.github.io/docs/external-provisioner.html)
|
||||
and a CSI driver component that then connects to the storage
|
||||
backplane. But for local storage, there is no such backplane.
|
||||
|
||||
TopoLVM solved this by having its different components communicate
|
||||
with each other through the Kubernetes API server by creating and
|
||||
reacting to custom resources. So although TopoLVM is based on CSI, a
|
||||
standard that is independent of a particular container orchestrator,
|
||||
TopoLVM only works on Kubernetes.
|
||||
|
||||
PMEM-CSI created its own storage backplane with communication through
|
||||
gRPC calls. Securing that communication depends on TLS certificates,
|
||||
which made driver deployment more complicated.
|
||||
|
||||
### Informing Pod scheduler about capacity
|
||||
|
||||
The next problem is scheduling. When volumes get created independently
|
||||
of pods ("immediate binding"), the CSI driver must pick a node without
|
||||
knowing anything about the pod(s) that are going to use it. Topology
|
||||
information then forces those pods to run on the node where the volume
|
||||
was created. If other resources like RAM or CPU are exhausted there,
|
||||
the pod cannot start. This can be avoided by configuring in the
|
||||
StorageClass that volume creation is meant to wait for the first pod
|
||||
that uses a volume (`volumeBinding: WaitForFirstConsumer`). In that
|
||||
mode, the Kubernetes scheduler tentatively picks a node based on other
|
||||
constraints and then the external-provisioner is asked to create a
|
||||
volume such that it is usable there. If local storage is exhausted,
|
||||
the provisioner [can
|
||||
ask](https://github.com/kubernetes-csi/external-provisioner/blob/master/doc/design.md)
|
||||
for another scheduling round. But without information about available
|
||||
capacity, the scheduler might always pick the same unsuitable node.
|
||||
|
||||
Both TopoLVM and PMEM-CSI solved this with scheduler extenders. This
|
||||
works, but it is hard to configure when deploying the driver because
|
||||
communication between kube-scheduler and the driver is very dependent
|
||||
on how the cluster was set up.
|
||||
|
||||
### Rescheduling
|
||||
|
||||
A common use case for local storage is scratch space. A better fit for
|
||||
that use case than persistent volumes are ephemeral volumes that get
|
||||
created for a pod and destroyed together with it. The initial API for
|
||||
supporting ephemeral volumes with CSI drivers (hence called ["*CSI*
|
||||
ephemeral
|
||||
volumes"](/docs/concepts/storage/ephemeral-volumes/#csi-ephemeral-volumes))
|
||||
was [designed for light-weight
|
||||
volumes](https://github.com/kubernetes/enhancements/blob/master/keps/sig-storage/20190122-csi-inline-volumes.md)
|
||||
where volume creation is unlikely to fail. Volume creation happens
|
||||
after pods have been permanently scheduled onto a node, in contrast to
|
||||
the traditional provisioning where volume creation is tried before
|
||||
scheduling a pod onto a node. CSI drivers must be modified to support
|
||||
"CSI ephemeral volumes", which was done for TopoLVM and PMEM-CSI. But
|
||||
due to the design of the feature in Kubernetes, pods can get stuck
|
||||
permanently if storage capacity runs out on a node. The scheduler
|
||||
extenders try to avoid that, but cannot be 100% reliable.
|
||||
|
||||
## Enhancements in Kubernetes 1.21
|
||||
|
||||
### Distributed provisioning
|
||||
|
||||
Starting with [external-provisioner
|
||||
v2.1.0](https://github.com/kubernetes-csi/external-provisioner/releases/tag/v2.1.0),
|
||||
released for Kubernetes 1.20, provisioning can be handled by
|
||||
external-provisioner instances that get [deployed together with the
|
||||
CSI driver on each
|
||||
node](https://github.com/kubernetes-csi/external-provisioner#deployment-on-each-node)
|
||||
and then cooperate to provision volumes ("distributed
|
||||
provisioning"). There is no need any more to have a central component
|
||||
and thus no need for communication between nodes, at least not for
|
||||
provisioning.
|
||||
|
||||
### Storage capacity tracking
|
||||
|
||||
A scheduler extender still needs some way to find out about capacity
|
||||
on each node. When PMEM-CSI switched to distributed provisioning in
|
||||
v0.9.0, this was done by querying the metrics data exposed by the
|
||||
local driver containers. But it is better also for users to eliminate
|
||||
the need for a scheduler extender completely because the driver
|
||||
deployment becomes simpler. [Storage capacity
|
||||
tracking](/docs/concepts/storage/storage-capacity/), [introduced in
|
||||
1.19](/blog/2020/09/01/ephemeral-volumes-with-storage-capacity-tracking/)
|
||||
and promoted to beta in Kubernetes 1.21, achieves that. It works by
|
||||
publishing information about capacity in `CSIStorageCapacity`
|
||||
objects. The scheduler itself then uses that information to filter out
|
||||
unsuitable nodes. Because information might be not quite up-to-date,
|
||||
pods may still get assigned to nodes with insufficient storage, it's
|
||||
just less likely and the next scheduling attempt for a pod should work
|
||||
better once the information got refreshed.
|
||||
|
||||
### Generic ephemeral volumes
|
||||
|
||||
So CSI drivers still need the ability to recover from a bad scheduling
|
||||
decision, something that turned out to be impossible to implement for
|
||||
"CSI ephemeral volumes". ["*Generic* ephemeral
|
||||
volumes"](/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes),
|
||||
another feature that got promoted to beta in 1.21, don't have that
|
||||
limitation. This feature adds a controller that will create and manage
|
||||
PVCs with the lifetime of the Pod and therefore the normal recovery
|
||||
mechanism also works for them. Existing storage drivers will be able
|
||||
to process these PVCs without any new logic to handle this new
|
||||
scenario.
|
||||
|
||||
## Known limitations
|
||||
|
||||
Both generic ephemeral volumes and storage capacity tracking increase
|
||||
the load on the API server. Whether that is a problem depends a lot on
|
||||
the kind of workload, in particular how many pods have volumes and how
|
||||
often those need to be created and destroyed.
|
||||
|
||||
No attempt was made to model how scheduling decisions affect storage
|
||||
capacity. That's because the effect can vary considerably depending on
|
||||
how the storage system handles storage. The effect is that multiple
|
||||
pods with unbound volumes might get assigned to the same node even
|
||||
though there is only sufficient capacity for one pod. Scheduling
|
||||
should recover, but it would be more efficient if the scheduler knew
|
||||
more about storage.
|
||||
|
||||
Because storage capacity gets published by a running CSI driver and
|
||||
the cluster autoscaler needs information about a node that hasn't been
|
||||
created yet, it will currently not scale up a cluster for pods that
|
||||
need volumes. There is an [idea how to provide that
|
||||
information](https://github.com/kubernetes/autoscaler/pull/3887), but
|
||||
more work is needed in that area.
|
||||
|
||||
Distributed snapshotting and resizing are not currently supported. It
|
||||
should be doable to adapt the respective sidecar and there are
|
||||
tracking issues for external-snapshotter and external-resizer open
|
||||
already, they just need some volunteer.
|
||||
|
||||
The recovery from a bad scheduling decising can fail for pods with
|
||||
multiple volumes, in particular when those volumes are local to nodes:
|
||||
if one volume can be created and then storage is insufficient for
|
||||
another volume, the first volume continues to exist and forces the
|
||||
scheduler to put the pod onto the node of that volume. There is an
|
||||
idea how do deal with this, [rolling back the provision of the
|
||||
volume](https://github.com/kubernetes/enhancements/pull/1703), but
|
||||
this is only in the very early stages of brainstorming and not even a
|
||||
merged KEP yet. For now it is better to avoid creating pods with more
|
||||
than one persistent volume.
|
||||
|
||||
## Enabling the new features and next steps
|
||||
|
||||
With the feature entering beta in the 1.21 release, no additional actions are needed to enable it. Generic
|
||||
ephemeral volumes also work without changes in CSI drivers. For more
|
||||
information, see the
|
||||
[documentation](/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes)
|
||||
and the [previous blog
|
||||
post](/blog/2020/09/01/ephemeral-volumes-with-storage-capacity-tracking/)
|
||||
about it. The API has not changed at all between alpha and beta.
|
||||
|
||||
For the other two features, the external-provisioner documentation
|
||||
explains how CSI driver developers must change how their driver gets
|
||||
deployed to support [storage capacity
|
||||
tracking](https://github.com/kubernetes-csi/external-provisioner#capacity-support)
|
||||
and [distributed
|
||||
provisioning](https://github.com/kubernetes-csi/external-provisioner#deployment-on-each-node).
|
||||
These two features are independent, therefore it is okay to enable
|
||||
only one of them.
|
||||
|
||||
[SIG
|
||||
Storage](https://github.com/kubernetes/community/tree/master/sig-storage)
|
||||
would like to hear from you if you are using these new features. We
|
||||
can be reached through
|
||||
[email](https://groups.google.com/forum/#!forum/kubernetes-sig-storage),
|
||||
[Slack](https://slack.k8s.io/) (channel [`#sig-storage`](https://kubernetes.slack.com/messages/sig-storage)) and in the
|
||||
[regular SIG
|
||||
meeting](https://github.com/kubernetes/community/tree/master/sig-storage#meeting).
|
||||
A description of your workload would be very useful to validate design
|
||||
decisions, set up performance tests and eventually promote these
|
||||
features to GA.
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Thanks a lot to the members of the community who have contributed to these
|
||||
features or given feedback including members of SIG Scheduling, SIG Auth,
|
||||
and of course SIG Storage!
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
layout: blog
|
||||
title: 'Three Tenancy Models For Kubernetes'
|
||||
date: 2021-04-15
|
||||
slug: three-tenancy-models-for-kubernetes
|
||||
---
|
||||
|
||||
**Authors:** Ryan Bezdicek (Medtronic), Jim Bugwadia (Nirmata), Tasha Drew (VMware), Fei Guo (Alibaba), Adrian Ludwin (Google)
|
||||
|
||||
Kubernetes clusters are typically used by several teams in an organization. In other cases, Kubernetes may be used to deliver applications to end users requiring segmentation and isolation of resources across users from different organizations. Secure sharing of Kubernetes control plane and worker node resources allows maximizing productivity and saving costs in both cases.
|
||||
|
||||
The Kubernetes Multi-Tenancy Working Group is chartered with defining tenancy models for Kubernetes and making it easier to operationalize tenancy related use cases. This blog post, from the working group members, describes three common tenancy models and introduces related working group projects.
|
||||
|
||||
We will also be presenting on this content and discussing different use cases at our Kubecon EU 2021 panel session, [Multi-tenancy vs. Multi-cluster: When Should you Use What?](https://sched.co/iE66).
|
||||
|
||||
## Namespaces as a Service
|
||||
|
||||
With the *namespaces-as-a-service* model, tenants share a cluster and tenant workloads are restricted to a set of Namespaces assigned to the tenant. The cluster control plane resources like the API server and scheduler, and worker node resources like CPU, memory, etc. are available for use across all tenants.
|
||||
|
||||
To isolate tenant workloads, each namespace must also contain:
|
||||
* **[role bindings](/docs/reference/access-authn-authz/rbac/#rolebinding-and-clusterrolebinding):** for controlling access to the namespace
|
||||
* **[network policies](/docs/concepts/services-networking/network-policies/):** to prevent network traffic across tenants
|
||||
* **[resource quotas](/docs/concepts/policy/resource-quotas/):** to limit usage and ensure fairness across tenants
|
||||
|
||||
With this model, tenants share cluster-wide resources like ClusterRoles and CustomResourceDefinitions (CRDs) and hence cannot create or update these cluster-wide resources.
|
||||
|
||||
The [Hierarchical Namespace Controller (HNC)](/blog/2020/08/14/introducing-hierarchical-namespaces/) project makes it easier to manage namespace based tenancy by allowing users to create additional namespaces under a namespace, and propagating resources within the namespace hierarchy. This allows self-service namespaces for tenants, without requiring cluster-wide permissions.
|
||||
|
||||
The [Multi-Tenancy Benchmarks (MTB)](https://github.com/kubernetes-sigs/multi-tenancy/tree/master/benchmarks) project provides benchmarks and a command-line tool that performs several configuration and runtime checks to report if tenant namespaces are properly isolated and the necessary security controls are implemented.
|
||||
|
||||
## Clusters as a Service
|
||||
|
||||
With the *clusters-as-a-service* usage model, each tenant gets their own cluster. This model allows tenants to have different versions of cluster-wide resources such as CRDs, and provides full isolation of the Kubernetes control plane.
|
||||
|
||||
The tenant clusters may be provisioned using projects like [Cluster API (CAPI)](https://cluster-api.sigs.k8s.io/) where a management cluster is used to provision multiple workload clusters. A workload cluster is assigned to a tenant and tenants have full control over cluster resources. Note that in most enterprises a central platform team may be responsible for managing required add-on services such as security and monitoring services, and for providing cluster lifecycle management services such as patching and upgrades. A tenant administrator may be restricted from modifying the centrally managed services and other critical cluster information.
|
||||
|
||||
## Control planes as a Service
|
||||
|
||||
In a variation of the *clusters-as-a-service* model, the tenant cluster may be a **virtual cluster** where each tenant gets their own dedicated Kubernetes control plane but share worker node resources. As with other forms of virtualization, users of a virtual cluster see no significant differences between a virtual cluster and other Kubernetes clusters. This is sometimes referred to as `Control Planes as a Service` (CPaaS).
|
||||
|
||||
A virtual cluster of this type shares worker node resources and workload state independent control plane components, like the scheduler. Other workload aware control-plane components, like the API server, are created on a per-tenant basis to allow overlaps, and additional components are used to synchronize and manage state across the per-tenant control plane and the underlying shared cluster resources. With this model users can manage their own cluster-wide resources.
|
||||
|
||||
The [Virtual Cluster](https://github.com/kubernetes-sigs/multi-tenancy/tree/master/incubator/virtualcluster) project implements this model, where a `supercluster` is shared by multiple `virtual clusters`. The [Cluster API Nested](https://github.com/kubernetes-sigs/cluster-api-provider-nested) project is extending this work to conform to the CAPI model, allowing use of familiar API resources to provision and manage virtual clusters.
|
||||
|
||||
## Security considerations
|
||||
|
||||
Cloud native security involves different system layers and lifecycle phases as described in the [Cloud Native Security Whitepaper](/blog/2020/11/18/cloud-native-security-for-your-clusters) from CNCF SIG Security. Without proper security measures implemented across all layers and phases, Kubernetes tenant isolation can be compromised and a security breach with one tenant can threaten other tenants.
|
||||
|
||||
It is important for any new user to Kubernetes to realize that the default installation of a new upstream Kubernetes cluster is not secure, and you are going to need to invest in hardening it in order to avoid security issues.
|
||||
|
||||
At a minimum, the following security measures are required:
|
||||
* image scanning: container image vulnerabilities can be exploited to execute commands and access additional resources.
|
||||
* [RBAC](/docs/reference/access-authn-authz/rbac/): for *namespaces-as-a-service* user roles and permissions must be properly configured at a per-namespace level; for other models tenants may need to be restricted from accessing centrally managed add-on services and other cluster-wide resources.
|
||||
* [network policies](/docs/concepts/services-networking/network-policies/): for *namespaces-as-a-service* default network policies that deny all ingress and egress traffic are recommended to prevent cross-tenant network traffic and may also be used as a best practice for other tenancy models.
|
||||
* [Kubernetes Pod Security Standards](/docs/concepts/security/pod-security-standards/): to enforce Pod hardening best practices the `Restricted` policy is recommended as the default for tenant workloads with exclusions configured only as needed.
|
||||
* [CIS Benchmarks for Kubernetes](https://www.cisecurity.org/benchmark/kubernetes/): the CIS Benchmarks for Kubernetes guidelines should be used to properly configure Kubernetes control-plane and worker node components.
|
||||
|
||||
Additional recommendations include using:
|
||||
* policy engines: for configuration security best practices, such as only allowing trusted registries.
|
||||
* runtime scanners: to detect and report runtime security events.
|
||||
* VM-based container sandboxing: for stronger data plane isolation.
|
||||
|
||||
While proper security is required independently of tenancy models, not having essential security controls like [pod security](/docs/concepts/security/pod-security-standards/) in a shared cluster provides attackers with means to compromise tenancy models and possibly access sensitive information across tenants increasing the overall risk profile.
|
||||
|
||||
## Summary
|
||||
|
||||
A 2020 CNCF survey showed that production Kubernetes usage has increased by over 300% since 2016. As an increasing number of Kubernetes workloads move to production, organizations are looking for ways to share Kubernetes resources across teams for agility and cost savings.
|
||||
|
||||
The **namespaces as a service** tenancy model allows sharing clusters and hence enables resource efficiencies. However, it requires proper security configurations and has limitations as all tenants share the same cluster-wide resources.
|
||||
|
||||
The **clusters as a service** tenancy model addresses these limitations, but with higher management and resource overhead.
|
||||
|
||||
The **control planes as a service** model provides a way to share resources of a single Kubernetes cluster and also let tenants manage their own cluster-wide resources. Sharing worker node resources increases resource effeciencies, but also exposes cross tenant security and isolation concerns that exist for shared clusters.
|
||||
|
||||
In many cases, organizations will use multiple tenancy models to address different use cases and as different product and development teams will have varying needs. Following security and management best practices, such as applying [Pod Security Standards](/docs/concepts/security/pod-security-standards/) and not using the `default` namespace, makes it easer to switch from one model to another.
|
||||
|
||||
The [Kubernetes Multi-Tenancy Working Group](https://github.com/kubernetes-sigs/multi-tenancy) has created several projects like [Hierarchical Namespaces Controller](https://github.com/kubernetes-sigs/multi-tenancy/tree/master/incubator/hnc), [Virtual Cluster](https://github.com/kubernetes-sigs/multi-tenancy/tree/master/incubator/virtualcluster) / [CAPI Nested](https://github.com/kubernetes-sigs/cluster-api-provider-nested), and [Multi-Tenancy Benchmarks](https://github.com/kubernetes-sigs/multi-tenancy/tree/master/benchmarks) to make it easier to provision and manage multi-tenancy models.
|
||||
|
||||
If you are interested in multi-tenancy topics, or would like to share your use cases, please join us in an upcoming [community meeting](https://github.com/kubernetes/community/blob/master/wg-multitenancy/README.md) or reach out on the *wg-multitenancy channel* on the [Kubernetes slack](https://slack.k8s.io/).
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Volume Health Monitoring Alpha Update"
|
||||
date: 2021-04-16
|
||||
slug: volume-health-monitoring-alpha-update
|
||||
---
|
||||
|
||||
**Author:** Xing Yang (VMware)
|
||||
|
||||
The CSI Volume Health Monitoring feature, originally introduced in 1.19 has undergone a large update for the 1.21 release.
|
||||
|
||||
## Why add Volume Health Monitoring to Kubernetes?
|
||||
|
||||
Without Volume Health Monitoring, Kubernetes has no knowledge of the state of the underlying volumes of a storage system after a PVC is provisioned and used by a Pod. Many things could happen to the underlying storage system after a volume is provisioned in Kubernetes. For example, the volume could be deleted by accident outside of Kubernetes, the disk that the volume resides on could fail, it could be out of capacity, the disk may be degraded which affects its performance, and so on. Even when the volume is mounted on a pod and used by an application, there could be problems later on such as read/write I/O errors, file system corruption, accidental unmounting of the volume outside of Kubernetes, etc. It is very hard to debug and detect root causes when something happened like this.
|
||||
|
||||
Volume health monitoring can be very beneficial to Kubernetes users. It can communicate with the CSI driver to retrieve errors detected by the underlying storage system. PVC events can be reported up to the user to take action. For example, if the volume is out of capacity, they could request a volume expansion to get more space.
|
||||
|
||||
## What is Volume Health Monitoring?
|
||||
|
||||
CSI Volume Health Monitoring allows CSI Drivers to detect abnormal volume conditions from the underlying storage systems and report them as events on PVCs or Pods.
|
||||
|
||||
The Kubernetes components that monitor the volumes and report events with volume health information include the following:
|
||||
|
||||
* Kubelet, in addition to gathering the existing volume stats will watch the volume health of the PVCs on that node. If a PVC has an abnormal health condition, an event will be reported on the pod object using the PVC. If multiple pods are using the same PVC, events will be reported on all pods using that PVC.
|
||||
* An [External Volume Health Monitor Controller](https://github.com/kubernetes-csi/external-health-monitor) watches volume health of the PVCs and reports events on the PVCs.
|
||||
|
||||
Note that the node side volume health monitoring logic was an external agent when this feature was first introduced in the Kubernetes 1.19 release. In Kubernetes 1.21, the node side volume health monitoring logic was moved from the external agent into the Kubelet, to avoid making duplicate CSI function calls. With this change in 1.21, a new alpha [feature gate](/docs/reference/command-line-tools-reference/feature-gates/) `CSIVolumeHealth` was introduced for the volume health monitoring logic in Kubelet.
|
||||
|
||||
Currently the Volume Health Monitoring feature is informational only as it only reports abnormal volume health events on PVCs or Pods. Users will need to check these events and manually fix the problems. This feature serves as a stepping stone towards programmatic detection and resolution of volume health issues by Kubernetes in the future.
|
||||
|
||||
## How do I use Volume Health on my Kubernetes Cluster?
|
||||
|
||||
To use the Volume Health feature, first make sure the CSI driver you are using supports this feature. Refer to this [CSI drivers doc](https://kubernetes-csi.github.io/docs/drivers.html) to find out which CSI drivers support this feature.
|
||||
|
||||
To enable Volume Health Monitoring from the node side, the alpha feature gate `CSIVolumeHealth` needs to be enabled.
|
||||
|
||||
If a CSI driver supports the Volume Health Monitoring feature from the controller side, events regarding abnormal volume conditions will be recorded on PVCs.
|
||||
|
||||
If a CSI driver supports the Volume Health Monitoring feature from the controller side, user can also get events regarding node failures if the `enable-node-watcher` flag is set to true when deploying the External Health Monitor Controller. When a node failure event is detected, an event will be reported on the PVC to indicate that pods using this PVC are on a failed node.
|
||||
|
||||
If a CSI driver supports the Volume Health Monitoring feature from the node side, events regarding abnormal volume conditions will be recorded on pods using the PVCs.
|
||||
|
||||
## As a storage vendor, how do I add support for volume health to my CSI driver?
|
||||
|
||||
Volume Health Monitoring includes two parts:
|
||||
* An External Volume Health Monitoring Controller monitors volume health from the controller side.
|
||||
* Kubelet monitors volume health from the node side.
|
||||
|
||||
For details, see the [CSI spec](https://github.com/container-storage-interface/spec/blob/master/spec.md) and the [Kubernetes-CSI Driver Developer Guide](https://kubernetes-csi.github.io/docs/volume-health-monitor.html).
|
||||
|
||||
There is a sample implementation for volume health in [CSI host path driver](https://github.com/kubernetes-csi/csi-driver-host-path).
|
||||
|
||||
### Controller Side Volume Health Monitoring
|
||||
|
||||
To learn how to deploy the External Volume Health Monitoring controller, see [CSI external-health-monitor-controller](https://kubernetes-csi.github.io/docs/external-health-monitor-controller.html) in the CSI documentation.
|
||||
|
||||
The External Health Monitor Controller calls either `ListVolumes` or `ControllerGetVolume` CSI RPC and reports VolumeConditionAbnormal events with messages on PVCs if abnormal volume conditions are detected. Only CSI drivers with `LIST_VOLUMES` and `VOLUME_CONDITION` controller capability or `GET_VOLUME` and `VOLUME_CONDITION` controller capability support Volume Health Monitoring in the external controller.
|
||||
|
||||
To implement the volume health feature from the controller side, a CSI driver **must** add support for the new controller capabilities.
|
||||
|
||||
If a CSI driver supports `LIST_VOLUMES` and `VOLUME_CONDITION` controller capabilities, it **must** implement controller RPC `ListVolumes` and report the volume condition in the response.
|
||||
|
||||
If a CSI driver supports `GET_VOLUME` and `VOLUME_CONDITION` controller capability, it **must** implement controller PRC `ControllerGetVolume` and report the volume condition in the response.
|
||||
|
||||
If a CSI driver supports `LIST_VOLUMES`, `GET_VOLUME`, and `VOLUME_CONDITION` controller capabilities, only `ListVolumes` CSI RPC will be invoked by the External Health Monitor Controller.
|
||||
|
||||
### Node Side Volume Health Monitoring
|
||||
|
||||
Kubelet calls `NodeGetVolumeStats` CSI RPC and reports VolumeConditionAbnormal events with messages on Pods if abnormal volume conditions are detected. Only CSI drivers with `VOLUME_CONDITION` node capability support Volume Health Monitoring in Kubelet.
|
||||
|
||||
To implement the volume health feature from the node side, a CSI driver **must** add support for the new node capabilities.
|
||||
|
||||
If a CSI driver supports `VOLUME_CONDITION` node capability, it **must** report the volume condition in node RPC `NodeGetVoumeStats`.
|
||||
|
||||
## What’s next?
|
||||
|
||||
Depending on feedback and adoption, the Kubernetes team plans to push the CSI volume health implementation to beta in either 1.22 or 1.23.
|
||||
|
||||
We are also exploring how to use volume health information for programmatic detection and automatic reconcile in Kubernetes.
|
||||
|
||||
## How can I learn more?
|
||||
|
||||
To learn the design details for Volume Health Monitoring, read the [Volume Health Monitor](https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1432-volume-health-monitor) enhancement proposal.
|
||||
|
||||
The Volume Health Monitor controller source code is at [https://github.com/kubernetes-csi/external-health-monitor](https://github.com/kubernetes-csi/external-health-monitor).
|
||||
|
||||
There are also more details about volume health checks in the [Container Storage Interface Documentation](https://kubernetes-csi.github.io/docs/).
|
||||
|
||||
## How do I get involved?
|
||||
|
||||
The [Kubernetes Slack channel #csi](https://kubernetes.slack.com/messages/csi) and any of the [standard SIG Storage communication channels](https://github.com/kubernetes/community/blob/master/sig-storage/README.md#contact) are great mediums to reach out to the SIG Storage and the CSI team.
|
||||
|
||||
We offer a huge thank you to the contributors who helped release this feature in 1.21. We want to thank Yuquan Ren ([NickrenREN](https://github.com/nickrenren)) who implemented the initial volume health monitor controller and agent in the external health monitor repo, thank Ran Xu ([fengzixu](https://github.com/fengzixu)) who moved the volume health monitoring logic from the external agent to Kubelet in 1.21, and we offer special thanks to the following people for their insightful reviews: David Ashpole ([dashpole](https://github.com/dashpole)), Michelle Au ([msau42](https://github.com/msau42)), David Eads ([deads2k](https://github.com/deads2k)), Elana Hashman ([ehashman](https://github.com/ehashman)), Seth Jennings ([sjenning](https://github.com/sjenning)), and Jiawei Wang ([Jiawei0227](https://github.com/Jiawei0227)).
|
||||
|
||||
Those interested in getting involved with the design and development of CSI or any part of the Kubernetes Storage system, join the [Kubernetes Storage Special Interest Group](https://github.com/kubernetes/community/tree/master/sig-storage) (SIG). We’re rapidly growing and always welcome new contributors.
|
||||
@@ -0,0 +1,95 @@
|
||||
---
|
||||
title: "Introducing Indexed Jobs"
|
||||
date: 2021-04-19
|
||||
slug: introducing-indexed-jobs
|
||||
---
|
||||
|
||||
**Author:** Aldo Culquicondor (Google)
|
||||
|
||||
Once you have containerized a non-parallel [Job](/docs/concepts/workloads/controllers/job/),
|
||||
it is quite easy to get it up and running on Kubernetes without modifications to
|
||||
the binary. In most cases, when running parallel distributed Jobs, you had
|
||||
to set a separate system to partition the work among the workers. For
|
||||
example, you could set up a task queue to [assign one work item to each
|
||||
Pod](/docs/tasks/job/coarse-parallel-processing-work-queue/) or [multiple items
|
||||
to each Pod until the queue is emptied](/docs/tasks/job/fine-parallel-processing-work-queue/).
|
||||
|
||||
The Kubernetes 1.21 release introduces a new field to control Job _completion mode_,
|
||||
a configuration option that allows you to control how Pod completions affect the
|
||||
overall progress of a Job, with two possible options (for now):
|
||||
|
||||
- `NonIndexed` (default): the Job is considered complete when there has been
|
||||
a number of successfully completed Pods equal to the specified number in
|
||||
`.spec.completions`. In other words, each Pod completion is homologous to
|
||||
each other. Any Job you might have created before the introduction of
|
||||
completion modes is implicitly NonIndexed.
|
||||
- `Indexed`: the Job is considered complete when there is one successfully
|
||||
completed Pod associated with each index from 0 to `.spec.completions-1`. The
|
||||
index is exposed to each Pod in the `batch.kubernetes.io/job-completion-index`
|
||||
annotation and the `JOB_COMPLETION_INDEX` environment variable.
|
||||
|
||||
You can start using Jobs with Indexed completion mode, or Indexed Jobs, for
|
||||
short, to easily start parallel Jobs. Then, each worker Pod can have a statically
|
||||
assigned partition of the data based on the index. This saves you from having to
|
||||
set up a queuing system or even having to modify your binary!
|
||||
|
||||
## Creating an Indexed Job
|
||||
|
||||
To create an Indexed Job, you just have to add `completionMode: Indexed` to the
|
||||
Job spec and make use of the `JOB_COMPLETION_INDEX` environment variable.
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: 'sample-job'
|
||||
spec:
|
||||
completions: 3
|
||||
parallelism: 3
|
||||
completionMode: Indexed
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- command:
|
||||
- 'bash'
|
||||
- '-c'
|
||||
- 'echo "My partition: ${JOB_COMPLETION_INDEX}"'
|
||||
image: 'docker.io/library/bash'
|
||||
name: 'sample-load'
|
||||
```
|
||||
|
||||
Note that completion mode is an alpha feature in the 1.21 release. To be able to
|
||||
use it in your cluster, make sure to enable the `IndexedJob` [feature
|
||||
gate](/docs/reference/command-line-tools-reference/feature-gates/) on the
|
||||
[API server](docs/reference/command-line-tools-reference/kube-apiserver/) and
|
||||
the [controller manager](/docs/reference/command-line-tools-reference/kube-controller-manager/).
|
||||
|
||||
When you run the example, you will see that each of the three created Pods gets a
|
||||
different completion index. For the user's convenience, the control plane sets the
|
||||
`JOB_COMPLETION_INDEX` environment variable, but you can choose to [set your
|
||||
own](/docs/tasks/inject-data-application/environment-variable-expose-pod-information/)
|
||||
or [expose the index as a file](/docs/tasks/inject-data-application/downward-api-volume-expose-pod-information/).
|
||||
|
||||
See [Indexed Job for parallel processing with static work
|
||||
assignment](/docs/tasks/job/indexed-parallel-processing-static/) for a
|
||||
step-by-step guide, and a few more examples.
|
||||
|
||||
## Future plans
|
||||
|
||||
SIG Apps envisions that there might be more completion modes that enable more
|
||||
use cases for the Job API. We welcome you to open issues in
|
||||
[kubernetes/kubernetes](https://github.com/kubernetes/kubernetes) with your
|
||||
suggestions.
|
||||
|
||||
In particular, we are considering an `IndexedAndUnique` mode where the indexes
|
||||
are not just available as annotation, but they are part of the Pod names,
|
||||
similar to {{< glossary_tooltip text="StatefulSet" term_id="statefulset" >}}.
|
||||
This should facilitate inter-Pod communication for tightly coupled Pods.
|
||||
You can join the discussion in the [open issue](https://github.com/kubernetes/kubernetes/issues/99497).
|
||||
|
||||
## Wrap-up
|
||||
|
||||
Indexed Jobs allows you to statically partition work among the workers of your
|
||||
parallel Jobs. SIG Apps hopes that this feature facilitates the migration of
|
||||
more batch workloads to Kubernetes.
|
||||
@@ -0,0 +1,479 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Defining Network Policy Conformance for Container Network Interface (CNI) providers"
|
||||
date: 2021-04-20
|
||||
slug: defining-networkpolicy-conformance-cni-providers
|
||||
---
|
||||
|
||||
Authors: Matt Fenwick (Synopsys), Jay Vyas (VMWare), Ricardo Katz, Amim Knabben (Loadsmart), Douglas Schilling Landgraf (Red Hat), Christopher Tomkins (Tigera)
|
||||
|
||||
Special thanks to Tim Hockin and Bowie Du (Google), Dan Winship and Antonio Ojea (Red Hat),
|
||||
Casey Davenport and Shaun Crampton (Tigera), and Abhishek Raut and Antonin Bas (VMware) for
|
||||
being supportive of this work, and working with us to resolve issues in different Container Network Interfaces (CNIs) over time.
|
||||
|
||||
A brief conversation around "node local" Network Policies in April of 2020 inspired the creation of a NetworkPolicy subproject from SIG Network. It became clear that as a community,
|
||||
we need a rock-solid story around how to do pod network security on Kubernetes, and this story needed a community around it, so as to grow the cultural adoption of enterprise security patterns in K8s.
|
||||
|
||||
In this post we'll discuss:
|
||||
|
||||
- Why we created a subproject for [Network Policies](https://kubernetes.io/docs/concepts/services-networking/network-policies/)
|
||||
- How we changed the Kubernetes e2e framework to `visualize` NetworkPolicy implementation of your CNI provider
|
||||
- The initial results of our comprehensive NetworkPolicy conformance validator, _Cyclonus_, built around these principles
|
||||
- Improvements subproject contributors have made to the NetworkPolicy user experience
|
||||
|
||||
## Why we created a subproject for NetworkPolicies
|
||||
|
||||
In April of 2020 it was becoming clear that many CNIs were emerging, and many vendors
|
||||
implement these CNIs in subtly different ways. Users were beginning to express a little bit
|
||||
of confusion around how to implement policies for different scenarios, and asking for new features.
|
||||
It was clear that we needed to begin unifying the way we think about Network Policies
|
||||
in Kubernetes, to avoid API fragmentation and unnecessary complexity.
|
||||
|
||||
For example:
|
||||
- In order to be flexible to the user’s environment, Calico as a CNI provider can be run using IPIP or VXLAN mode, or without encapsulation overhead. CNIs such as Antrea
|
||||
and Cilium offer similar configuration options as well.
|
||||
- Some CNI plugins offer iptables for NetworkPolicies amongst other options, whereas other CNIs use a completely
|
||||
different technology stack (for example, the Antrea project uses Open vSwitch rules).
|
||||
- Some CNI plugins only implement a subset of the Kubernetes NetworkPolicy API, and some a superset. For example, certain plugins don't support the
|
||||
ability to target a named port; others don't work with certain IP address types, and there are diverging semantics for similar policy types.
|
||||
- Some CNI plugins combine with OTHER CNI plugins in order to implement NetworkPolicies (canal), some CNI's might mix implementations (multus), and some clouds do routing separately from NetworkPolicy implementation.
|
||||
|
||||
Although this complexity is to some extent necessary to support different environments, end-users find that they need to follow a multistep process to implement Network Policies to secure their applications:
|
||||
- Confirm that their network plugin supports NetworkPolicies (some don't, such as Flannel)
|
||||
- Confirm that their cluster's network plugin supports the specific NetworkPolicy features that they are interested in (again, the named port or port range examples come to mind here)
|
||||
- Confirm that their application's Network Policy definitions are doing the right thing
|
||||
- Find out the nuances of a vendor's implementation of policy, and check whether or not that implementation has a CNI neutral implementation (which is sometimes adequate for users)
|
||||
|
||||
The NetworkPolicy project in upstream Kubernetes aims at providing a community where
|
||||
people can learn about, and contribute to, the Kubernetes NetworkPolicy API and the surrounding ecosystem.
|
||||
|
||||
## The First step: A validation framework for NetworkPolicies that was intuitive to use and understand
|
||||
|
||||
The Kubernetes end to end suite has always had NetworkPolicy tests, but these weren't
|
||||
run in CI, and the way they were implemented didn't provide holistic, easily consumable
|
||||
information about how a policy was working in a cluster.
|
||||
This is because the original tests didn't provide any kind of visual summary of connectivity
|
||||
across a cluster. We thus initially set out to make it easy to confirm CNI support for NetworkPolicies by
|
||||
making the end to end tests (which are often used by administrators or users to diagnose cluster conformance) easy to interpret.
|
||||
|
||||
To solve the problem of confirming that CNIs support the basic features most users care about
|
||||
for a policy, we built a new NetworkPolicy validation tool into the Kubernetes e2e
|
||||
framework which allows for visual inspection of policies and their effect on a standard set of pods in a cluster.
|
||||
For example, take the following test output. We found a bug in
|
||||
[OVN Kubernetes](https://github.com/ovn-org/ovn-kubernetes/issues/1782). This bug has now been resolved. With this tool the bug was really
|
||||
easy to characterize, wherein certain policies caused a state-modification that,
|
||||
later on, caused traffic to incorrectly be blocked (even after all Network Policies were deleted from the cluster).
|
||||
|
||||
This is the network policy for the test in question:
|
||||
```yaml
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: allow-ingress-port-80
|
||||
spec:
|
||||
ingress:
|
||||
- ports:
|
||||
- port: serve-80-tcp
|
||||
podSelector: {}
|
||||
```
|
||||
|
||||
These are the expected connectivity results. The test setup is 9 pods (3 namespaces: x, y, and z;
|
||||
and 3 pods in each namespace: a, b, and c); each pod runs a server on the same port and protocol
|
||||
that can be reached through HTTP calls in the absence of network policies. Connectivity is verified
|
||||
by using the [agnhost](https://github.com/kubernetes/kubernetes/tree/master/test/images/agnhost) network utility to issue HTTP calls on a port and protocol that other pods are
|
||||
expected to be serving. A test scenario first
|
||||
runs a connectivity check to ensure that each pod can reach each other pod, for 81 (= 9 x 9) data
|
||||
points. This is the "control". Then perturbations are applied, depending on the test scenario:
|
||||
policies are created, updated, and deleted; labels are added and removed from pods and namespaces,
|
||||
and so on. After each change, the connectivity matrix is recollected and compared to the expected
|
||||
connectivity.
|
||||
|
||||
These results give a visual indication of connectivity in a simple matrix. Going down the leftmost column is the "source"
|
||||
pod, or the pod issuing the request; going across the topmost row is the "destination" pod, or the pod
|
||||
receiving the request. A `.` means that the connection was allowed; an `X` means the connection was
|
||||
blocked. For example:
|
||||
|
||||
```
|
||||
Nov 4 16:58:43.449: INFO: expected:
|
||||
|
||||
- x/a x/b x/c y/a y/b y/c z/a z/b z/c
|
||||
x/a . . . . . . . . .
|
||||
x/b . . . . . . . . .
|
||||
x/c . . . . . . . . .
|
||||
y/a . . . . . . . . .
|
||||
y/b . . . . . . . . .
|
||||
y/c . . . . . . . . .
|
||||
z/a . . . . . . . . .
|
||||
z/b . . . . . . . . .
|
||||
z/c . . . . . . . . .
|
||||
```
|
||||
|
||||
Below are the observed connectivity results in the case of the OVN Kubernetes bug. Notice how the top three rows indicate that
|
||||
all requests from namespace x regardless of pod and destination were blocked. Since these
|
||||
experimental results do not match the expected results, a failure will be reported. Note
|
||||
how the specific pattern of failure provides clear insight into the nature of the problem --
|
||||
since all requests from a specific namespace fail, we have a clear clue to start our
|
||||
investigation.
|
||||
|
||||
```
|
||||
Nov 4 16:58:43.449: INFO: observed:
|
||||
|
||||
- x/a x/b x/c y/a y/b y/c z/a z/b z/c
|
||||
x/a X X X X X X X X X
|
||||
x/b X X X X X X X X X
|
||||
x/c X X X X X X X X X
|
||||
y/a . . . . . . . . .
|
||||
y/b . . . . . . . . .
|
||||
y/c . . . . . . . . .
|
||||
z/a . . . . . . . . .
|
||||
z/b . . . . . . . . .
|
||||
z/c . . . . . . . . .
|
||||
```
|
||||
|
||||
This was one of our earliest wins in the Network Policy group, as we were able to
|
||||
identify and work with the OVN Kubernetes group to fix a bug in egress policy processing.
|
||||
|
||||
However, even though this tool has made it easy to validate roughly 30 common scenarios,
|
||||
it doesn't validate *all* Network Policy scenarios - because there are an enormous number of possible
|
||||
permutations that one might create (technically, we might say this number is
|
||||
infinite given that there's an infinite number of possible namespace/pod/port/protocol variations one can create).
|
||||
|
||||
Once these tests were in play, we worked with the Upstream SIG Network and SIG Testing communities
|
||||
(thanks to Antonio Ojea and Ben Elder) to put a testgrid Network Policy job in place. This job
|
||||
continuously runs the entire suite of Network Policy tests against
|
||||
[GCE with Calico as a Network Policy provider](https://testgrid.k8s.io/sig-network-gce#presubmit-network-policies,%20google-gce).
|
||||
|
||||
Part of our role as a subproject is to help make sure that, when these tests break, we can help triage them effectively.
|
||||
|
||||
## Cyclonus: The next step towards Network Policy conformance {#cyclonus}
|
||||
|
||||
Around the time that we were finishing the validation work, it became clear from the community that,
|
||||
in general, we needed to solve the overall problem of testing ALL possible Network Policy implementations.
|
||||
For example, a KEP was recently written which introduced the concept of micro versioning to
|
||||
Network Policies to accommodate [describing this at the API level](https://github.com/kubernetes/enhancements/pull/2137/files), by Dan Winship.
|
||||
|
||||
In response to this increasingly obvious need to comprehensively evaluate Network
|
||||
Policy implementations from all vendors, Matt Fenwick decided to evolve our approach to Network Policy validation again by creating Cyclonus.
|
||||
|
||||
Cyclonus is a comprehensive Network Policy fuzzing tool which verifies a CNI provider
|
||||
against hundreds of different Network Policy scenarios, by defining similar truth table/policy
|
||||
combinations as demonstrated in the end to end tests, while also providing a hierarchical
|
||||
representation of policy "categories". We've found some interesting nuances and issues
|
||||
in almost every CNI we've tested so far, and have even contributed some fixes back.
|
||||
|
||||
To perform a Cyclonus validation run, you create a Job manifest similar to:
|
||||
|
||||
```yaml
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: cyclonus
|
||||
spec:
|
||||
template:
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- command:
|
||||
- ./cyclonus
|
||||
- generate
|
||||
- --perturbation-wait-seconds=15
|
||||
- --server-protocol=tcp,udp
|
||||
name: cyclonus
|
||||
imagePullPolicy: IfNotPresent
|
||||
image: mfenwick100/cyclonus:latest
|
||||
serviceAccount: cyclonus
|
||||
```
|
||||
|
||||
Cyclonus outputs a report of all the test cases it will run:
|
||||
```
|
||||
test cases to run by tag:
|
||||
- target: 6
|
||||
- peer-ipblock: 4
|
||||
- udp: 16
|
||||
- delete-pod: 1
|
||||
- conflict: 16
|
||||
- multi-port/protocol: 14
|
||||
- ingress: 51
|
||||
- all-pods: 14
|
||||
- egress: 51
|
||||
- all-namespaces: 10
|
||||
- sctp: 10
|
||||
- port: 56
|
||||
- miscellaneous: 22
|
||||
- direction: 100
|
||||
- multi-peer: 0
|
||||
- any-port-protocol: 2
|
||||
- set-namespace-labels: 1
|
||||
- upstream-e2e: 0
|
||||
- allow-all: 6
|
||||
- namespaces-by-label: 6
|
||||
- deny-all: 10
|
||||
- pathological: 6
|
||||
- action: 6
|
||||
- rule: 30
|
||||
- policy-namespace: 4
|
||||
- example: 0
|
||||
- tcp: 16
|
||||
- target-namespace: 3
|
||||
- named-port: 24
|
||||
- update-policy: 1
|
||||
- any-peer: 2
|
||||
- target-pod-selector: 3
|
||||
- IP-block-with-except: 2
|
||||
- pods-by-label: 6
|
||||
- numbered-port: 28
|
||||
- protocol: 42
|
||||
- peer-pods: 20
|
||||
- create-policy: 2
|
||||
- policy-stack: 0
|
||||
- any-port: 14
|
||||
- delete-namespace: 1
|
||||
- delete-policy: 1
|
||||
- create-pod: 1
|
||||
- IP-block-no-except: 2
|
||||
- create-namespace: 1
|
||||
- set-pod-labels: 1
|
||||
testing 112 cases
|
||||
```
|
||||
|
||||
Note that Cyclonus tags its tests based on the type of policy being created, because
|
||||
the policies themselves are auto-generated, and thus have no meaningful names to be recognized by.
|
||||
|
||||
For each test, Cyclonus outputs a truth table, which is again similar to that of the
|
||||
E2E tests, along with the policy being validated:
|
||||
|
||||
```
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: base
|
||||
namespace: x
|
||||
spec:
|
||||
egress:
|
||||
- ports:
|
||||
- port: 81
|
||||
to:
|
||||
- namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: ns
|
||||
operator: In
|
||||
values:
|
||||
- "y"
|
||||
- z
|
||||
podSelector:
|
||||
matchExpressions:
|
||||
- key: pod
|
||||
operator: In
|
||||
values:
|
||||
- a
|
||||
- b
|
||||
- ports:
|
||||
- port: 53
|
||||
protocol: UDP
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchExpressions:
|
||||
- key: ns
|
||||
operator: In
|
||||
values:
|
||||
- x
|
||||
- "y"
|
||||
podSelector:
|
||||
matchExpressions:
|
||||
- key: pod
|
||||
operator: In
|
||||
values:
|
||||
- b
|
||||
- c
|
||||
ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
podSelector:
|
||||
matchLabels:
|
||||
pod: a
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
|
||||
0 wrong, 0 ignored, 81 correct
|
||||
+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| TCP/80 | X/A | X/B | X/C | Y/A | Y/B | Y/C | Z/A | Z/B | Z/C |
|
||||
| TCP/81 | | | | | | | | | |
|
||||
| UDP/80 | | | | | | | | | |
|
||||
| UDP/81 | | | | | | | | | |
|
||||
+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| x/a | X | X | X | X | X | X | X | X | X |
|
||||
| | X | X | X | . | . | X | . | . | X |
|
||||
| | X | X | X | X | X | X | X | X | X |
|
||||
| | X | X | X | X | X | X | X | X | X |
|
||||
+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| x/b | . | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| x/c | . | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| y/a | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| y/b | . | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| y/c | . | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| z/a | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| z/b | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
| z/c | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
| | X | . | . | . | . | . | . | . | . |
|
||||
+--------+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|
||||
```
|
||||
|
||||
Both Cyclonus and the e2e tests use the same strategy to validate a Network Policy - probing pods over TCP or UDP, with
|
||||
SCTP support available as well for CNIs that support it (such as Calico).
|
||||
|
||||
As examples of how we use Cyclonus to help make CNI implementations better from a Network Policy perspective, you can see the following issues:
|
||||
|
||||
- [Antrea: NetworkPolicy: unable to allow ingress by CIDR](https://github.com/vmware-tanzu/antrea/issues/1764)
|
||||
- [Calico: default missing protocol to TCP; don't let single port overwrite all ports](https://github.com/projectcalico/libcalico-go/pull/1373)
|
||||
- [Cilium: Egress Network Policy allows traffic that should be denied](https://github.com/cilium/cilium/issues/14678)
|
||||
|
||||
The good news is that Antrea and Calico have already merged fixes for all the issues found and other CNI providers are working on it,
|
||||
with the support of SIG Network and the Network Policy subproject.
|
||||
|
||||
Are you interested in verifying NetworkPolicy functionality on your cluster?
|
||||
(if you care about security or offer multi-tenant SaaS, you should be)
|
||||
If so, you can run the upstream end to end tests, or Cyclonus, or both.
|
||||
- If you're just getting started with NetworkPolicies and want to simply
|
||||
verify the "common" NetworkPolicy cases that most CNIs should be
|
||||
implementing correctly, in a way that is quick to diagnose, then you're
|
||||
better off running the e2e tests only.
|
||||
- If you are deeply curious about your CNI provider's NetworkPolicy
|
||||
implementation, and want to verify it: use Cyclonus.
|
||||
- If you want to test *hundreds* of policies, and evaluate your CNI plugin
|
||||
for comprehensive functionality, for deep discovery of potential security
|
||||
holes: use Cyclonus, and also consider running end-to-end cluster tests.
|
||||
- If you're thinking of getting involved with the upstream NetworkPolicy efforts:
|
||||
use Cyclonus, and read at least an outline of which e2e tests are relevant.
|
||||
|
||||
## Where to start with NetworkPolicy testing?
|
||||
|
||||
- Cyclonus is easy to run on your cluster, check out the [instructions on github](https://github.com/mattfenwick/cyclonus#run-as-a-kubernetes-job),
|
||||
and determine whether *your* specific CNI configuration is fully conformant to the hundreds of different
|
||||
Kubernetes Network Policy API constructs.
|
||||
- Alternatively, you can use a tool like [sonobuoy](https://github.com/vmware-tanzu/sonobuoy)
|
||||
to run the existing E2E tests in Kubernetes, with the `--ginkgo.focus=NetworkPolicy` flag.
|
||||
Make sure that you use the K8s conformance image for K8s 1.21 or above (for example, by using the `--kube-conformance-image-version v1.21.0` flag),
|
||||
as older images will not have the *new* Network Policy tests in them.
|
||||
|
||||
## Improvements to the NetworkPolicy API and user experience
|
||||
|
||||
In addition to cleaning up the validation story for CNI plugins that implement NetworkPolicies,
|
||||
subproject contributors have also spent some time improving the Kubernetes NetworkPolicy API for a few commonly requested features.
|
||||
After months of deliberation, we eventually settled on a few core areas for improvement:
|
||||
|
||||
- Port Range policies: We now allow you to specify a *range* of ports for a policy.
|
||||
This allows users interested in scenarios like FTP or virtualization to enable advanced policies.
|
||||
The port range option for network policies will be available to use in Kubernetes 1.21.
|
||||
Read more in [targeting a range of ports](/docs/concepts/services-networking/network-policies/#targeting-a-range-of-ports).
|
||||
- Namespace as name policies: Allowing users in Kubernetes >= 1.21 to target namespaces using names,
|
||||
when building Network Policy objects. This was done in collaboration with Jordan Liggitt and Tim Hockin on the API Machinery side.
|
||||
This change allowed us to improve the Network Policy user experience without actually
|
||||
changing the API! For more details, you can read
|
||||
[Automatic labelling](/docs/concepts/overview/working-with-objects/namespaces/#automatic-labelling) in the page about Namespaces.
|
||||
The TL,DR; is that for Kubernetes 1.21 and later, **all namespaces** have the following label added by default:
|
||||
|
||||
```
|
||||
kubernetes.io/metadata.name: <name-of-namespace>
|
||||
```
|
||||
|
||||
This means you can write a namespace policy against this namespace, even if you can't edit its labels.
|
||||
For example, this policy, will 'just work', without needing to run a command such as `kubectl edit namespace`.
|
||||
In fact, it will even work if you can't edit or view this namespace's data at all, because of the magic of API server defaulting.
|
||||
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: test-network-policy
|
||||
namespace: default
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
role: db
|
||||
policyTypes:
|
||||
- Ingress
|
||||
# Allow inbound traffic to Pods labelled role=db, in the namespace 'default'
|
||||
# provided that the source is a Pod in the namespace 'my-namespace'
|
||||
ingress:
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: my-namespace
|
||||
```
|
||||
|
||||
## Results
|
||||
|
||||
In our tests, we found that:
|
||||
|
||||
- Antrea and Calico are at a point where they support all of cyclonus's scenarios, modulo a few very minor tweaks which we've made.
|
||||
- Cilium also conformed to the majority of the policies, outside known features that aren't fully supported (for example, related to the way Cilium deals with pod CIDR policies).
|
||||
|
||||
If you are a CNI provider and interested in helping us to do a better job curating large tests of network policies, please reach out! We are continuing to curate the Network Policy conformance results from Cyclonus [here](https://raw.githubusercontent.com/K8sbykeshed/cyclonus-artifacts/), but
|
||||
we are not capable of maintaining all of the subtleties in NetworkPolicy testing data on our own. For now, we use github actions and Kind to test in CI.
|
||||
|
||||
## The Future
|
||||
|
||||
We're also working on some improvements for the future of Network Policies, including:
|
||||
|
||||
- Fully qualified Domain policies: The Google Cloud team created a prototype (which
|
||||
we are really excited about) of [FQDN policies](https://github.com/GoogleCloudPlatform/gke-fqdnnetworkpolicies-golang).
|
||||
This tool uses the Network Policy API to enforce policies against L7 URLs, by finding
|
||||
their IPs and blocking them proactively when requests are made.
|
||||
- Cluster Administrative policies: We're working hard at enabling *administrative* or
|
||||
*cluster scoped* Network Policies for the future. These are being presented iteratively to the NetworkPolicy subproject.
|
||||
You can read about them here in [Cluster Scoped Network Policy](https://docs.google.com/presentation/d/1Jk86jtS3TcGAugVSM_I4Yds5ukXFJ4F1ZCvxN5v2BaY/).
|
||||
|
||||
The Network Policy subproject meets on mondays at 4PM EST. For details, check out the
|
||||
[SIG Network community repo](https://github.com/kubernetes/community/tree/master/sig-network). We'd love
|
||||
to hang out with you, hack on stuff, and help you adopt K8s Network Policies for your cluster wherever possible.
|
||||
|
||||
### A quick note on User Feedback
|
||||
|
||||
We've gotten a lot of ideas and feedback from users on Network Policies. A lot of people have interesting ideas about Network Policies,
|
||||
but we've found that as a subproject, very few people were deeply interested in implementing these ideas to the full extent.
|
||||
|
||||
Almost every change to the NetworkPolicy API includes weeks or months of discussion to cover different cases, and ensure no CVEs are being introduced. Thus, long term ownership
|
||||
is the biggest impediment in improving the NetworkPolicy user experience for us, over time.
|
||||
|
||||
- We've documented a lot of the history of the Network Policy dialogue [here](https://github.com/jayunit100/network-policy-subproject/blob/master/history.md).
|
||||
- We've also taken a poll of users, for what they'd like to see in the Network Policy API [here](https://github.com/jayunit100/network-policy-subproject/blob/master/p0_user_stories.md).
|
||||
|
||||
We encourage anyone to provide us with feedback, but our most pressing issues right now
|
||||
involve finding *long term owners to help us drive changes*.
|
||||
|
||||
This doesn't require a lot of technical knowledge, but rather, just a long term commitment to helping us stay organized, do paperwork,
|
||||
and iterate through the many stages of the K8s feature process. If you want to help us and get involved, please reach out on the SIG Network mailing list, or in the SIG Network room in the k8s.io slack channel!
|
||||
|
||||
Anyone can put an oar in the water and help make NetworkPolices better!
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
layout: blog
|
||||
title: 'Annotating Kubernetes Services for Humans'
|
||||
date: 2021-04-20
|
||||
slug: annotating-k8s-for-humans
|
||||
---
|
||||
|
||||
**Author:** Richard Li, Ambassador Labs
|
||||
|
||||
Have you ever been asked to troubleshoot a failing Kubernetes service and struggled to find basic information about the service such as the source repository and owner?
|
||||
|
||||
One of the problems as Kubernetes applications grow is the proliferation of services. As the number of services grows, developers start to specialize working with specific services. When it comes to troubleshooting, however, developers need to be able to find the source, understand the service and dependencies, and chat with the owning team for any service.
|
||||
|
||||
## Human service discovery
|
||||
|
||||
Troubleshooting always begins with information gathering. While much attention has been paid to centralizing machine data (e.g., logs, metrics), much less attention has been given to the human aspect of service discovery. Who owns a particular service? What Slack channel does the team work on? Where is the source for the service? What issues are currently known and being tracked?
|
||||
|
||||
## Kubernetes annotations
|
||||
|
||||
Kubernetes annotations are designed to solve exactly this problem. Oft-overlooked, Kubernetes annotations are designed to add metadata to Kubernetes objects. The Kubernetes documentation says annotations can “attach arbitrary non-identifying metadata to objects.” This means that annotations should be used for attaching metadata that is external to Kubernetes (i.e., metadata that Kubernetes won’t use to identify objects. As such, annotations can contain any type of data. This is a contrast to labels, which are designed for uses internal to Kubernetes. As such, label structure and values are [constrained](/docs/concepts/overview/working-with-objects/labels/#syntax-and-character-set) so they can be efficiently used by Kubernetes.
|
||||
|
||||
|
||||
## Kubernetes annotations in action
|
||||
|
||||
Here is an example. Imagine you have a Kubernetes service for quoting, called the quote service. You can do the following:
|
||||
|
||||
```
|
||||
kubectl annotate service quote a8r.io/owner=”@sally”
|
||||
```
|
||||
|
||||
In this example, we've just added an annotation called `a8r.io/owner` with the value of @sally. Now, we can use `kubectl describe` to get the information.
|
||||
|
||||
```
|
||||
Name: quote
|
||||
Namespace: default
|
||||
Labels: <none>
|
||||
Annotations: a8r.io/owner: @sally
|
||||
Selector: app=quote
|
||||
Type: ClusterIP
|
||||
IP: 10.109.142.131
|
||||
Port: http 80/TCP
|
||||
TargetPort: 8080/TCP
|
||||
Endpoints: <none>
|
||||
Session Affinity: None
|
||||
Events: <none>
|
||||
```
|
||||
|
||||
If you’re practicing GitOps (and you should be!) you’ll want to code these values directly into your Kubernetes manifest, e.g.,
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: quote
|
||||
annotations:
|
||||
a8r.io/owner: “@sally”
|
||||
spec:
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: 8080
|
||||
selector:
|
||||
app: quote
|
||||
```
|
||||
|
||||
## A Convention for Annotations
|
||||
|
||||
Adopting a common convention for annotations ensures consistency and understandability. Typically, you’ll want to attach the annotation to the service object, as services are the high-level resource that maps most clearly to a team’s responsibility. Namespacing your annotations is also very important. Here is one set of conventions, documented at [a8r.io](https://a8r.io), and reproduced below:
|
||||
|
||||
{{< table caption="Annotation convention for human-readable services">}}
|
||||
| Annotation | Description |
|
||||
| ------------------------------------------ | ------------------------------------------- |
|
||||
| `a8r.io/description` | Unstructured text description of the service for humans. |
|
||||
| `a8r.io/owner` | SSO username (GitHub), email address (linked to GitHub account), or unstructured owner description. |
|
||||
| `a8r.io/chat` | Slack channel, or link to external chat system. |
|
||||
| `a8r.io/bugs` | Link to external bug tracker. |
|
||||
| `a8r.io/logs` | Link to external log viewer. |
|
||||
| `a8r.io/documentation` | Link to external project documentation. |
|
||||
| `a8r.io/repository` | Link to external VCS repository. |
|
||||
| `a8r.io/support` | Link to external support center. |
|
||||
| `a8r.io/runbook` | Link to external project runbook. |
|
||||
| `a8r.io/incidents` | Link to external incident dashboard. |
|
||||
| `a8r.io/uptime` | Link to external uptime dashboard. |
|
||||
| `a8r.io/performance` | Link to external performance dashboard. |
|
||||
| `a8r.io/dependencies` | Unstructured text describing the service dependencies for humans. |
|
||||
|
||||
|
||||
## Visualizing annotations: Service Catalogs
|
||||
|
||||
As the number of microservices and annotations proliferate, running `kubectl describe` can get tedious. Moreover, using `kubectl describe` requires every developer to have some direct access to the Kubernetes cluster. Over the past few years, service catalogs have gained greater visibility in the Kubernetes ecosystem. Popularized by tools such as [Shopify's ServicesDB](https://shopify.engineering/scaling-mobile-development-by-treating-apps-as-services) and [Spotify's System Z](https://dzone.com/articles/modeling-microservices-at-spotify-with-petter-mari), service catalogs are internally-facing developer portals that present critical information about microservices.
|
||||
|
||||
Note that these service catalogs should not be confused with the [Kubernetes Service Catalog project](https://svc-cat.io/). Built on the Open Service Broker API, the Kubernetes Service Catalog enables Kubernetes operators to plug in different services (e.g., databases) to their cluster.
|
||||
|
||||
## Annotate your services now and thank yourself later
|
||||
|
||||
Much like implementing observability within microservice systems, you often don’t realize that you need human service discovery until it’s too late. Don't wait until something is on fire in production to start wishing you had implemented better metrics and also documented how to get in touch with the part of your organization that looks after it.
|
||||
|
||||
There's enormous benefits to building an effective “version 0” service: a [_dancing skeleton_](https://containerjournal.com/topics/container-management/dancing-skeleton-apis-and-microservices/) application with a thin slice of complete functionality that can be deployed to production with a minimal yet effective continuous delivery pipeline.
|
||||
|
||||
Adding service annotations should be an essential part of your “version 0” for all of your services. Add them now, and you’ll thank yourself later.
|
||||
@@ -0,0 +1,80 @@
|
||||
---
|
||||
layout: blog
|
||||
title: 'Graceful Node Shutdown Goes Beta'
|
||||
date: 2021-04-21
|
||||
slug: graceful-node-shutdown-beta
|
||||
---
|
||||
|
||||
**Authors:** David Porter (Google), Mrunal Patel (Red Hat), and Tim Bannister (The Scale Factory)
|
||||
|
||||
Graceful node shutdown, beta in 1.21, enables kubelet to gracefully evict pods during a node shutdown.
|
||||
|
||||
Kubernetes is a distributed system and as such we need to be prepared for inevitable failures — nodes will fail, containers might crash or be restarted, and - ideally - your workloads will be able to withstand these catastrophic events.
|
||||
|
||||
One of the common classes of issues are workload failures on node shutdown or restart. The best practice prior to bringing your node down is to [safely drain and cordon your node](/docs/tasks/administer-cluster/safely-drain-node/). This will ensure that all pods running on this node can safely be evicted. An eviction will ensure your pods can follow the expected [pod termination lifecycle](/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination) meaning receiving a SIGTERM in your container and/or running `preStopHooks`.
|
||||
|
||||
Prior to Kubernetes 1.20 (when graceful node shutdown was introduced as an alpha feature), safe node draining was not easy: it required users to manually take action and drain the node beforehand. If someone or something shut down your node without draining it first, most likely your pods would not be safely evicted from your node and shutdown abruptly. Other services talking to those pods might see errors due to the pods exiting abruptly. Some examples of this situation may be caused by a reboot due to security patches or preemption of short lived cloud compute instances.
|
||||
|
||||
Kubernetes 1.21 brings graceful node shutdown to beta. Graceful node shutdown gives you more control over some of those unexpected shutdown situations. With graceful node shutdown, the kubelet is aware of underlying system shutdown events and can propagate these events to pods, ensuring containers can shut down as gracefully as possible. This gives the containers a chance to checkpoint their state or release back any resources they are holding.
|
||||
|
||||
Note, that for the best availability, even with graceful node shutdown, you should still design your deployments to be resilient to node failures.
|
||||
|
||||
## How does it work?
|
||||
On Linux, your system can shut down in many different situations. For example:
|
||||
* A user or script running `shutdown -h now` or `systemctl poweroff` or `systemctl reboot`.
|
||||
* Physically pressing a power button on the machine.
|
||||
* Stopping a VM instance on a cloud provider, e.g. `gcloud compute instances stop` on GCP.
|
||||
* A Preemptible VM or Spot Instance that your cloud provider can terminate unexpectedly, but with a brief warning.
|
||||
|
||||
|
||||
Many of these situations can be unexpected and there is no guarantee that a cluster administrator drained the node prior to these events. With the graceful node shutdown feature, kubelet uses a systemd mechanism called ["Inhibitor Locks"](https://www.freedesktop.org/wiki/Software/systemd/inhibit) to allow draining in most cases. Using Inhibitor Locks, kubelet instructs systemd to postpone system shutdown for a specified duration, giving a chance for the node to drain and evict pods on the system.
|
||||
|
||||
Kubelet makes use of this mechanism to ensure your pods will be terminated cleanly. When the kubelet starts, it acquires a systemd delay-type inhibitor lock. When the system is about to shut down, the kubelet can delay that shutdown for a configurable, short duration utilizing the delay-type inhibitor lock it acquired earlier. This gives your pods extra time to terminate. As a result, even during unexpected shutdowns, your application will receive a SIGTERM, [preStop hooks](/docs/concepts/containers/container-lifecycle-hooks/#container-hooks) will execute, and kubelet will properly update `Ready` node condition and respective pod statuses to the api-server.
|
||||
|
||||
For example, on a node with graceful node shutdown enabled, you can see that the inhibitor lock is taken by the kubelet:
|
||||
|
||||
```
|
||||
kubelet-node ~ # systemd-inhibit --list
|
||||
Who: kubelet (UID 0/root, PID 1515/kubelet)
|
||||
What: shutdown
|
||||
Why: Kubelet needs time to handle node shutdown
|
||||
Mode: delay
|
||||
|
||||
1 inhibitors listed.
|
||||
```
|
||||
|
||||
One important consideration we took when designing this feature is that not all pods are created equal. For example, some of the pods running on a node such as a logging related daemonset should stay running as long as possible to capture important logs during the shutdown itself. As a result, pods are split into two categories: "regular" and "critical". [Critical pods](/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods/#marking-pod-as-critical) are those that have `priorityClassName` set to `system-cluster-critical` or `system-node-critical`; all other pods are considered regular.
|
||||
|
||||
In our example, the logging DaemonSet would run as a critical pod. During the graceful node shutdown, regular pods are terminated first, followed by critical pods. As an example, this would allow a critical pod associated with a logging daemonset to continue functioning, and collecting logs during the termination of regular pods.
|
||||
|
||||
We will evaluate during the beta phase if we need more flexibility for different pod priority classes and add support if needed, please let us know if you have some scenarios in mind.
|
||||
|
||||
|
||||
## How do I use it?
|
||||
|
||||
Graceful node shutdown is controlled with the `GracefulNodeShutdown` [feature gate](/docs/reference/command-line-tools-reference/feature-gates) and is enabled by default in Kubernetes 1.21.
|
||||
|
||||
You can configure the graceful node shutdown behavior using two kubelet configuration options: `ShutdownGracePeriod` and `ShutdownGracePeriodCriticalPods`. To configure these options, you edit the kubelet configuration file that is passed to kubelet via the `--config` flag; for more details, refer to [Set kubelet parameters via a configuration file](/docs/tasks/administer-cluster/kubelet-config-file/).
|
||||
|
||||
|
||||
During a shutdown, kubelet terminates pods in two phases. You can configure how long each of these phases lasts.
|
||||
1. Terminate regular pods running on the node.
|
||||
2. Terminate critical pods running on the node.
|
||||
|
||||
The settings that control the duration of shutdown are:
|
||||
* `ShutdownGracePeriod`
|
||||
* Specifies the total duration that the node should delay the shutdown by. This is the total grace period for pod termination for both regular and critical pods.
|
||||
* `ShutdownGracePeriodCriticalPods`
|
||||
* Specifies the duration used to terminate critical pods during a node shutdown. This should be less than `ShutdownGracePeriod`.
|
||||
|
||||
For example, if `ShutdownGracePeriod=30s`, and `ShutdownGracePeriodCriticalPods=10s`, kubelet will delay the node shutdown by 30 seconds. During this time, the first 20 seconds (30-10) would be reserved for gracefully terminating normal pods, and the last 10 seconds would be reserved for terminating critical pods.
|
||||
|
||||
Note that by default, both configuration options described above, `ShutdownGracePeriod` and `ShutdownGracePeriodCriticalPods` are set to zero, so you will need to configure them as appropriate for your environment to activate graceful node shutdown functionality.
|
||||
|
||||
## How can I learn more?
|
||||
* Read the [documentation](/docs/concepts/architecture/nodes/#graceful-node-shutdown)
|
||||
* Read the enhancement proposal, [KEP 2000](https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/2000-graceful-node-shutdown)
|
||||
* View the [code](https://github.com/kubernetes/kubernetes/tree/release-1.21/pkg/kubelet/nodeshutdown)
|
||||
|
||||
## How do I get involved?
|
||||
Your feedback is always welcome! SIG Node meets regularly and can be reached via [Slack](https://slack.k8s.io) (channel `#sig-node`), or the SIG's [mailing list](https://github.com/kubernetes/community/tree/master/sig-node#contact)
|
||||
|
After Width: | Height: | Size: 274 KiB |
|
After Width: | Height: | Size: 118 KiB |
@@ -0,0 +1,197 @@
|
||||
|
||||
---
|
||||
layout: blog
|
||||
title: 'Evolving Kubernetes networking with the Gateway API'
|
||||
date: 2021-04-22
|
||||
slug: evolving-kubernetes-networking-with-the-gateway-api
|
||||
---
|
||||
|
||||
**Authors:** Mark Church (Google), Harry Bagdi (Kong), Daneyon Hanson (Red Hat), Nick Young (VMware), Manuel Zapf (Traefik Labs)
|
||||
|
||||
The Ingress resource is one of the many Kubernetes success stories. It created a [diverse ecosystem of Ingress controllers](/docs/concepts/services-networking/ingress-controllers/) which were used across hundreds of thousands of clusters in a standardized and consistent way. This standardization helped users adopt Kubernetes. However, five years after the creation of Ingress, there are signs of fragmentation into different but [strikingly similar CRDs](https://dave.cheney.net/paste/ingress-is-dead-long-live-ingressroute.pdf) and [overloaded annotations](https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/). The same portability that made Ingress pervasive also limited its future.
|
||||
|
||||
It was at Kubecon 2019 San Diego when a passionate group of contributors gathered to discuss the [evolution of Ingress](https://static.sched.com/hosted_files/kccncna19/a5/Kubecon%20San%20Diego%202019%20-%20Evolving%20the%20Kubernetes%20Ingress%20APIs%20to%20GA%20and%20Beyond%20%5BPUBLIC%5D.pdf). The discussion overflowed to the hotel lobby across the street and what came out of it would later be known as the [Gateway API](https://gateway-api.sigs.k8s.io). This discussion was based on a few key assumptions:
|
||||
|
||||
1. The API standards underlying route matching, traffic management, and service exposure are commoditized and provide little value to their implementers and users as custom APIs
|
||||
2. It’s possible to represent L4/L7 routing and traffic management through common core API resources
|
||||
3. It’s possible to provide extensibility for more complex capabilities in a way that does not sacrifice the user experience of the core API
|
||||
|
||||
|
||||
## Introducing the Gateway API
|
||||
|
||||
This led to design principles that allow the Gateway API to improve upon Ingress:
|
||||
|
||||
- **Expressiveness** - In addition to HTTP host/path matching and TLS, Gateway API can express capabilities like HTTP header manipulation, traffic weighting & mirroring, TCP/UDP routing, and other capabilities that were only possible in Ingress through custom annotations.
|
||||
- **Role-oriented design** - The API resource model reflects the separation of responsibilities that is common in routing and Kubernetes service networking.
|
||||
- **Extensibility** - The resources allow arbitrary configuration attachment at various layers within the API. This makes granular customization possible at the most appropriate places.
|
||||
- **Flexible conformance** - The Gateway API defines varying conformance levels - core (mandatory support), extended (portable if supported), and custom (no portability guarantee), known together as [flexible conformance](https://gateway-api.sigs.k8s.io/concepts/guidelines/#conformance). This promotes a highly portable core API (like Ingress) that still gives flexibility for Gateway controller implementers.
|
||||
|
||||
### What does the Gateway API look like?
|
||||
|
||||
The Gateway API introduces a few new resource types:
|
||||
|
||||
- **[GatewayClasses](https://gateway-api.sigs.k8s.io/references/spec/#networking.x-k8s.io/v1alpha1.GatewayClass)** are cluster-scoped resources that act as templates to explicitly define behavior for Gateways derived from them. This is similar in concept to StorageClasses, but for networking data-planes.
|
||||
- **[Gateways](https://gateway-api.sigs.k8s.io/references/spec/#networking.x-k8s.io/v1alpha1.Gateway)** are the deployed instances of GatewayClasses. They are the logical representation of the data-plane which performs routing, which may be in-cluster proxies, hardware LBs, or cloud LBs.
|
||||
- **Routes** are not a single resource, but represent many different protocol-specific Route resources. The [HTTPRoute](https://gateway-api.sigs.k8s.io/references/spec/#networking.x-k8s.io/v1alpha1.HTTPRoute) has matching, filtering, and routing rules that get applied to Gateways that can process HTTP and HTTPS traffic. Similarly, there are [TCPRoutes](https://gateway-api.sigs.k8s.io/references/spec/#networking.x-k8s.io/v1alpha1.TCPRoute), [UDPRoutes](https://gateway-api.sigs.k8s.io/references/spec/#networking.x-k8s.io/v1alpha1.UDPRoute), and [TLSRoutes](https://gateway-api.sigs.k8s.io/references/spec/#networking.x-k8s.io/v1alpha1.TLSRoute) which also have protocol-specific semantics. This model also allows the Gateway API to incrementally expand its protocol support in the future.
|
||||
|
||||

|
||||
|
||||
### Gateway Controller Implementations
|
||||
|
||||
The good news is that although Gateway is in [Alpha](https://github.com/kubernetes-sigs/gateway-api/releases), there are already several [Gateway controller implementations](https://gateway-api.sigs.k8s.io/references/implementations/) that you can run. Since it’s a standardized spec, the following example could be run on any of them and should function the exact same way. Check out [getting started](https://gateway-api.sigs.k8s.io/guides/getting-started/) to see how to install and use one of these Gateway controllers.
|
||||
|
||||
## Getting Hands-on with the Gateway API
|
||||
|
||||
In the following example, we’ll demonstrate the relationships between the different API Resources and walk you through a common use case:
|
||||
|
||||
* Team foo has their app deployed in the foo Namespace. They need to control the routing logic for the different pages of their app.
|
||||
* Team bar is running in the bar Namespace. They want to be able to do blue-green rollouts of their application to reduce risk.
|
||||
* The platform team is responsible for managing the load balancer and network security of all the apps in the Kubernetes cluster.
|
||||
|
||||
The following foo-route does path matching to various Services in the foo Namespace and also has a default route to a 404 server. This exposes foo-auth and foo-home Services via `foo.example.com/login` and `foo.example.com/home` respectively.:
|
||||
|
||||
|
||||
```yaml
|
||||
kind: HTTPRoute
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: foo-route
|
||||
namespace: foo
|
||||
labels:
|
||||
gateway: external-https-prod
|
||||
spec:
|
||||
hostnames:
|
||||
- "foo.example.com"
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: Prefix
|
||||
value: /login
|
||||
forwardTo:
|
||||
- serviceName: foo-auth
|
||||
port: 8080
|
||||
- matches:
|
||||
- path:
|
||||
type: Prefix
|
||||
value: /home
|
||||
forwardTo:
|
||||
- serviceName: foo-home
|
||||
port: 8080
|
||||
- matches:
|
||||
- path:
|
||||
type: Prefix
|
||||
value: /
|
||||
forwardTo:
|
||||
- serviceName: foo-404
|
||||
port: 8080
|
||||
```
|
||||
|
||||
|
||||
The bar team, operating in the bar Namespace of the same Kubernetes cluster, also wishes to expose their application to the internet, but they also want to control their own canary and blue-green rollouts. The following HTTPRoute is configured for the following behavior:
|
||||
|
||||
* For traffic to `bar.example.com`:
|
||||
* Send 90% of the traffic to bar-v1
|
||||
* Send 10% of the traffic to bar-v2
|
||||
* For traffic to `bar.example.com` with the HTTP header `env: canary`:
|
||||
|
||||
* Send all the traffic to bar-v2
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
```yaml
|
||||
kind: HTTPRoute
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: bar-route
|
||||
namespace: bar
|
||||
labels:
|
||||
gateway: external-https-prod
|
||||
spec:
|
||||
hostnames:
|
||||
- "bar.example.com"
|
||||
rules:
|
||||
- forwardTo:
|
||||
- serviceName: bar-v1
|
||||
port: 8080
|
||||
weight: 90
|
||||
- serviceName: bar-v2
|
||||
port: 8080
|
||||
weight: 10
|
||||
- matches:
|
||||
- headers:
|
||||
values:
|
||||
env: canary
|
||||
forwardTo:
|
||||
- serviceName: bar-v2
|
||||
port: 8080
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Route and Gateway Binding
|
||||
|
||||
So we have two HTTPRoutes matching and routing traffic to different Services. You might be wondering, where are these Services accessible? Through which networks or IPs are they exposed?
|
||||
|
||||
How Routes are exposed to clients is governed by [Route binding](https://gateway-api.sigs.k8s.io/concepts/api-overview/#route-binding), which describes how Routes and Gateways create a bidirectional relationship between each other. When Routes are bound to a Gateway it means their collective routing rules are configured on the underlying load balancers or proxies and the Routes are accessible through the Gateway. Thus, a Gateway is a logical representation of a networking data plane that can be configured through Routes.
|
||||
|
||||
|
||||

|
||||
|
||||
### Administrative Delegation
|
||||
|
||||
The split between Gateway and Route resources allows the cluster administrator to delegate some of the routing configuration to individual teams while still retaining centralized control. The following Gateway resource exposes HTTPS on port 443 and terminates all traffic on the port with a certificate controlled by the cluster administrator.
|
||||
|
||||
|
||||
```yaml
|
||||
kind: Gateway
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: prod-web
|
||||
spec:
|
||||
gatewayClassName: acme-lb
|
||||
listeners:
|
||||
- protocol: HTTPS
|
||||
port: 443
|
||||
routes:
|
||||
kind: HTTPRoute
|
||||
selector:
|
||||
matchLabels:
|
||||
gateway: external-https-prod
|
||||
namespaces:
|
||||
from: All
|
||||
tls:
|
||||
certificateRef:
|
||||
name: admin-controlled-cert
|
||||
```
|
||||
|
||||
|
||||
The following HTTPRoute shows how the Route can ensure it matches the Gateway's selector via it’s `kind` (HTTPRoute) and resource labels (`gateway=external-https-prod`).
|
||||
|
||||
|
||||
```yaml
|
||||
# Matches the required kind selector on the Gateway
|
||||
kind: HTTPRoute
|
||||
apiVersion: networking.x-k8s.io/v1alpha1
|
||||
metadata:
|
||||
name: foo-route
|
||||
namespace: foo-ns
|
||||
labels:
|
||||
|
||||
# Matches the required label selector on the Gateway
|
||||
gateway: external-https-prod
|
||||
...
|
||||
```
|
||||
|
||||
### Role Oriented Design
|
||||
|
||||
When you put it all together, you have a single load balancing infrastructure that can be safely shared by multiple teams. The Gateway API is not only a more expressive API for advanced routing, but is also a role-oriented API, designed for multi-tenant infrastructure. Its extensibility ensures that it will evolve for future use-cases while preserving portability. Ultimately these characteristics will allow the Gateway API to adapt to different organizational models and implementations well into the future.
|
||||
|
||||
### Try it out and get involved
|
||||
|
||||
There are many resources to check out to learn more.
|
||||
|
||||
* Check out the [user guides](https://gateway-api.sigs.k8s.io/guides/getting-started/) to see what use-cases can be addressed.
|
||||
* Try out one of the [existing Gateway controllers ](https://gateway-api.sigs.k8s.io/references/implementations/)
|
||||
* Or [get involved](https://gateway-api.sigs.k8s.io/contributing/community/) and help design and influence the future of Kubernetes service networking!
|
||||
|
After Width: | Height: | Size: 91 KiB |
@@ -0,0 +1,80 @@
|
||||
---
|
||||
layout: blog
|
||||
title: 'Kubernetes 1.21: Metrics Stability hits GA'
|
||||
date: 2021-04-23
|
||||
slug: kubernetes-release-1.21-metrics-stability-ga
|
||||
---
|
||||
|
||||
**Authors**: Han Kang (Google), Elana Hashman (Red Hat)
|
||||
|
||||
Kubernetes 1.21 marks the graduation of the metrics stability framework and along with it, the first officially supported stable metrics. Not only do stable metrics come with supportability guarantees, the metrics stability framework brings escape hatches that you can use if you encounter problematic metrics.
|
||||
|
||||
See the list of [stable Kubernetes metrics here](https://github.com/kubernetes/kubernetes/blob/master/test/instrumentation/testdata/stable-metrics-list.yaml)
|
||||
|
||||
### What are stable metrics and why do we need them?
|
||||
A stable metric is one which, from a consumption point of view, can be reliably consumed across a number of Kubernetes versions without risk of ingestion failure.
|
||||
|
||||
Metrics stability is an ongoing community concern. Cluster monitoring infrastructure often assumes the stability of some control plane metrics, so we have introduced a mechanism for versioning metrics as a proper API, with stability guarantees around a formal metrics deprecation process.
|
||||
|
||||
### What are the stability levels for metrics?
|
||||
|
||||
Metrics can currently have one of two stability levels: alpha or stable.
|
||||
|
||||
_Alpha metrics_ have no stability guarantees; as such they can be modified or deleted at any time. At this time, all Kubernetes metrics implicitly fall into this category.
|
||||
|
||||
_Stable metrics_ can be guaranteed to not change, except that the metric may become marked deprecated for a future Kubernetes version. By not change, we mean three things:
|
||||
|
||||
1. the metric itself will not be deleted or renamed
|
||||
2. the type of metric will not be modified
|
||||
3. no labels can be added or removed from this metric
|
||||
|
||||
From an ingestion point of view, it is backwards-compatible to add or remove possible values for labels which already do exist, but not labels themselves. Therefore, adding or removing values from an existing label is permitted. Stable metrics can also be marked as deprecated for a future Kubernetes version, since this is tracked in a metadata field and does not actually change the metric itself.
|
||||
|
||||
Removing or adding labels from stable metrics is not permitted. In order to add or remove a label from an existing stable metric, one would have to introduce a new metric and deprecate the stable one; otherwise this would violate compatibility agreements.
|
||||
|
||||
|
||||
#### How are metrics deprecated?
|
||||
|
||||
While deprecation policies only affect stability guarantees for stable metrics (and not alpha ones), deprecation information may be optionally provided on alpha metrics to help component owners inform users of future intent and assist with transition plans.
|
||||
|
||||
A stable metric undergoing the deprecation process signals that the metric will eventually be deleted. The metrics deprecation lifecycle looks roughly like this (with each stage representing a Kubernetes release):
|
||||
|
||||

|
||||
|
||||
_Deprecated metrics_ have the same stability guarantees of their stable counterparts. If a stable metric is deprecated, then a deprecated stable metric is guaranteed to not change. When deprecating a stable metric, a future Kubernetes release is specified as the point from which the metric will be considered deprecated.
|
||||
|
||||
Deprecated metrics will have their description text prefixed with a deprecation notice string “(Deprecated from x.y)” and a warning log will be emitted during metric registration, in the spirit of the official Kubernetes deprecation policy.
|
||||
|
||||
Like their stable metric counterparts, deprecated metrics will be automatically registered to the metrics endpoint. On a subsequent release (when the metric's deprecatedVersion is equal to _current\_kubernetes\_version - 4_)), a deprecated metric will become a _hidden_ metric. _Hidden metrics_ are not automatically registered, and hence are hidden by default from end users. These hidden metrics can be explicitly re-enabled for one release after they reach the hidden state, to provide a migration path for cluster operators.
|
||||
|
||||
|
||||
#### As an owner of a Kubernetes component, how do I add stable metrics?
|
||||
|
||||
During metric instantiation, stability can be specified by setting the metadata field, StabilityLevel, to “Stable”. When a StabilityLevel is not explicitly set, metrics default to “Alpha” stability. Note that metrics which have fields determined at runtime cannot be marked as Stable. Stable metrics will be detected during static analysis during the pre-commit phase, and must be reviewed by sig-instrumentation.
|
||||
|
||||
```golang
|
||||
var metricDefinition = kubemetrics.CounterOpts{
|
||||
Name: "some_metric",
|
||||
Help: "some description",
|
||||
StabilityLevel: kubemetrics.STABLE,
|
||||
}
|
||||
```
|
||||
For more examples of setting metrics stability and deprecation, see the [Metrics Stability KEP](http://bit.ly/metrics-stability).
|
||||
|
||||
|
||||
### How do I get involved?
|
||||
|
||||
This project, like all of Kubernetes, is the result of hard work by many contributors from diverse backgrounds working together.
|
||||
We offer a huge thank you to all the contributors in Kubernetes community who helped review the design and implementation of the project, including but not limited to the following:
|
||||
|
||||
- Han Kang (logicalhan)
|
||||
- Frederic Branczyk (brancz)
|
||||
- Marek Siarkowicz (serathius)
|
||||
- Elana Hashman (ehashman)
|
||||
- Solly Ross (DirectXMan12)
|
||||
- Stefan Schimanski (sttts)
|
||||
- David Ashpole (dashpole)
|
||||
- Yuchen Zhou (yoyinzyc)
|
||||
- Yu Yi (erain)
|
||||
|
||||
If you’re interested in getting involved with the design and development of instrumentation or any part of the Kubernetes metrics system, join the [Kubernetes Instrumentation Special Interest Group (SIG)](https://github.com/kubernetes/community/tree/master/sig-instrumentation). We’re rapidly growing and always welcome new contributors.
|
||||
|
After Width: | Height: | Size: 39 KiB |
@@ -0,0 +1,268 @@
|
||||
---
|
||||
layout: blog
|
||||
title: 'Using Finalizers to Control Deletion'
|
||||
date: 2021-05-14
|
||||
slug: using-finalizers-to-control-deletion
|
||||
---
|
||||
|
||||
**Authors:** Aaron Alpar (Kasten)
|
||||
|
||||
Deleting objects in Kubernetes can be challenging. You may think you’ve deleted something, only to find it still persists. While issuing a `kubectl delete` command and hoping for the best might work for day-to-day operations, understanding how Kubernetes `delete` commands operate will help you understand why some objects linger after deletion.
|
||||
|
||||
In this post, I’ll look at:
|
||||
|
||||
- What properties of a resource govern deletion
|
||||
- How finalizers and owner references impact object deletion
|
||||
- How the propagation policy can be used to change the order of deletions
|
||||
- How deletion works, with examples
|
||||
|
||||
For simplicity, all examples will use ConfigMaps and basic shell commands to demonstrate the process. We’ll explore how the commands work and discuss repercussions and results from using them in practice.
|
||||
|
||||
## The basic `delete`
|
||||
|
||||
Kubernetes has several different commands you can use that allow you to create, read, update, and delete objects. For the purpose of this blog post, we’ll focus on four `kubectl` commands: `create`, `get`, `patch`, and `delete`.
|
||||
|
||||
Here are examples of the basic `kubectl delete` command:
|
||||
|
||||
```
|
||||
kubectl create configmap mymap
|
||||
configmap/mymap created
|
||||
```
|
||||
|
||||
```
|
||||
kubectl get configmap/mymap
|
||||
NAME DATA AGE
|
||||
mymap 0 12s
|
||||
```
|
||||
|
||||
```
|
||||
kubectl delete configmap/mymap
|
||||
configmap "mymap" deleted
|
||||
```
|
||||
|
||||
```
|
||||
kubectl get configmap/mymap
|
||||
Error from server (NotFound): configmaps "mymap" not found
|
||||
```
|
||||
|
||||
Shell commands preceded by `$` are followed by their output. You can see that we begin with a `kubectl create configmap mymap`, which will create the empty configmap `mymap`. Next, we need to `get` the configmap to prove it exists. We can then delete that configmap. Attempting to `get` it again produces an HTTP 404 error, which means the configmap is not found.
|
||||
|
||||
The state diagram for the basic `delete` command is very simple:
|
||||
|
||||
|
||||
{{<figure width="495" src="/images/blog/2021-05-14-using-finalizers-to-control-deletion/state-diagram-delete.png" caption="State diagram for delete">}}
|
||||
|
||||
Although this operation is straightforward, other factors may interfere with the deletion, including finalizers and owner references.
|
||||
|
||||
## Understanding Finalizers
|
||||
|
||||
When it comes to understanding resource deletion in Kubernetes, knowledge of how finalizers work is helpful and can help you understand why some objects don’t get deleted.
|
||||
|
||||
Finalizers are keys on resources that signal pre-delete operations. They control the garbage collection on resources, and are designed to alert controllers what cleanup operations to perform prior to removing a resource. However, they don’t necessarily name code that should be executed; finalizers on resources are basically just lists of keys much like annotations. Like annotations, they can be manipulated.
|
||||
|
||||
Some common finalizers you’ve likely encountered are:
|
||||
|
||||
- `kubernetes.io/pv-protection`
|
||||
- `kubernetes.io/pvc-protection`
|
||||
|
||||
The finalizers above are used on volumes to prevent accidental deletion. Similarly, some finalizers can be used to prevent deletion of any resource but are not managed by any controller.
|
||||
|
||||
Below with a custom configmap, which has no properties but contains a finalizer:
|
||||
|
||||
```
|
||||
cat <<EOF | kubectl create -f -
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: mymap
|
||||
finalizers:
|
||||
- kubernetes
|
||||
EOF
|
||||
```
|
||||
|
||||
The configmap resource controller doesn't understand what to do with the `kubernetes` finalizer key. I term these “dead” finalizers for configmaps as it is normally used on namespaces. Here’s what happen upon attempting to delete the configmap:
|
||||
|
||||
```
|
||||
kubectl delete configmap/mymap &
|
||||
configmap "mymap" deleted
|
||||
jobs
|
||||
[1]+ Running kubectl delete configmap/mymap
|
||||
```
|
||||
|
||||
Kubernetes will report back that the object has been deleted, however, it hasn’t been deleted in a traditional sense. Rather, it’s in the process of deletion. When we attempt to `get` that object again, we discover the object has been modified to include the deletion timestamp.
|
||||
|
||||
```
|
||||
kubectl get configmap/mymap -o yaml
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
creationTimestamp: "2020-10-22T21:30:18Z"
|
||||
deletionGracePeriodSeconds: 0
|
||||
deletionTimestamp: "2020-10-22T21:30:34Z"
|
||||
finalizers:
|
||||
- kubernetes
|
||||
name: mymap
|
||||
namespace: default
|
||||
resourceVersion: "311456"
|
||||
selfLink: /api/v1/namespaces/default/configmaps/mymap
|
||||
uid: 93a37fed-23e3-45e8-b6ee-b2521db81638
|
||||
```
|
||||
|
||||
In short, what’s happened is that the object was updated, not deleted. That’s because Kubernetes saw that the object contained finalizers and put it into a read-only state. The deletion timestamp signals that the object can only be read, with the exception of removing the finalizer key updates. In other words, the deletion will not be complete until we edit the object and remove the finalizer.
|
||||
|
||||
Here's a demonstration of using the `patch` command to remove finalizers. If we want to delete an object, we can simply patch it on the command line to remove the finalizers. In this way, the deletion that was running in the background will complete and the object will be deleted. When we attempt to `get` that configmap, it will be gone.
|
||||
|
||||
```
|
||||
kubectl patch configmap/mymap \
|
||||
--type json \
|
||||
--patch='[ { "op": "remove", "path": "/metadata/finalizers" } ]'
|
||||
configmap/mymap patched
|
||||
[1]+ Done kubectl delete configmap/mymap
|
||||
|
||||
kubectl get configmap/mymap -o yaml
|
||||
Error from server (NotFound): configmaps "mymap" not found
|
||||
```
|
||||
|
||||
Here's a state diagram for finalization:
|
||||
|
||||
{{<figure width="617" src="/images/blog/2021-05-14-using-finalizers-to-control-deletion/state-diagram-finalize.png" caption="State diagram for finalize">}}
|
||||
|
||||
So, if you attempt to delete an object that has a finalizer on it, it will remain in finalization until the controller has removed the finalizer keys or the finalizers are removed using Kubectl. Once that finalizer list is empty, the object can actually be reclaimed by Kubernetes and put into a queue to be deleted from the registry.
|
||||
|
||||
## Owner References
|
||||
|
||||
Owner references describe how groups of objects are related. They are properties on resources that specify the relationship to one another, so entire trees of resources can be deleted.
|
||||
|
||||
Finalizer rules are processed when there are owner references. An owner reference consists of a name and a UID. Owner references link resources within the same namespace, and it also needs a UID for that reference to work. Pods typically have owner references to the owning replica set. So, when deployments or stateful sets are deleted, then the child replica sets and pods are deleted in the process.
|
||||
|
||||
Here are some examples of owner references and how they work. In the first example, we create a parent object first, then the child. The result is a very simple configmap that contains an owner reference to its parent:
|
||||
|
||||
```
|
||||
cat <<EOF | kubectl create -f -
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: mymap-parent
|
||||
EOF
|
||||
CM_UID=$(kubectl get configmap mymap-parent -o jsonpath="{.metadata.uid}")
|
||||
|
||||
cat <<EOF | kubectl create -f -
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: mymap-child
|
||||
ownerReferences:
|
||||
- apiVersion: v1
|
||||
kind: ConfigMap
|
||||
name: mymap-parent
|
||||
uid: $CM_UID
|
||||
EOF
|
||||
```
|
||||
|
||||
Deleting the child object when an owner reference is involved does not delete the parent:
|
||||
|
||||
```
|
||||
kubectl get configmap
|
||||
NAME DATA AGE
|
||||
mymap-child 0 12m4s
|
||||
mymap-parent 0 12m4s
|
||||
|
||||
kubectl delete configmap/mymap-child
|
||||
configmap "mymap-child" deleted
|
||||
|
||||
kubectl get configmap
|
||||
NAME DATA AGE
|
||||
mymap-parent 0 12m10s
|
||||
```
|
||||
|
||||
In this example, we re-created the parent-child configmaps from above. Now, when deleting from the parent (instead of the child) with an owner reference from the child to the parent, when we `get` the configmaps, none are in the namespace:
|
||||
|
||||
```
|
||||
kubectl get configmap
|
||||
NAME DATA AGE
|
||||
mymap-child 0 10m2s
|
||||
mymap-parent 0 10m2s
|
||||
|
||||
kubectl delete configmap/mymap-parent
|
||||
configmap "mymap-parent" deleted
|
||||
|
||||
kubectl get configmap
|
||||
No resources found in default namespace.
|
||||
```
|
||||
|
||||
To sum things up, when there's an override owner reference from a child to a parent, deleting the parent deletes the children automatically. This is called `cascade`. The default for cascade is `true`, however, you can use the --cascade=false option for `kubectl delete` to delete an object and orphan its children.
|
||||
|
||||
In the following example, there is a parent and a child. Notice the owner references are still included. If I delete the parent using --cascade=false, the parent is deleted but the child still exists:
|
||||
|
||||
```
|
||||
kubectl get configmap
|
||||
NAME DATA AGE
|
||||
mymap-child 0 13m8s
|
||||
mymap-parent 0 13m8s
|
||||
|
||||
kubectl delete --cascade=false configmap/mymap-parent
|
||||
configmap "mymap-parent" deleted
|
||||
|
||||
kubectl get configmap
|
||||
NAME DATA AGE
|
||||
mymap-child 0 13m21s
|
||||
```
|
||||
|
||||
The --cascade option links to the propagation policy in the API, which allows you to change the order in which objects are deleted within a tree. In the following example uses API access to craft a custom delete API call with the background propagation policy:
|
||||
|
||||
```
|
||||
kubectl proxy --port=8080 &
|
||||
Starting to serve on 127.0.0.1:8080
|
||||
|
||||
curl -X DELETE \
|
||||
localhost:8080/api/v1/namespaces/default/configmaps/mymap-parent \
|
||||
-d '{ "kind":"DeleteOptions", "apiVersion":"v1", "propagationPolicy":"Background" }' \
|
||||
-H "Content-Type: application/json"
|
||||
{
|
||||
"kind": "Status",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {},
|
||||
"status": "Success",
|
||||
"details": { ... }
|
||||
}
|
||||
```
|
||||
|
||||
Note that the propagation policy cannot be specified on the command line using kubectl. You have to specify it using a custom API call. Simply create a proxy, so you have access to the API server from the client, and execute a `curl` command with just a URL to execute that `delete` command.
|
||||
|
||||
There are three different options for the propagation policy:
|
||||
|
||||
- `Foreground`: Children are deleted before the parent (post-order)
|
||||
- `Background`: Parent is deleted before the children (pre-order)
|
||||
- `Orphan`: Owner references are ignored
|
||||
|
||||
Keep in mind that when you delete an object and owner references have been specified, finalizers will be honored in the process. This can result in trees of objects persisting, and you end up with a partial deletion. At that point, you have to look at any existing owner references on your objects, as well as any finalizers, to understand what’s happening.
|
||||
|
||||
## Forcing a Deletion of a Namespace
|
||||
|
||||
There's one situation that may require forcing finalization for a namespace. If you've deleted a namespace and you've cleaned out all of the objects under it, but the namespace still exists, deletion can be forced by updating the namespace subresource, `finalize`. This informs the namespace controller that it needs to remove the finalizer from the namespace and perform any cleanup:
|
||||
|
||||
```
|
||||
cat <<EOF | curl -X PUT \
|
||||
localhost:8080/api/v1/namespaces/test/finalize \
|
||||
-H "Content-Type: application/json" \
|
||||
--data-binary @-
|
||||
{
|
||||
"kind": "Namespace",
|
||||
"apiVersion": "v1",
|
||||
"metadata": {
|
||||
"name": "test"
|
||||
},
|
||||
"spec": {
|
||||
"finalizers": null
|
||||
}
|
||||
}
|
||||
EOF
|
||||
```
|
||||
|
||||
This should be done with caution as it may delete the namespace only and leave orphan objects within the, now non-exiting, namespace - a confusing state for Kubernetes. If this happens, the namespace can be re-created manually and sometimes the orphaned objects will re-appear under the just-created namespace which will allow manual cleanup and recovery.
|
||||
|
||||
## Key Takeaways
|
||||
|
||||
As these examples demonstrate, finalizers can get in the way of deleting resources in Kubernetes, especially when there are parent-child relationships between objects. Often, there is a reason for adding a finalizer into the code, so you should always investigate before manually deleting it. Owner references allow you to specify and remove trees of resources, although finalizers will be honored in the process. Finally, the propagation policy can be used to specify the order of deletion via a custom API call, giving you control over how objects are deleted. Now that you know a little more about how deletions work in Kubernetes, we recommend you try it out on your own, using a test cluster.
|
||||
|
||||
{{< youtube class="youtube-quote-sm" id="F7-ZxWwf4sY" title="Clean Up Your Room! What Does It Mean to Delete Something in K8s">}}
|
||||
@@ -0,0 +1,467 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Writing a Controller for Pod Labels"
|
||||
date: 2021-06-21
|
||||
slug: writing-a-controller-for-pod-labels
|
||||
---
|
||||
|
||||
**Authors**: Arthur Busser (Padok)
|
||||
|
||||
[Operators][what-is-an-operator] are proving to be an excellent solution to
|
||||
running stateful distributed applications in Kubernetes. Open source tools like
|
||||
the [Operator SDK][operator-sdk] provide ways to build reliable and maintainable
|
||||
operators, making it easier to extend Kubernetes and implement custom
|
||||
scheduling.
|
||||
|
||||
Kubernetes operators run complex software inside your cluster. The open source
|
||||
community has already built [many operators][operatorhub] for distributed
|
||||
applications like Prometheus, Elasticsearch, or Argo CD. Even outside of
|
||||
open source, operators can help to bring new functionality to your Kubernetes
|
||||
cluster.
|
||||
|
||||
An operator is a set of [custom resources][custom-resource-definitions] and a
|
||||
set of [controllers][controllers]. A controller watches for changes to specific
|
||||
resources in the Kubernetes API and reacts by creating, updating, or deleting
|
||||
resources.
|
||||
|
||||
The Operator SDK is best suited for building fully-featured operators.
|
||||
Nonetheless, you can use it to write a single controller. This post will walk
|
||||
you through writing a Kubernetes controller in Go that will add a `pod-name`
|
||||
label to pods that have a specific annotation.
|
||||
|
||||
## Why do we need a controller for this?
|
||||
|
||||
I recently worked on a project where we needed to create a Service that routed
|
||||
traffic to a specific Pod in a ReplicaSet. The problem is that a Service can
|
||||
only select pods by label, and all pods in a ReplicaSet have the same labels.
|
||||
There are two ways to solve this problem:
|
||||
|
||||
1. Create a Service without a selector and manage the Endpoints or
|
||||
EndpointSlices for that Service directly. We would need to write a custom
|
||||
controller to insert our Pod's IP address into those resources.
|
||||
2. Add a label to the Pod with a unique value. We could then use this label in
|
||||
our Service's selector. Again, we would need to write a custom controller to
|
||||
add this label.
|
||||
|
||||
A controller is a control loop that tracks one or more Kubernetes resource
|
||||
types. The controller from option n°2 above only needs to track pods, which
|
||||
makes it simpler to implement. This is the option we are going to walk through
|
||||
by writing a Kubernetes controller that adds a `pod-name` label to our pods.
|
||||
|
||||
StatefulSets [do this natively][statefulset-pod-name-label] by adding a
|
||||
`pod-name` label to each Pod in the set. But what if we don't want to or can't
|
||||
use StatefulSets?
|
||||
|
||||
We rarely create pods directly; most often, we use a Deployment, ReplicaSet, or
|
||||
another high-level resource. We can specify labels to add to each Pod in the
|
||||
PodSpec, but not with dynamic values, so no way to replicate a StatefulSet's
|
||||
`pod-name` label.
|
||||
|
||||
We tried using a [mutating admission webhook][mutating-admission-webhook]. When
|
||||
anyone creates a Pod, the webhook patches the Pod with a label containing the
|
||||
Pod's name. Disappointingly, this does not work: not all pods have a name before
|
||||
being created. For instance, when the ReplicaSet controller creates a Pod, it
|
||||
sends a `namePrefix` to the Kubernetes API server and not a `name`. The API
|
||||
server generates a unique name before persisting the new Pod to etcd, but only
|
||||
after calling our admission webhook. So in most cases, we can't know a Pod's
|
||||
name with a mutating webhook.
|
||||
|
||||
Once a Pod exists in the Kubernetes API, it is mostly immutable, but we can
|
||||
still add a label. We can even do so from the command line:
|
||||
|
||||
```bash
|
||||
kubectl label my-pod my-label-key=my-label-value
|
||||
```
|
||||
|
||||
We need to watch for changes to any pods in the Kubernetes API and add the label
|
||||
we want. Rather than do this manually, we are going to write a controller that
|
||||
does it for us.
|
||||
|
||||
## Bootstrapping a controller with the Operator SDK
|
||||
|
||||
A controller is a reconciliation loop that reads the desired state of a resource
|
||||
from the Kubernetes API and takes action to bring the cluster's actual state
|
||||
closer to the desired state.
|
||||
|
||||
In order to write this controller as quickly as possible, we are going to use
|
||||
the Operator SDK. If you don't have it installed, follow the
|
||||
[official documentation][operator-sdk-installation].
|
||||
|
||||
```terminal
|
||||
$ operator-sdk version
|
||||
operator-sdk version: "v1.4.2", commit: "4b083393be65589358b3e0416573df04f4ae8d9b", kubernetes version: "v1.19.4", go version: "go1.15.8", GOOS: "darwin", GOARCH: "amd64"
|
||||
```
|
||||
|
||||
Let's create a new directory to write our controller in:
|
||||
|
||||
```bash
|
||||
mkdir label-operator && cd label-operator
|
||||
```
|
||||
|
||||
Next, let's initialize a new operator, to which we will add a single controller.
|
||||
To do this, you will need to specify a domain and a repository. The domain
|
||||
serves as a prefix for the group your custom Kubernetes resources will belong
|
||||
to. Because we are not going to be defining custom resources, the domain does
|
||||
not matter. The repository is going to be the name of the Go module we are going
|
||||
to write. By convention, this is the repository where you will be storing your
|
||||
code.
|
||||
|
||||
As an example, here is the command I ran:
|
||||
|
||||
```bash
|
||||
# Feel free to change the domain and repo values.
|
||||
operator-sdk init --domain=padok.fr --repo=github.com/busser/label-operator
|
||||
```
|
||||
|
||||
Next, we need a create a new controller. This controller will handle pods and
|
||||
not a custom resource, so no need to generate the resource code. Let's run this
|
||||
command to scaffold the code we need:
|
||||
|
||||
```bash
|
||||
operator-sdk create api --group=core --version=v1 --kind=Pod --controller=true --resource=false
|
||||
```
|
||||
|
||||
We now have a new file: `controllers/pod_controller.go`. This file contains a
|
||||
`PodReconciler` type with two methods that we need to implement. The first is
|
||||
`Reconcile`, and it looks like this for now:
|
||||
|
||||
```go
|
||||
func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||
_ = r.Log.WithValues("pod", req.NamespacedName)
|
||||
|
||||
// your logic here
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
```
|
||||
|
||||
The `Reconcile` method is called whenever a Pod is created, updated, or deleted.
|
||||
The name and namespace of the Pod are in the `ctrl.Request` the method receives
|
||||
as a parameter.
|
||||
|
||||
The second method is `SetupWithManager` and for now it looks like this:
|
||||
|
||||
```go
|
||||
func (r *PodReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
// Uncomment the following line adding a pointer to an instance of the controlled resource as an argument
|
||||
// For().
|
||||
Complete(r)
|
||||
}
|
||||
```
|
||||
|
||||
The `SetupWithManager` method is called when the operator starts. It serves to
|
||||
tell the operator framework what types our `PodReconciler` needs to watch. To
|
||||
use the same `Pod` type used by Kubernetes internally, we need to import some of
|
||||
its code. All of the Kubernetes source code is open source, so you can import
|
||||
any part you like in your own Go code. You can find a complete list of available
|
||||
packages in the Kubernetes source code or [here on pkg.go.dev][pkg-go-dev]. To
|
||||
use pods, we need the `k8s.io/api/core/v1` package.
|
||||
|
||||
```go
|
||||
package controllers
|
||||
|
||||
import (
|
||||
// other imports...
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
// other imports...
|
||||
)
|
||||
```
|
||||
|
||||
Lets use the `Pod` type in `SetupWithManager` to tell the operator framework we
|
||||
want to watch pods:
|
||||
|
||||
```go
|
||||
func (r *PodReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
For(&corev1.Pod{}).
|
||||
Complete(r)
|
||||
}
|
||||
```
|
||||
|
||||
Before moving on, we should set the RBAC permissions our controller needs. Above
|
||||
the `Reconcile` method, we have some default permissions:
|
||||
|
||||
```go
|
||||
// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=core,resources=pods/status,verbs=get;update;patch
|
||||
// +kubebuilder:rbac:groups=core,resources=pods/finalizers,verbs=update
|
||||
```
|
||||
|
||||
We don't need all of those. Our controller will never interact with a Pod's
|
||||
status or its finalizers. It only needs to read and update pods. Lets remove the
|
||||
unnecessary permissions and keep only what we need:
|
||||
|
||||
```go
|
||||
// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;update;patch
|
||||
```
|
||||
|
||||
We are now ready to write our controller's reconciliation logic.
|
||||
|
||||
## Implementing reconciliation
|
||||
|
||||
Here is what we want our `Reconcile` method to do:
|
||||
|
||||
1. Use the Pod's name and namespace from the `ctrl.Request` to fetch the Pod
|
||||
from the Kubernetes API.
|
||||
2. If the Pod has an `add-pod-name-label` annotation, add a `pod-name` label to
|
||||
the Pod; if the annotation is missing, don't add the label.
|
||||
3. Update the Pod in the Kubernetes API to persist the changes made.
|
||||
|
||||
Lets define some constants for the annotation and label:
|
||||
|
||||
```go
|
||||
const (
|
||||
addPodNameLabelAnnotation = "padok.fr/add-pod-name-label"
|
||||
podNameLabel = "padok.fr/pod-name"
|
||||
)
|
||||
```
|
||||
|
||||
The first step in our reconciliation function is to fetch the Pod we are working
|
||||
on from the Kubernetes API:
|
||||
|
||||
```go
|
||||
// Reconcile handles a reconciliation request for a Pod.
|
||||
// If the Pod has the addPodNameLabelAnnotation annotation, then Reconcile
|
||||
// will make sure the podNameLabel label is present with the correct value.
|
||||
// If the annotation is absent, then Reconcile will make sure the label is too.
|
||||
func (r *PodReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||
log := r.Log.WithValues("pod", req.NamespacedName)
|
||||
|
||||
/*
|
||||
Step 0: Fetch the Pod from the Kubernetes API.
|
||||
*/
|
||||
|
||||
var pod corev1.Pod
|
||||
if err := r.Get(ctx, req.NamespacedName, &pod); err != nil {
|
||||
log.Error(err, "unable to fetch Pod")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
```
|
||||
|
||||
Our `Reconcile` method will be called when a Pod is created, updated, or
|
||||
deleted. In the deletion case, our call to `r.Get` will return a specific error.
|
||||
Let's import the package that defines this error:
|
||||
|
||||
```go
|
||||
package controllers
|
||||
|
||||
import (
|
||||
// other imports...
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
// other imports...
|
||||
)
|
||||
```
|
||||
|
||||
We can now handle this specific error and — since our controller does not care
|
||||
about deleted pods — explicitly ignore it:
|
||||
|
||||
```go
|
||||
/*
|
||||
Step 0: Fetch the Pod from the Kubernetes API.
|
||||
*/
|
||||
|
||||
var pod corev1.Pod
|
||||
if err := r.Get(ctx, req.NamespacedName, &pod); err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
// we'll ignore not-found errors, since we can get them on deleted requests.
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
log.Error(err, "unable to fetch Pod")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
```
|
||||
|
||||
Next, lets edit our Pod so that our dynamic label is present if and only if our
|
||||
annotation is present:
|
||||
|
||||
```go
|
||||
/*
|
||||
Step 1: Add or remove the label.
|
||||
*/
|
||||
|
||||
labelShouldBePresent := pod.Annotations[addPodNameLabelAnnotation] == "true"
|
||||
labelIsPresent := pod.Labels[podNameLabel] == pod.Name
|
||||
|
||||
if labelShouldBePresent == labelIsPresent {
|
||||
// The desired state and actual state of the Pod are the same.
|
||||
// No further action is required by the operator at this moment.
|
||||
log.Info("no update required")
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
if labelShouldBePresent {
|
||||
// If the label should be set but is not, set it.
|
||||
if pod.Labels == nil {
|
||||
pod.Labels = make(map[string]string)
|
||||
}
|
||||
pod.Labels[podNameLabel] = pod.Name
|
||||
log.Info("adding label")
|
||||
} else {
|
||||
// If the label should not be set but is, remove it.
|
||||
delete(pod.Labels, podNameLabel)
|
||||
log.Info("removing label")
|
||||
}
|
||||
```
|
||||
|
||||
Finally, let's push our updated Pod to the Kubernetes API:
|
||||
|
||||
```go
|
||||
/*
|
||||
Step 2: Update the Pod in the Kubernetes API.
|
||||
*/
|
||||
|
||||
if err := r.Update(ctx, &pod); err != nil {
|
||||
log.Error(err, "unable to update Pod")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
```
|
||||
|
||||
When writing our updated Pod to the Kubernetes API, there is a risk that the Pod
|
||||
has been updated or deleted since we first read it. When writing a Kubernetes
|
||||
controller, we should keep in mind that we are not the only actors in the
|
||||
cluster. When this happens, the best thing to do is start the reconciliation
|
||||
from scratch, by requeuing the event. Lets do exactly that:
|
||||
|
||||
```go
|
||||
/*
|
||||
Step 2: Update the Pod in the Kubernetes API.
|
||||
*/
|
||||
|
||||
if err := r.Update(ctx, &pod); err != nil {
|
||||
if apierrors.IsConflict(err) {
|
||||
// The Pod has been updated since we read it.
|
||||
// Requeue the Pod to try to reconciliate again.
|
||||
return ctrl.Result{Requeue: true}, nil
|
||||
}
|
||||
if apierrors.IsNotFound(err) {
|
||||
// The Pod has been deleted since we read it.
|
||||
// Requeue the Pod to try to reconciliate again.
|
||||
return ctrl.Result{Requeue: true}, nil
|
||||
}
|
||||
log.Error(err, "unable to update Pod")
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
```
|
||||
|
||||
Let's remember to return successfully at the end of the method:
|
||||
|
||||
```go
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
```
|
||||
|
||||
And that's it! We are now ready to run the controller on our cluster.
|
||||
|
||||
## Run the controller on your cluster
|
||||
|
||||
To run our controller on your cluster, we need to run the operator. For that,
|
||||
all you will need is `kubectl`. If you don't have a Kubernetes cluster at hand,
|
||||
I recommend you start one locally with [KinD (Kubernetes in Docker)][kind].
|
||||
|
||||
All it takes to run the operator from your machine is this command:
|
||||
|
||||
```bash
|
||||
make run
|
||||
```
|
||||
|
||||
After a few seconds, you should see the operator's logs. Notice that our
|
||||
controller's `Reconcile` method was called for all pods already running in the
|
||||
cluster.
|
||||
|
||||
Let's keep the operator running and, in another terminal, create a new Pod:
|
||||
|
||||
```bash
|
||||
kubectl run --image=nginx my-nginx
|
||||
```
|
||||
|
||||
The operator should quickly print some logs, indicating that it reacted to the
|
||||
Pod's creation and subsequent changes in status:
|
||||
|
||||
```text
|
||||
INFO controllers.Pod no update required {"pod": "default/my-nginx"}
|
||||
INFO controllers.Pod no update required {"pod": "default/my-nginx"}
|
||||
INFO controllers.Pod no update required {"pod": "default/my-nginx"}
|
||||
INFO controllers.Pod no update required {"pod": "default/my-nginx"}
|
||||
```
|
||||
|
||||
Lets check the Pod's labels:
|
||||
|
||||
```terminal
|
||||
$ kubectl get pod my-nginx --show-labels
|
||||
NAME READY STATUS RESTARTS AGE LABELS
|
||||
my-nginx 1/1 Running 0 11m run=my-nginx
|
||||
```
|
||||
|
||||
Let's add an annotation to the Pod so that our controller knows to add our
|
||||
dynamic label to it:
|
||||
|
||||
```bash
|
||||
kubectl annotate pod my-nginx padok.fr/add-pod-name-label=true
|
||||
```
|
||||
|
||||
Notice that the controller immediately reacted and produced a new line in its
|
||||
logs:
|
||||
|
||||
```text
|
||||
INFO controllers.Pod adding label {"pod": "default/my-nginx"}
|
||||
```
|
||||
|
||||
```terminal
|
||||
$ kubectl get pod my-nginx --show-labels
|
||||
NAME READY STATUS RESTARTS AGE LABELS
|
||||
my-nginx 1/1 Running 0 13m padok.fr/pod-name=my-nginx,run=my-nginx
|
||||
```
|
||||
|
||||
Bravo! You just successfully wrote a Kubernetes controller capable of adding
|
||||
labels with dynamic values to resources in your cluster.
|
||||
|
||||
Controllers and operators, both big and small, can be an important part of your
|
||||
Kubernetes journey. Writing operators is easier now than it has ever been. The
|
||||
possibilities are endless.
|
||||
|
||||
## What next?
|
||||
|
||||
If you want to go further, I recommend starting by deploying your controller or
|
||||
operator inside a cluster. The `Makefile` generated by the Operator SDK will do
|
||||
most of the work.
|
||||
|
||||
When deploying an operator to production, it is always a good idea to implement
|
||||
robust testing. The first step in that direction is to write unit tests.
|
||||
[This documentation][operator-sdk-testing] will guide you in writing tests for
|
||||
your operator. I wrote tests for the operator we just wrote; you can find all of
|
||||
my code in [this GitHub repository][github-repo].
|
||||
|
||||
## How to learn more?
|
||||
|
||||
The [Operator SDK documentation][operator-sdk-docs] goes into detail on how you
|
||||
can go further and implement more complex operators.
|
||||
|
||||
When modeling a more complex use-case, a single controller acting on built-in
|
||||
Kubernetes types may not be enough. You may need to build a more complex
|
||||
operator with [Custom Resource Definitions (CRDs)][custom-resource-definitions]
|
||||
and multiple controllers. The Operator SDK is a great tool to help you do this.
|
||||
|
||||
If you want to discuss building an operator, join the [#kubernetes-operator][slack-channel]
|
||||
channel in the [Kubernetes Slack workspace][slack-workspace]!
|
||||
|
||||
<!-- Links -->
|
||||
|
||||
[controllers]: https://kubernetes.io/docs/concepts/architecture/controller/
|
||||
[custom-resource-definitions]: https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/
|
||||
[kind]: https://kind.sigs.k8s.io/docs/user/quick-start/#installation
|
||||
[github-repo]: https://github.com/busser/label-operator
|
||||
[mutating-admission-webhook]: https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/#mutatingadmissionwebhook
|
||||
[operator-sdk]: https://sdk.operatorframework.io/
|
||||
[operator-sdk-docs]: https://sdk.operatorframework.io/docs/
|
||||
[operator-sdk-installation]: https://sdk.operatorframework.io/docs/installation/
|
||||
[operator-sdk-testing]: https://sdk.operatorframework.io/docs/building-operators/golang/testing/
|
||||
[operatorhub]: https://operatorhub.io/
|
||||
[pkg-go-dev]: https://pkg.go.dev/k8s.io/api
|
||||
[slack-channel]: https://kubernetes.slack.com/messages/kubernetes-operators
|
||||
[slack-workspace]: https://slack.k8s.io/
|
||||
[statefulset-pod-name-label]: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-name-label
|
||||
[what-is-an-operator]: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Announcing Kubernetes Community Group Annual Reports"
|
||||
description: >
|
||||
Introducing brand new Kubernetes Community Group Annual Reports for
|
||||
Special Interest Groups and Working Groups.
|
||||
date: 2021-06-28T10:00:00-08:00
|
||||
slug: Announcing-Kubernetes-Community-Group-Annual-Reports
|
||||
---
|
||||
|
||||
**Authors:** Divya Mohan
|
||||
|
||||
{{< figure src="k8s_annual_report_2020.svg" alt="Community annual report 2020" link="https://www.cncf.io/reports/kubernetes-community-annual-report-2020/" >}}
|
||||
|
||||
Given the growth and scale of the Kubernetes project, the existing reporting mechanisms were proving to be inadequate and challenging.
|
||||
Kubernetes is a large open source project. With over 100000 commits just to the main k/kubernetes repository, hundreds of other code
|
||||
repositories in the project, and thousands of contributors, there's a lot going on. In fact, there are 37 contributor groups at the time of
|
||||
writing. We also value all forms of contribution and not just code changes.
|
||||
|
||||
With that context in mind, the challenge of reporting on all this activity was a call to action for exploring better options. Therefore
|
||||
inspired by the Apache Software Foundation’s [open guide to PMC Reporting](https://www.apache.org/foundation/board/reporting) and the
|
||||
[CNCF project Annual Reporting](https://www.cncf.io/cncf-annual-report-2020/), the Kubernetes project is proud to announce the
|
||||
**Kubernetes Community Group Annual Reports for Special Interest Groups (SIGs) and Working Groups (WGs)**. In its flagship edition,
|
||||
the [2020 Summary report](https://www.cncf.io/reports/kubernetes-community-annual-report-2020/) focuses on bettering the
|
||||
Kubernetes ecosystem by assessing and promoting the healthiness of the groups within the upstream community.
|
||||
|
||||
Previously, the mechanisms for the Kubernetes project overall to report on groups and their activities were
|
||||
[devstats](https://k8s.devstats.cncf.io/), GitHub data, issues, to measure the healthiness of a given UG/WG/SIG/Committee. As a
|
||||
project spanning several diverse communities, it was essential to have something that captured the human side of things. With 50,000+
|
||||
contributors, it’s easy to assume that the project has enough help and this report surfaces more information than /help-wanted and
|
||||
/good-first-issue for end users. This is how we sustain the project. Paraphrasing one of the Steering Committee members,
|
||||
[Paris Pittman](https://github.com/parispittman), “There was a requirement for tighter feedback loops - ones that involved more than just
|
||||
GitHub data and issues. Given that Kubernetes, as a project, has grown in scale and number of contributors over the years, we have
|
||||
outgrown the existing reporting mechanisms."
|
||||
|
||||
The existing communication channels between the Steering committee members and the folks leading the groups and committees were also required
|
||||
to be made as open and as bi-directional as possible. Towards achieving this very purpose, every group and committee has been assigned a
|
||||
liaison from among the steering committee members for kick off, help, or guidance needed throughout the process. According to
|
||||
[Davanum Srinivas a.k.a. dims](https://github.com/dims), “... That was one of the main motivations behind this report. People (leading the
|
||||
groups/committees) know that they can reach out to us and there’s a vehicle for them to reach out to us… This is our way of setting up a
|
||||
two-way feedback for them." The progress on these action items would be updated and tracked on the monthly Steering Committee meetings
|
||||
ensuring that this is not a one-off activity. Quoting [Nikhita Raghunath](https://github.com/nikhita), one of the Steering Committee members,
|
||||
“... Once we have a base, the liaisons will work with these groups to ensure that the problems are resolved. When we have a report next year,
|
||||
we’ll have a look at the progress made and how we could still do better. But the idea is definitely to not stop at the report.”
|
||||
|
||||
With this report, we hope to empower our end user communities with information that they can use to identify ways in which they can support
|
||||
the project as well as a sneak peek into the roadmap for upcoming features. As a community, we thrive on feedback and would love to hear your
|
||||
views about the report. You can get in touch with the [Steering Committee](https://github.com/kubernetes/steering#contact) via
|
||||
[Slack](https://kubernetes.slack.com/messages/steering-committee) or via the [mailing list](steering@kubernetes.io).
|
||||
|
After Width: | Height: | Size: 1.2 MiB |
@@ -0,0 +1,275 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Kubernetes API and Feature Removals In 1.22: Here’s What You Need To Know"
|
||||
date: 2021-07-14
|
||||
slug: upcoming-changes-in-kubernetes-1-22
|
||||
---
|
||||
|
||||
**Authors**: Krishna Kilari (Amazon Web Services), Tim Bannister (The Scale Factory)
|
||||
|
||||
As the Kubernetes API evolves, APIs are periodically reorganized or upgraded.
|
||||
When APIs evolve, the old APIs they replace are deprecated, and eventually removed.
|
||||
See [Kubernetes API removals](#kubernetes-api-removals) to read more about Kubernetes'
|
||||
policy on removing APIs.
|
||||
|
||||
We want to make sure you're aware of some upcoming removals. These are
|
||||
beta APIs that you can use in current, supported Kubernetes versions,
|
||||
and they are already deprecated. The reason for all of these removals
|
||||
is that they have been superseded by a newer, stable (“GA”) API.
|
||||
|
||||
Kubernetes 1.22, due for release in August 2021, will remove a number of deprecated
|
||||
APIs.
|
||||
[Kubernetes 1.22 Release Information](https://www.kubernetes.dev/resources/release/)
|
||||
has details on the schedule for the v1.22 release.
|
||||
|
||||
## API removals for Kubernetes v1.22 {#api-changes}
|
||||
|
||||
The **v1.22** release will stop serving the API versions we've listed immediately below.
|
||||
These are all beta APIs that were previously deprecated in favor of newer and more stable
|
||||
API versions.
|
||||
<!-- sorted by API group -->
|
||||
|
||||
* Beta versions of the `ValidatingWebhookConfiguration` and `MutatingWebhookConfiguration` API (the **admissionregistration.k8s.io/v1beta1** API versions)
|
||||
* The beta `CustomResourceDefinition` API (**apiextensions.k8s.io/v1beta1**)
|
||||
* The beta `APIService` API (**apiregistration.k8s.io/v1beta1**)
|
||||
* The beta `TokenReview` API (**authentication.k8s.io/v1beta1**)
|
||||
* Beta API versions of `SubjectAccessReview`, `LocalSubjectAccessReview`, `SelfSubjectAccessReview` (API versions from **authorization.k8s.io/v1beta1**)
|
||||
* The beta `CertificateSigningRequest` API (**certificates.k8s.io/v1beta1**)
|
||||
* The beta `Lease` API (**coordination.k8s.io/v1beta1**)
|
||||
* All beta `Ingress` APIs (the **extensions/v1beta1** and **networking.k8s.io/v1beta1** API versions)
|
||||
|
||||
The Kubernetes documentation covers these
|
||||
[API removals for v1.22](/docs/reference/using-api/deprecation-guide/#v1-22) and explains
|
||||
how each of those APIs change between beta and stable.
|
||||
|
||||
## What to do
|
||||
|
||||
We're going to run through each of the resources that are affected by these removals
|
||||
and explain the steps you'll need to take.
|
||||
|
||||
`Ingress`
|
||||
: Migrate to use the **networking.k8s.io/v1**
|
||||
[Ingress](/docs/reference/kubernetes-api/service-resources/ingress-v1/) API,
|
||||
[available since v1.19](/blog/2020/08/26/kubernetes-release-1.19-accentuate-the-paw-sitive/#ingress-graduates-to-general-availability).
|
||||
The related API [IngressClass](/docs/reference/kubernetes-api/service-resources/ingress-class-v1/)
|
||||
is designed to complement the [Ingress](/docs/concepts/services-networking/ingress/)
|
||||
concept, allowing you to configure multiple kinds of Ingress within one cluster.
|
||||
If you're currently using the deprecated
|
||||
[`kubernetes.io/ingress.class`](https://kubernetes.io/docs/reference/labels-annotations-taints/#kubernetes-io-ingress-class-deprecated)
|
||||
annotation, plan to switch to using the `.spec.ingressClassName` field instead.
|
||||
On any cluster running Kubernetes v1.19 or later, you can use the v1 API to
|
||||
retrieve or update existing Ingress objects, even if they were created using an
|
||||
older API version.
|
||||
|
||||
When you convert an Ingress to the v1 API, you should review each rule in that Ingress.
|
||||
Older Ingresses use the legacy `ImplementationSpecific` path type. Instead of `ImplementationSpecific`, switch [path matching](/docs/concepts/services-networking/ingress/#path-types) to either `Prefix` or `Exact`. One of the benefits of moving to these alternative path types is that it becomes easier to migrate between different Ingress classes.
|
||||
|
||||
**ⓘ** As well as upgrading _your_ own use of the Ingress API as a client, make sure that
|
||||
every ingress controller that you use is compatible with the v1 Ingress API.
|
||||
Read [Ingress Prerequisites](/docs/concepts/services-networking/ingress/#prerequisites)
|
||||
for more context about Ingress and ingress controllers.
|
||||
|
||||
`ValidatingWebhookConfiguration` and `MutatingWebhookConfiguration`
|
||||
: Migrate to use the **admissionregistration.k8s.io/v1** API versions of
|
||||
[ValidatingWebhookConfiguration](/docs/reference/kubernetes-api/extend-resources/validating-webhook-configuration-v1/)
|
||||
and [MutatingWebhookConfiguration](/docs/reference/kubernetes-api/extend-resources/mutating-webhook-configuration-v1/),
|
||||
available since v1.16.
|
||||
You can use the v1 API to retrieve or update existing objects, even if they were created using an older API version.
|
||||
|
||||
`CustomResourceDefinition`
|
||||
: Migrate to use the [CustomResourceDefinition](/docs/reference/kubernetes-api/extend-resources/custom-resource-definition-v1/)
|
||||
**apiextensions.k8s.io/v1** API, available since v1.16.
|
||||
You can use the v1 API to retrieve or update existing objects, even if they were created
|
||||
using an older API version. If you defined any custom resources in your cluster, those
|
||||
are still served after you upgrade.
|
||||
|
||||
If you're using external CustomResourceDefinitions, you can use
|
||||
[`kubectl convert`](#kubectl-convert) to translate existing manifests to use the newer API.
|
||||
Because there are some functional differences between beta and stable CustomResourceDefinitions,
|
||||
our advice is to test out each one to make sure it works how you expect after the upgrade.
|
||||
|
||||
`APIService`
|
||||
: Migrate to use the **apiregistration.k8s.io/v1** [APIService](/docs/reference/kubernetes-api/cluster-resources/api-service-v1/)
|
||||
API, available since v1.10.
|
||||
You can use the v1 API to retrieve or update existing objects, even if they were created using an older API version.
|
||||
If you already have API aggregation using an APIService object, this aggregation continues
|
||||
to work after you upgrade.
|
||||
|
||||
`TokenReview`
|
||||
: Migrate to use the **authentication.k8s.io/v1** [TokenReview](/docs/reference/kubernetes-api/authentication-resources/token-review-v1/)
|
||||
API, available since v1.10.
|
||||
|
||||
As well as serving this API via HTTP, the Kubernetes API server uses the same format to
|
||||
[send](/docs/reference/access-authn-authz/authentication/#webhook-token-authentication)
|
||||
TokenReviews to webhooks. The v1.22 release continues to use the v1beta1 API for TokenReviews
|
||||
sent to webhooks by default. See [Looking ahead](#looking-ahead) for some specific tips about
|
||||
switching to the stable API.
|
||||
|
||||
`SubjectAccessReview`, `SelfSubjectAccessReview` and `LocalSubjectAccessReview`
|
||||
: Migrate to use the **authorization.k8s.io/v1** versions of those
|
||||
[authorization APIs](/docs/reference/kubernetes-api/authorization-resources/), available since v1.6.
|
||||
|
||||
`CertificateSigningRequest`
|
||||
: Migrate to use the **certificates.k8s.io/v1**
|
||||
[CertificateSigningRequest](/docs/reference/kubernetes-api/authentication-resources/certificate-signing-request-v1/)
|
||||
API, available since v1.19.
|
||||
You can use the v1 API to retrieve or update existing objects, even if they were created
|
||||
using an older API version. Existing issued certificates retain their validity when you upgrade.
|
||||
|
||||
`Lease`
|
||||
: Migrate to use the **coordination.k8s.io/v1** [Lease](/docs/reference/kubernetes-api/cluster-resources/lease-v1/)
|
||||
API, available since v1.14.
|
||||
You can use the v1 API to retrieve or update existing objects, even if they were created
|
||||
using an older API version.
|
||||
|
||||
### `kubectl convert`
|
||||
|
||||
There is a plugin to `kubectl` that provides the `kubectl convert` subcommand.
|
||||
It's an official plugin that you can download as part of Kubernetes.
|
||||
See [Download Kubernetes](/releases/download/) for more details.
|
||||
|
||||
You can use `kubectl convert` to update manifest files to use a different API
|
||||
version. For example, if you have a manifest in source control that uses the beta
|
||||
Ingress API, you can check that definition out,
|
||||
and run
|
||||
`kubectl convert -f <manifest> --output-version <group>/<version>`.
|
||||
You can use the `kubectl convert` command to automatically convert an
|
||||
existing manifest.
|
||||
|
||||
For example, to convert an older Ingress definition to
|
||||
`networking.k8s.io/v1`, you can run:
|
||||
```bash
|
||||
kubectl convert -f ./legacy-ingress.yaml --output-version networking.k8s.io/v1
|
||||
```
|
||||
|
||||
The automatic conversion uses a similar technique to how the Kubernetes control plane
|
||||
updates objects that were originally created using an older API version. Because it's
|
||||
a mechanical conversion, you might need to go in and change the manifest to adjust
|
||||
defaults etc.
|
||||
|
||||
### Rehearse for the upgrade
|
||||
|
||||
If you manage your cluster's API server component, you can try out these API
|
||||
removals before you upgrade to Kubernetes v1.22.
|
||||
|
||||
To do that, add the following to the kube-apiserver command line arguments:
|
||||
|
||||
`--runtime-config=admissionregistration.k8s.io/v1beta1=false,apiextensions.k8s.io/v1beta1=false,apiregistration.k8s.io/v1beta1=false,authentication.k8s.io/v1beta1=false,authorization.k8s.io/v1beta1=false,certificates.k8s.io/v1beta1=false,coordination.k8s.io/v1beta1=false,extensions/v1beta1/ingresses=false,networking.k8s.io/v1beta1=false`
|
||||
|
||||
(as a side effect, this also turns off v1beta1 of EndpointSlice - watch out for
|
||||
that when you're testing).
|
||||
|
||||
Once you've switched all the kube-apiservers in your cluster to use that setting,
|
||||
those beta APIs are removed. You can test that API clients (`kubectl`, deployment
|
||||
tools, custom controllers etc) still work how you expect, and you can revert if
|
||||
you need to without having to plan a more disruptive downgrade.
|
||||
|
||||
|
||||
|
||||
### Advice for software authors
|
||||
|
||||
Maybe you're reading this because you're a developer of an addon or other
|
||||
component that integrates with Kubernetes?
|
||||
|
||||
If you develop an Ingress controller, webhook authenticator, an API aggregation, or
|
||||
any other tool that relies on these deprecated APIs, you should already have started
|
||||
to switch your software over.
|
||||
|
||||
You can use the tips in
|
||||
[Rehearse for the upgrade](#rehearse-for-the-upgrade) to run your own Kubernetes
|
||||
cluster that only uses the new APIs, and make sure that your code works OK.
|
||||
For your documentation, make sure readers are aware of any steps they should take
|
||||
for the Kubernetes v1.22 upgrade.
|
||||
|
||||
Where possible, give your users a hand to adopt the new APIs early - perhaps in a
|
||||
test environment - so they can give you feedback about any problems.
|
||||
|
||||
There are some [more deprecations](#looking-ahead) coming in Kubernetes v1.25,
|
||||
so plan to have those covered too.
|
||||
|
||||
## Kubernetes API removals
|
||||
|
||||
Here's some background about why Kubernetes removes some APIs, and also a promise
|
||||
about _stable_ APIs in Kubernetes.
|
||||
|
||||
Kubernetes follows a defined
|
||||
[deprecation policy](/docs/reference/using-api/deprecation-policy/) for its
|
||||
features, including the Kubernetes API. That policy allows for replacing stable
|
||||
(“GA”) APIs from Kubernetes. Importantly, this policy means that a stable API only
|
||||
be deprecated when a newer stable version of that same API is available.
|
||||
|
||||
That stability guarantee matters: if you're using a stable Kubernetes API, there
|
||||
won't ever be a new version released that forces you to switch to an alpha or beta
|
||||
feature.
|
||||
|
||||
Earlier stages are different. Alpha features are under test and potentially
|
||||
incomplete. Almost always, alpha features are disabled by default.
|
||||
Kubernetes releases can and do remove alpha features that haven't worked out.
|
||||
|
||||
After alpha, comes beta. These features are typically enabled by default; if the
|
||||
testing works out, the feature can graduate to stable. If not, it might need
|
||||
a redesign.
|
||||
|
||||
Last year, Kubernetes officially
|
||||
[adopted](/blog/2020/08/21/moving-forward-from-beta/#avoiding-permanent-beta)
|
||||
a policy for APIs that have reached their beta phase:
|
||||
|
||||
> For Kubernetes REST APIs, when a new feature's API reaches beta, that starts
|
||||
> a countdown. The beta-quality API now has three releases …
|
||||
> to either:
|
||||
>
|
||||
> * reach GA, and deprecate the beta, or
|
||||
> * have a new beta version (and deprecate the previous beta).
|
||||
|
||||
_At the time of that article, three Kubernetes releases equated to roughly nine
|
||||
calendar months. Later that same month, Kubernetes
|
||||
adopted a new
|
||||
release cadence of three releases per calendar year, so the countdown period is
|
||||
now roughly twelve calendar months._
|
||||
|
||||
Whether an API removal is because of a beta feature graduating to stable, or
|
||||
because that API hasn't proved successful, Kubernetes will continue to remove
|
||||
APIs by following its deprecation policy and making sure that migration options
|
||||
are documented.
|
||||
|
||||
### Looking ahead
|
||||
|
||||
There's a setting that's relevant if you use webhook authentication checks.
|
||||
A future Kubernetes release will switch to sending TokenReview objects
|
||||
to webhooks using the `authentication.k8s.io/v1` API by default. At the moment,
|
||||
the default is to send `authentication.k8s.io/v1beta1` TokenReviews to webhooks,
|
||||
and that's still the default for Kubernetes v1.22.
|
||||
However, you can switch over to the stable API right now if you want:
|
||||
add `--authentication-token-webhook-version=v1` to the command line options for
|
||||
the kube-apiserver, and check that webhooks for authentication still work how you
|
||||
expected.
|
||||
|
||||
Once you're happy it works OK, you can leave the `--authentication-token-webhook-version=v1`
|
||||
option set across your control plane.
|
||||
|
||||
The **v1.25** release that's planned for next year will stop serving beta versions of
|
||||
several Kubernetes APIs that are stable right now and have been for some time.
|
||||
The same v1.25 release will **remove** PodSecurityPolicy, which is deprecated and won't
|
||||
graduate to stable. See
|
||||
[PodSecurityPolicy Deprecation: Past, Present, and Future](/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/)
|
||||
for more information.
|
||||
|
||||
The official [list of API removals](/docs/reference/using-api/deprecation-guide/#v1-25)
|
||||
planned for Kubernetes 1.25 is:
|
||||
|
||||
* The beta `CronJob` API (**batch/v1beta1**)
|
||||
* The beta `EndpointSlice` API (**networking.k8s.io/v1beta1**)
|
||||
* The beta `PodDisruptionBudget` API (**policy/v1beta1**)
|
||||
* The beta `PodSecurityPolicy` API (**policy/v1beta1**)
|
||||
|
||||
## Want to know more?
|
||||
|
||||
Deprecations are announced in the Kubernetes release notes. You can see the announcements
|
||||
of pending deprecations in the release notes for
|
||||
[1.19](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.19.md#deprecations),
|
||||
[1.20](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md#deprecation),
|
||||
and [1.21](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.21.md#deprecation).
|
||||
|
||||
For information on the process of deprecation and removal, check out the official Kubernetes
|
||||
[deprecation policy](/docs/reference/using-api/deprecation-policy/#deprecating-parts-of-the-api)
|
||||
document.
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Spotlight on SIG Usability"
|
||||
date: 2021-07-15
|
||||
slug: sig-usability-spotlight-2021
|
||||
---
|
||||
|
||||
**Author:** Kunal Kushwaha, Civo
|
||||
|
||||
## Introduction
|
||||
|
||||
Are you interested in learning about what [SIG Usability](https://github.com/kubernetes/community/tree/master/sig-usability) does and how you can get involved? Well, you're at the right place. SIG Usability is all about making Kubernetes more accessible to new folks, and its main activity is conducting user research for the community. In this blog, we have summarized our conversation with [Gaby Moreno](https://twitter.com/morengab), who walks us through the various aspects of being a part of the SIG and shares some insights about how others can get involved.
|
||||
|
||||
Gaby is a co-lead for SIG Usability. She works as a Product Designer at IBM and enjoys working on the user experience of open, hybrid cloud technologies like Kubernetes, OpenShift, Terraform, and Cloud Foundry.
|
||||
|
||||
## A summary of our conversation
|
||||
|
||||
### Q. Could you tell us a little about what SIG Usability does?
|
||||
|
||||
A. SIG Usability at a high level started because there was no dedicated user experience team for Kubernetes. The extent of SIG Usability is focussed on the end-client ease of use of the Kubernetes project. The main activity is user research for the community, which includes speaking to Kubernetes users.
|
||||
|
||||
This covers points like user experience and accessibility. The objectives of the SIG are to guarantee that the Kubernetes project is maximally usable by people of a wide range of foundations and capacities, such as incorporating internationalization and ensuring the openness of documentation.
|
||||
|
||||
### Q. Why should new and existing contributors consider joining SIG Usability?
|
||||
|
||||
A. There are plenty of territories where new contributors can begin. For example:
|
||||
- User research projects, where people can help understand the usability of the end-user experiences, including error messages, end-to-end tasks, etc.
|
||||
- Accessibility guidelines for Kubernetes community artifacts, examples include: internationalization of documentation, color choices for people with color blindness, ensuring compatibility with screen reader technology, user interface design for core components with user interfaces, and more.
|
||||
|
||||
### Q. What do you do to help new contributors get started?
|
||||
|
||||
A. New contributors can get started by shadowing one of the user interviews, going through user interview transcripts, analyzing them, and designing surveys.
|
||||
|
||||
SIG Usability is also open to new project ideas. If you have an idea, we’ll do what we can to support it. There are regular SIG Meetings where people can ask their questions live. These meetings are also recorded for those who may not be able to attend. As always, you can reach out to us on Slack as well.
|
||||
|
||||
### Q. What does the survey include?
|
||||
|
||||
A. In simple terms, the survey gathers information about how people use Kubernetes, such as trends in learning to deploy a new system, error messages they receive, and workflows.
|
||||
|
||||
One of our goals is to standardize the responses accordingly. The ultimate goal is to analyze survey responses for important user stories whose needs aren't being met.
|
||||
|
||||
### Q. Are there any particular skills you’d like to recruit for? What skills are contributors to SIG Usability likely to learn?
|
||||
|
||||
A. Although contributing to SIG Usability does not have any pre-requisites as such, experience with user research, qualitative research, or prior experience with how to conduct an interview would be great plus points. Quantitative research, like survey design and screening, is also helpful and something that we expect contributors to learn.
|
||||
|
||||
### Q. What are you getting positive feedback on, and what’s coming up next for SIG Usability?
|
||||
|
||||
A. We have had new members joining and coming to monthly meetings regularly and showing interests in becoming a contributor and helping the community. We have also had a lot of people reach out to us via Slack showcasing their interest in the SIG.
|
||||
|
||||
Currently, we are focused on finishing the study mentioned in our [talk](https://www.youtube.com/watch?v=Byn0N_ZstE0), also our project for this year. We are always happy to have new contributors join us.
|
||||
|
||||
### Q: Any closing thoughts/resources you’d like to share?
|
||||
|
||||
A. We love meeting new contributors and assisting them in investigating different Kubernetes project spaces. We will work with and team up with other SIGs to facilitate engaging with end-users, running studies, and help them integrate accessible design practices into their development practices.
|
||||
|
||||
Here are some resources for you to get started:
|
||||
- [GitHub](https://github.com/kubernetes/community/tree/master/sig-usability)
|
||||
- [Mailing list](https://groups.google.com/g/kubernetes-sig-usability)
|
||||
- [Open Community Issues/PRs](https://github.com/kubernetes/community/labels/sig%2Fusability)
|
||||
- [Slack](https://slack.k8s.io/)
|
||||
- [Slack channel #sig-usability](https://kubernetes.slack.com/archives/CLC5EF63T)
|
||||
|
||||
## Wrap Up
|
||||
|
||||
SIG Usability hosted a [KubeCon talk](https://www.youtube.com/watch?v=Byn0N_ZstE0) about studying Kubernetes users' experiences. The talk focuses on updates to the user study projects, understanding who is using Kubernetes, what they are trying to achieve, how the project is addressing their needs, and where we need to improve the project and the client experience. Join the SIG's update to find out about the most recent research results, what the plans are for the forthcoming year, and how to get involved in the upstream usability team as a contributor!
|
||||
@@ -0,0 +1,83 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Kubernetes Release Cadence Change: Here’s What You Need To Know"
|
||||
date: 2021-07-20
|
||||
slug: new-kubernetes-release-cadence
|
||||
---
|
||||
|
||||
**Authors**: Celeste Horgan, Adolfo García Veytia, James Laverack, Jeremy Rickard
|
||||
|
||||
On April 23, 2021, the Release Team merged a Kubernetes Enhancement Proposal (KEP) changing the Kubernetes release cycle from four releases a year (once a quarter) to three releases a year.
|
||||
|
||||
This blog post provides a high level overview about what this means for the Kubernetes community's contributors and maintainers.
|
||||
|
||||
## What's changing and when
|
||||
|
||||
Starting with the [Kubernetes 1.22 release](https://github.com/kubernetes/sig-release/tree/master/releases/release-1.22), a lightweight policy will drive the creation of each release schedule. This policy states:
|
||||
|
||||
* The first Kubernetes release of a calendar year should start at the second or third
|
||||
week of January to provide people more time for contributors coming back from the
|
||||
end of year holidays.
|
||||
* The last Kubernetes release of a calendar year should be finished by the middle of
|
||||
December.
|
||||
* A Kubernetes release cycle has a length of approximately 15 weeks.
|
||||
* The week of KubeCon + CloudNativeCon is not considered a 'working week' for SIG Release. The Release Team will not hold meetings or make decisions in this period.
|
||||
* An explicit SIG Release break of at least two weeks between each cycle will
|
||||
be enforced.
|
||||
|
||||
As a result, Kubernetes will follow a three releases per year cadence. Kubernetes 1.23 will be the final release of the 2021 calendar year. This new policy results in a very predictable release schedule, allowing us to forecast upcoming release dates:
|
||||
|
||||
|
||||
*Proposed Kubernetes Release Schedule for the remainder of 2021*
|
||||
|
||||
| Week Number in Year | Release Number | Release Week | Note |
|
||||
| -------- | -------- | -------- | -------- |
|
||||
| 35 | 1.23 | 1 (August 23) | |
|
||||
| 50 | 1.23 | 16 (December 07) | KubeCon + CloudNativeCon NA Break (Oct 11-15) |
|
||||
|
||||
*Proposed Kubernetes Release Schedule for 2022*
|
||||
|
||||
| Week Number in Year | Release Number | Release Week | Note |
|
||||
| -------- | -------- | -------- | -------- |
|
||||
| 1 | 1.24 | 1 (January 03) | |
|
||||
| 15 | 1.24 | 15 (April 12) | |
|
||||
| 17 | 1.25 | 1 (April 26) | KubeCon + CloudNativeCon EU likely to occur |
|
||||
| 32 | 1.25 | 15 (August 09) | |
|
||||
| 34 | 1.26 | 1 (August 22 | KubeCon + CloudNativeCon NA likely to occur |
|
||||
| 49 | 1.26 | 14 (December 06) |
|
||||
|
||||
These proposed dates reflect only the start and end dates, and they are subject to change. The Release Team will select dates for enhancement freeze, code freeze, and other milestones at the start of each release. For more information on these milestones, please refer to the [release phases](https://www.k8s.dev/resources/release/#phases) documentation. Feedback from prior releases will feed into this process.
|
||||
|
||||
## What this means for end users
|
||||
|
||||
The major change end users will experience is a slower release cadence and a slower rate of enhancement graduation. Kubernetes release artifacts, release notes, and all other aspects of any given release will stay the same.
|
||||
|
||||
Prior to this change an enhancement could graduate from alpha to stable in 9 months. With the change in cadence, this will stretch to 12 months. Additionally, graduation of features over the last few releases has in some part been driven by release team activities.
|
||||
|
||||
With fewer releases, users can expect to see the rate of feature graduation slow. Users can also expect releases to contain a larger number of enhancements that they need to be aware of during upgrades. However, with fewer releases to consume per year, it's intended that end user organizations will spend less time on upgrades and gain more time on supporting their Kubernetes clusters. It also means that Kubernetes releases are in support for a slightly longer period of time, so bug fixes and security patches will be available for releases for a longer period of time.
|
||||
|
||||
|
||||
## What this means for Kubernetes contributors
|
||||
|
||||
With a lower release cadence, contributors have more time for project enhancements, feature development, planning, and testing. A slower release cadence also provides more room for maintaining their mental health, preparing for events like KubeCon + CloudNativeCon or work on downstream integrations.
|
||||
|
||||
|
||||
## Why we decided to change the release cadence
|
||||
|
||||
The Kubernetes 1.19 cycle was far longer than usual. SIG Release extended it to lessen the burden on both Kubernetes contributors and end users due the COVID-19 pandemic. Following this extended release, the Kubernetes 1.20 release became the third, and final, release for 2020.
|
||||
|
||||
As the Kubernetes project matures, the number of enhancements per cycle grows, along with the burden on contributors, the Release Engineering team. Downstream consumers and integrators also face increased challenges keeping up with [ever more feature-packed releases](https://kubernetes.io/blog/2021/04/08/kubernetes-1-21-release-announcement/). A wider project adoption means the complexity of supporting a rapidly evolving platform affects a bigger downstream chain of consumers.
|
||||
|
||||
Changing the release cadence from four to three releases per year balances a variety of factors for stakeholders: while it's not strictly an LTS policy, consumers and integrators will get longer support terms for each minor version as the extended release cycles lead to the [previous three releases being supported](https://kubernetes.io/blog/2020/08/31/kubernetes-1-19-feature-one-year-support/) for a longer period. Contributors get more time to [mature enhancements](https://www.cncf.io/blog/2021/04/12/enhancing-the-kubernetes-enhancements-process/) and [get them ready for production](https://github.com/kubernetes/community/blob/master/sig-architecture/production-readiness.md).
|
||||
|
||||
Finally, the management overhead for SIG Release and the Release Engineering team diminishes allowing the team to spend more time on improving the quality of the software releases and the tooling that drives them.
|
||||
|
||||
## How you can help
|
||||
|
||||
Join the [discussion](https://github.com/kubernetes/sig-release/discussions/1566) about communicating future release dates and be sure to be on the lookout for post release surveys.
|
||||
|
||||
## Where you can find out more
|
||||
|
||||
- Read the KEP [here](https://github.com/kubernetes/enhancements/tree/master/keps/sig-release/2572-release-cadence)
|
||||
- Join the [kubernetes-dev](https://groups.google.com/g/kubernetes-dev) mailing list
|
||||
- Join [Kubernetes Slack](https://slack.k8s.io) and follow the #announcements channel
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
layout: blog
|
||||
title: 'Updating NGINX-Ingress to use the stable Ingress API'
|
||||
date: 2021-07-26
|
||||
slug: update-with-ingress-nginx
|
||||
---
|
||||
|
||||
**Authors:** James Strong, Ricardo Katz
|
||||
|
||||
With all Kubernetes APIs, there is a process to creating, maintaining, and
|
||||
ultimately deprecating them once they become GA. The networking.k8s.io API group is no
|
||||
different. The upcoming Kubernetes 1.22 release will remove several deprecated APIs
|
||||
that are relevant to networking:
|
||||
|
||||
- the `networking.k8s.io/v1beta1` API version of [IngressClass](/docs/concepts/services-networking/ingress/#ingress-class)
|
||||
- all beta versions of [Ingress](/docs/concepts/services-networking/ingress/): `extensions/v1beta1` and `networking.k8s.io/v1beta1`
|
||||
|
||||
On a v1.22 Kubernetes cluster, you'll be able to access Ingress and IngressClass
|
||||
objects through the stable (v1) APIs, but access via their beta APIs won't be possible.
|
||||
This change has been in
|
||||
in discussion since
|
||||
[2017](https://github.com/kubernetes/kubernetes/issues/43214),
|
||||
[2019](https://kubernetes.io/blog/2019/07/18/api-deprecations-in-1-16/) with
|
||||
1.16 Kubernetes API deprecations, and most recently in
|
||||
KEP-1453:
|
||||
[Graduate Ingress API to GA](https://github.com/kubernetes/enhancements/tree/master/keps/sig-network/1453-ingress-api#122).
|
||||
|
||||
During community meetings, the networking Special Interest Group has decided to continue
|
||||
supporting Kubernetes versions older than 1.22 with Ingress-NGINX version 0.47.0.
|
||||
Support for Ingress-NGINX will continue for six months after Kubernetes 1.22
|
||||
is released. Any additional bug fixes and CVEs for Ingress-NGINX will be
|
||||
addressed on a need-by-need basis.
|
||||
|
||||
Ingress-NGINX will have separate branches and releases of Ingress-NGINX to
|
||||
support this model, mirroring the Kubernetes project process. Future
|
||||
releases of the Ingress-NGINX project will track and support the latest
|
||||
versions of Kubernetes.
|
||||
|
||||
{{< table caption="Ingress NGINX supported version with Kubernetes Versions" >}}
|
||||
Kubernetes version | Ingress-NGINX version | Notes
|
||||
:-------------------|:----------------------|:------------
|
||||
v1.22 | v1.0.0-alpha.2 | New features, plus bug fixes.
|
||||
v1.21 | v0.47.x | Bugfixes only, and just for security issues or crashes. No end-of-support date announced.
|
||||
v1.20 | v0.47.x | Bugfixes only, and just for security issues or crashes. No end-of-support date announced.
|
||||
v1.19 | v0.47.x | Bugfixes only, and just for security issues or crashes. Fixes only provided until 6 months after Kubernetes v1.22.0 is released.
|
||||
{{< /table >}}
|
||||
|
||||
Because of the updates in Kubernetes 1.22, **v0.47.0** will not work with
|
||||
Kubernetes 1.22.
|
||||
|
||||
# What you need to do
|
||||
|
||||
The team is currently in the process of upgrading ingress-nginx to support
|
||||
the v1 migration, you can track the progress
|
||||
[here](https://github.com/kubernetes/ingress-nginx/pull/7156).
|
||||
We're not making feature improvements to `ingress-nginx` until after the support for
|
||||
Ingress v1 is complete.
|
||||
|
||||
In the meantime to ensure no compatibility issues:
|
||||
|
||||
* Update to the latest version of Ingress-NGINX; currently
|
||||
[v0.47.0](https://github.com/kubernetes/ingress-nginx/releases/tag/controller-v0.47.0)
|
||||
* After Kubernetes 1.22 is released, ensure you are using the latest version of
|
||||
Ingress-NGINX that supports the stable APIs for Ingress and IngressClass.
|
||||
* Test Ingress-NGINX version v1.0.0-alpha.2 with Cluster versions >= 1.19
|
||||
and report any issues to the projects Github page.
|
||||
|
||||
The community’s feedback and support in this effort is welcome. The
|
||||
Ingress-NGINX Sub-project regularly holds community meetings where we discuss
|
||||
this and other issues facing the project. For more information on the sub-project,
|
||||
please see [SIG Network](https://github.com/kubernetes/community/tree/master/sig-network).
|
||||
@@ -0,0 +1,231 @@
|
||||
---
|
||||
layout: blog
|
||||
title: "Roorkee robots, releases and racing: the Kubernetes 1.21 release interview"
|
||||
date: 2021-07-29
|
||||
---
|
||||
|
||||
**Author**: Craig Box (Google)
|
||||
|
||||
With Kubernetes 1.22 due out next week, now is a great time to look back on 1.21. The release team for that version was led by [Nabarun Pal](https://twitter.com/theonlynabarun) from VMware.
|
||||
|
||||
Back in April I [interviewed Nabarun](https://kubernetespodcast.com/episode/146-kubernetes-1.21/) on the weekly [Kubernetes Podcast from Google](https://kubernetespodcast.com/); the latest in a series of release lead conversations that started back with 1.11, not long after the show started back in 2018.
|
||||
|
||||
In these interviews we learn a little about the release, but also about the process behind it, and the story behind the person chosen to lead it. Getting to know a community member is my favourite part of the show each week, and so I encourage you to [subscribe wherever you get your podcasts](https://kubernetespodcast.com/subscribe/). With a release coming next week, you can probably guess what our next topic will be!
|
||||
|
||||
*This transcript has been edited and condensed for clarity.*
|
||||
|
||||
---
|
||||
|
||||
**CRAIG BOX: You have a Bachelor of Technology in Metallurgical and Materials Engineering. How are we doing at turning lead into gold?**
|
||||
|
||||
NABARUN PAL: Well, last I checked, we have yet to find the philosopher's stone!
|
||||
|
||||
**CRAIG BOX: One of the more important parts of the process?**
|
||||
|
||||
NABARUN PAL: We're not doing that well in terms of getting alchemists up and running. There is some improvement in nuclear technology, where you can turn lead into gold, but I would guess buying gold would be much more efficient.
|
||||
|
||||
**CRAIG BOX: Or Bitcoin? It depends what you want to do with the gold.**
|
||||
|
||||
NABARUN PAL: Yeah, seeing the increasing prices of Bitcoin, you'd probably prefer to bet on that. But, don't take this as a suggestion. I'm not a registered investment advisor, and I don't give investment advice!
|
||||
|
||||
**CRAIG BOX: But you are, of course, a trained materials engineer. How did you get into that line of education?**
|
||||
|
||||
NABARUN PAL: We had a graded and equated exam structure, where you sit a single exam, and then based on your performance in that exam, you can try any of the universities which take those scores into account. I went to the Indian Institute of Technology, Roorkee.
|
||||
|
||||
Materials engineering interested me a lot. I had a passion for computer science since childhood, but I also liked material science, so I wanted to explore that field. I did a lot of exploration around material science and metallurgy in my freshman and sophomore years, but then computing, since it was a passion, crept into the picture.
|
||||
|
||||
**CRAIG BOX: Let's dig in there a little bit. What did computing look like during your childhood?**
|
||||
|
||||
NABARUN PAL: It was a very interesting journey. I started exploring computers back when I was seven or eight. For my first programming language, if you call it a programming language, I explored LOGO.
|
||||
|
||||
You have a turtle on the screen, and you issue commands to it, like move forward or rotate or pen up or pen down. You basically draw geometric figures. I could visually see how I could draw a square and how I could draw a triangle. It was an interesting journey after that. I learned BASIC, then went to some amount of HTML, JavaScript.
|
||||
|
||||
**CRAIG BOX: It's interesting to me because Logo and BASIC were probably my first two programming languages, but I think there was probably quite a gap in terms of when HTML became a thing after those two! Did your love of computing always lead you down the path towards programming, or were you interested as a child in using computers for games or application software? What led you specifically into programming?**
|
||||
|
||||
NABARUN PAL: Programming came in late. Not just in computing, but in life, I'm curious with things. When my parents got me my first computer, I was curious. I was like, "how does this operating system work?" What even is running it? Using a television and using a computer is a different experience, but usability is kind of the same thing. The HCI device for a television is a remote, whereas with a computer, I had a keyboard and a mouse. I used to tinker with the box and reinstall operating systems.
|
||||
|
||||
We used to get magazines back then. They used to bundle OpenSuse or Debian, and I used to install them. It was an interesting experience, 15 years back, how Linux used to be. I have been a tinkerer all around, and that's what eventually led me to programming.
|
||||
|
||||
**CRAIG BOX: With an interest in both the physical and ethereal aspects of technology, you did a lot of robotics challenges during university. That's something that I am not surprised to hear from someone who has a background in Logo, to be honest. There's Mindstorms, and a lot of other technology that is based around robotics that a lot of LOGO people got into. How was that something that came about for you?**
|
||||
|
||||
NABARUN PAL: When I joined my university, apart from studying materials, one of the things they used to really encourage was to get involved in a lot of extracurricular activities. One which interested me was robotics. I joined [my college robotics team](https://github.com/marsiitr) and participated in a lot of challenges.
|
||||
|
||||
Predominantly, we used to participate in this competition called [ABU Robocon](https://en.wikipedia.org/wiki/ABU_Robocon), which is an event conducted by the Asia-Pacific Broadcasting Union. What they used to do was, every year, one of the participating countries in the contest would provide a problem statement. For example, one year, they asked us to build a badminton-playing robot. They asked us to build a rugby playing robot or a Frisbee thrower, and there are some interesting problem statements around the challenge: you can't do this. You can't do that. Weight has to be like this. Dimensions have to be like that.
|
||||
|
||||
I got involved in that, and most of my time at university, I used to spend there. Material science became kind of a backburner for me, and my hobby became my full time thing.
|
||||
|
||||
**CRAIG BOX: And you were not only involved there in terms of the project and contributions to it, but you got involved as a secretary of the team, effectively, doing a lot of the organization, which is a thread that will come up as we speak about Kubernetes.**
|
||||
|
||||
NABARUN PAL: Over the course of time, when I gained more knowledge into how the team works, it became very natural that I graduated up the ladder and then managed juniors. I became the joint secretary of the robotics club in our college. This was more of a broad, engaging role in evangelizing robotics at the university, to promote events, to help students to see the value in learning robotics - what you gain out of that mechanically or electronically, or how do you develop your logic by programming robots.
|
||||
|
||||
**CRAIG BOX: Your first job after graduation was working at a company called Algoshelf, but you were also an intern there while you were at school?**
|
||||
|
||||
NABARUN PAL: Algoshelf was known as Rorodata when I joined them as an intern. This was also an interesting opportunity for me in the sense that I was always interested in writing programs which people would use. One of the things that I did there was build an open source Function as a Service framework, if I may call it that - it was mostly turning Python functions into web servers without even writing any code. The interesting bit there was that it was targeted toward data scientists, and not towards programmers. We had to understand the pain of data scientists, that they had to learn a lot of programming in order to even deploy their machine learning models, and we wanted to solve that problem.
|
||||
|
||||
They offered me a job after my internship, and I kept on working for them after I graduated from university. There, I got introduced to Kubernetes, so we pivoted into a product structure where the very same thing I told you, the Functions as a Service thing, could be deployed in Kubernetes. I was exploring Kubernetes to use it as a scalable platform. Instead of managing pets, we wanted to manage cattle, as in, we wanted to have a very highly distributed architecture.
|
||||
|
||||
**CRAIG BOX: Not actual cattle. I've been to India. There are a lot of cows around.**
|
||||
|
||||
NABARUN PAL: Yeah, not actual cattle. That is a bit tough.
|
||||
|
||||
**CRAIG BOX: When Algoshelf we're looking at picking up Kubernetes, what was the evaluation process like? Were you looking at other tools at the time? Or had enough time passed that Kubernetes was clearly the platform that everyone was going to use?**
|
||||
|
||||
NABARUN PAL: Algoshelf was a natural evolution. Before Kubernetes, we used to deploy everything on a single big AWS server, using systemd. Everything was a systemd service, and everything was deployed using Fabric. Fabric is a Python package which essentially is like Ansible, but much leaner, as it does not have all the shims and things that Ansible has.
|
||||
|
||||
Then we asked "what if we need to scale out to different machines?" Kubernetes was in the hype. We hopped onto the hype train to see whether Kubernetes was worth it for us. And that's where my journey started, exploring the ecosystem, exploring the community. How can we improve the community in essence?
|
||||
|
||||
**CRAIG BOX: A couple of times now you've mentioned as you've grown in a role, becoming part of the organization and the arranging of the group. You've talked about working in Python. You had submitted some talks to Pycon India. And I understand you're now a tech lead for that conference. What does the tech community look like in India and how do you describe your involvement in it?**
|
||||
|
||||
NABARUN PAL: My involvement with the community began when I was at university. When I was working as an intern at Algoshelf, I was introduced to this-- I never knew about PyCon India, or tech conferences in general.
|
||||
|
||||
The person that I was working with just asked me, like hey, did you submit a talk to PyCon India? It's very useful, the library that we were making. So I [submitted a talk](https://www.nabarun.in/talk/2017/pyconindia/#1) to PyCon India in 2017. Eventually the talk got selected. That was not my first speaking opportunity, it was my second. I also spoke at PyData Delhi on a similar thing that I worked on in my internship.
|
||||
|
||||
It has been a journey since then. I talked about the same thing at FOSSASIA Summit in Singapore, and got really involved with the Python community because it was what I used to work on back then.
|
||||
|
||||
After giving all those talks at conferences, I got also introduced to this amazing group called [dgplug](https://dgplug.org/), which is an acronym for the Durgapur Linux Users Group. It is a group started in-- I don't remember the exact year, but it was around 12 to 13 years back, by someone called Kushal Das, with the ideology of [training students into being better open source contributors](https://foss.training/).
|
||||
|
||||
I liked the idea and got involved with in teaching last year. It is not limited to students. Professionals can also join in. It's about making anyone better at upstream contributions, making things sustainable. I started training people on Vim, on how to use text editors. so they are more efficient and productive. In general life, text editors are a really good tool.
|
||||
|
||||
The other thing was the shell. How do you navigate around the Linux shell and command line? That has been a fun experience.
|
||||
|
||||
**CRAIG BOX: It's very interesting to think about that, because my own involvement with a Linux User Group was probably around the year 2000. And back then we were teaching people how to install things-- Linux on CD was kinda new at that point in time. There was a lot more of, what is this new thing and how do we get involved? When the internet took off around that time, all of that stuff moved online - you no longer needed to go meet a group of people in a room to talk about Linux. And I haven't really given much thought to the concept of a LUG since then, but it's great to see it having turned into something that's now about contributing, rather than just about how you get things going for yourself.**
|
||||
|
||||
NABARUN PAL: Exactly. So as I mentioned earlier, my journey into Linux was installing SUSE from DVDs that came bundled with magazines. Back then it was a pain installing things because you did not get any instructions. There has certainly been a paradigm shift now. People are more open to reading instructions online, downloading ISOs, and then just installing them. So we really don't need to do that as part of LUGs.
|
||||
|
||||
We have shifted more towards enabling people to contribute to whichever project that they use. For example, if you're using Fedora, contribute to Fedora; make things better. It's just about giving back to the community in any way possible.
|
||||
|
||||
**CRAIG BOX: You're also involved in the [Kubernetes Bangalore meetup group](https://www.meetup.com/Bangalore-Kubernetes-Meetup/). Does that group have a similar mentality?**
|
||||
|
||||
NABARUN PAL: The Kubernetes Bangalore meetup group is essentially focused towards spreading the knowledge of Kubernetes and the aligned products in the ecosystem, whatever there is in the Cloud Native Landscape, in various ways. For example, to evangelize about using them in your company or how people use them in existing ways.
|
||||
|
||||
So a few months back in February, we did something like a [Kubernetes contributor workshop](https://www.youtube.com/watch?v=FgsXbHBRYIc). It was one of its kind in India. It was the first one if I recall correctly. We got a lot of traction and community members interested in contributing to Kubernetes and a lot of other projects. And this is becoming a really valuable thing.
|
||||
|
||||
I'm not much involved in the organization of the group. There are really great people already organizing it. I keep on being around and attending the meetups and trying to answer any questions if people have any.
|
||||
|
||||
**CRAIG BOX: One way that it is possible to contribute to the Kubernetes ecosystem is through the release process. You've [written a blog](https://blog.naba.run/posts/release-enhancements-journey/) which talks about your journey through that. It started in Kubernetes 1.17, where you took a shadow role for that release. Tell me about what it was like to first take that plunge.**
|
||||
|
||||
NABARUN PAL: Taking the plunge was a big step, I would say. It should not have been that way. After getting into the team, I saw that it is really encouraged that you should just apply to the team - but then write truthfully about yourself. What do you want? Write your passionate goal, why you want to be in the team.
|
||||
|
||||
So even right now the shadow applications are open for the next release. I wanted to give that a small shoutout. If you want to contribute to the Kubernetes release team, please do apply. The form is pretty simple. You just need to say why do you want to contribute to the release team.
|
||||
|
||||
**CRAIG BOX: What was your answer to that question?**
|
||||
|
||||
NABARUN PAL: It was a bit tricky. I have this philosophy of contributing to projects that I use in my day-to-day life. I use a lot of open source projects daily, and I started contributing to Kubernetes primarily because I was using the Kubernetes Python client. That was one of my first contributions.
|
||||
|
||||
When I was contributing to that, I explored the release team and it interested me a lot, particularly how interesting and varied the mechanics of releasing Kubernetes are. For most software projects, it's usually whenever you decide that you have made meaningful progress in terms of features, you release it. But Kubernetes is not like that. We follow a regular release cadence. And all those aspects really interested me. I actually applied for the first time in Kubernetes 1.16, but got rejected.
|
||||
|
||||
But I still applied to Kubernetes 1.17, and I got into the enhancements team. That team was led by [MrBobbyTables, Bob Killen](https://kubernetespodcast.com/episode/126-research-steering-honking/), back then, and [Jeremy Rickard](https://kubernetespodcast.com/episode/131-kubernetes-1.20/) was one of my co-shadows in the team. I shadowed enhancements again. Then I lead enhancements in 1.19. I then shadowed the lead in 1.20 and eventually led the 1.21 team. That's what my journey has been.
|
||||
|
||||
My suggestion to people is don't be afraid of failure. Even if you don't get selected, it's perfectly fine. You can still contribute to the release team. Just hop on the release calls, raise your hand, and introduce yourself.
|
||||
|
||||
**CRAIG BOX: Between the 1.20 and 1.21 releases, you moved to work on the upstream contribution team at VMware. I've noticed that VMware is hiring a lot of great upstream contributors at the moment. Is this something that [Stephen Augustus](https://kubernetespodcast.com/episode/130-kubecon-na-2020/) had his fingerprints all over? Is there something in the water?**
|
||||
|
||||
NABARUN PAL: A lot of people have fingerprints on this process. Stephen certainly had his fingerprints on it, I would say. We are expanding the team of upstream contributors primarily because the product that we are working for is based on Kubernetes. It helps us a lot in driving processes upstream and helping out the community as a whole, because everyone then gets enabled and benefits from what we contribute to the community.
|
||||
|
||||
**CRAIG BOX: I understand that the Tanzu team is being built out in India at the moment, but I guess you probably haven't been able to meet them in person yet?**
|
||||
|
||||
NABARUN PAL: Yes and no. I did not meet any of them after joining VMware, but I met a lot of my teammates, before I joined VMware, at KubeCons. For example, I met Nikhita, I met Dims, I met Stephen at KubeCon. I am yet to meet other members of the team and I'm really excited to catch up with them once everything comes out of lockdown and we go back to our normal lives.
|
||||
|
||||
**CRAIG BOX: Yes, everyone that I speak to who has changed jobs in the pandemic says it's a very odd experience, just nothing really being different. And the same perhaps for people who are working on open source moving companies as well. They're doing the same thing, perhaps just for a different employer.**
|
||||
|
||||
NABARUN PAL: As we say in the community, see you in another Slack in some time.
|
||||
|
||||
**CRAIG BOX: We now turn to the recent release of Kubernetes 1.21. First of all, congratulations on that.**
|
||||
|
||||
NABARUN PAL: Thank you.
|
||||
|
||||
**CRAIG BOX: [The announcement](https://kubernetes.io/blog/2021/04/08/kubernetes-1-21-release-announcement/) says the release consists of 51 enhancements, 13 graduating to stable, 16 moving to beta, 20 entering alpha, and then two features that have been deprecated. How would you summarize this release?**
|
||||
|
||||
NABARUN PAL: One of the big points for this release is that it is the largest release of all time.
|
||||
|
||||
**CRAIG BOX: Really?**
|
||||
|
||||
NABARUN PAL: Yep. 1.20 was the largest release back then, but 1.21 got more enhancements, primarily due to a lot of changes that we did to the process.
|
||||
|
||||
In the 1.21 release cycle, we did a few things differently compared to other release cycles-- for example, in the enhancement process. An enhancement, in the Kubernetes context, is basically a feature proposal. You will hear the terminology [Kubernetes Enhancement Proposals](https://github.com/kubernetes/enhancements/blob/master/keps/README.md), or KEP, a lot in the community. An enhancement is a broad thing encapsulated in a specific document.
|
||||
|
||||
**CRAIG BOX: I like to think of it as a thing that's worth having a heading in the release notes.**
|
||||
|
||||
NABARUN PAL: Indeed. Until the 1.20 release cycle, what we used to do was-- the release team has a vertical called enhancements. The enhancements team members used to ping each of the enhancement issues and ask whether they want to be part of the release cycle or not. The authors would decide, or talk to their SIG, and then come back with the answer, as to whether they wanted to be part of the cycle.
|
||||
|
||||
In this release, what we did was we eliminated that process and asked the SIGs proactively to discuss amongst themselves, what they wanted to pitch in for this release cycle. What set of features did they want to graduate this release? They may introduce things in alpha, graduate things to beta or stable, or they may also deprecate features.
|
||||
|
||||
What this did was promote a lot of async processes, and at the same time, give power back to the community. The community decides what they want in the release and then comes back collectively. It also reduces a lot of stress on the release team who previously had to ask people consistently what they wanted to pitch in for the release. You now have a deadline. You discuss amongst your SIG what your roadmap is and what it looks like for the near future. Maybe this release, and the next two. And you put all of those answers into a Google spreadsheet. Spreadsheets are still a thing.
|
||||
|
||||
**CRAIG BOX: The Kubernetes ecosystem runs entirely on Google Spreadsheets.**
|
||||
|
||||
NABARUN PAL: It does, and a lot of Google Docs for meeting notes! We did a lot of process improvements, which essentially led to a better release. This release cycle we had 13 enhancements graduating to stable, 16 which moved to beta, and 20 enhancements which were net new features into the ecosystem, and came in as alpha.
|
||||
|
||||
Along with that are features set for deprecation. One of them was PodSecurityPolicy. That has been a point of discussion in the Kubernetes user base and we also published [a blog post about it](https://kubernetes.io/blog/2021/04/06/podsecuritypolicy-deprecation-past-present-and-future/). All credit to SIG Security who have been on top of things as to find a replacement for PodSecurityPolicy even before this release cycle ended, so that they could at least have a proposal of what will happen next.
|
||||
|
||||
**CRAIG BOX: Let's talk about some old things and some new things. You mentioned PodSecurityPolicy there. That's a thing that's been around a long time and is being deprecated. Two things that have been around a long time and that are now being promoted to stable are CronJobs and PodDisruptionBudgets, both of which were introduced in Kubernetes 1.4, which came out in 2016. Why do you think it took so long for them both to go stable?**
|
||||
|
||||
NABARUN PAL: I might not have a definitive answer to your question. One of the things that I feel is they might be already so good that nobody saw that they were beta features, and just kept on using them.
|
||||
|
||||
One of the things that I noticed when reading for the CronJobs graduation from beta to stable was the new controller. Users might not see this, but there has been a drastic change in the CronJob controller v2. What it essentially does is goes from a poll-based method of checking what users have defined as CronJobs to a queue architecture, which is the modern method of defining controllers. That has been one of the really good improvements in the case of CronJobs. Instead of the controller working in O(N) time, you now have constant time complexity.
|
||||
|
||||
**CRAIG BOX: A lot of these features that have been in beta for a long time, like you say, people have an expectation that they are complete. With PodSecurityPolicy, it's being deprecated, which is allowed because it's a feature that never made it out of beta. But how do you think people will react to it going away? And does that say something about the need for the process to make sure that features don't just languish in beta forever, which has been introduced recently?**
|
||||
|
||||
NABARUN PAL: That's true. One of the driving factors, when contributors are thinking of graduating beta features has been the ["prevention of perma-beta" KEP](https://github.com/kubernetes/enhancements/blob/master/keps/sig-architecture/1635-prevent-permabeta/README.md). Back in 1.19 we [introduced this process](https://kubernetes.io/blog/2020/08/21/moving-forward-from-beta/) where each of the beta resources were marked for deprecation and removal in a certain time frame-- three releases for deprecation and another release for removal. That's also a motivating factor for eventually rethinking as to how beta resources work for us in the community. That is also very effective, I would say.
|
||||
|
||||
**CRAIG BOX: Do remember that Gmail was in beta for eight years.**
|
||||
|
||||
NABARUN PAL: I did not know that!
|
||||
|
||||
**CRAIG BOX: Nothing in Kubernetes is quite that old yet, but we'll get there. Of the 20 new enhancements, do you have a favorite or any that you'd like to call out?**
|
||||
|
||||
NABARUN PAL: There are two specific features in 1.21 that I'm really interested in, and are coming as net new features. One of them is the [persistent volume health monitor](https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1432-volume-health-monitor), which gives the users the capability to actually see whether the backing volumes, which power persistent volumes in Kubernetes, are deleted or not. For example, the volumes may get deleted due to an inadvertent event, or they may get corrupted. That information is basically surfaced out as a field so that the user can leverage it in any way.
|
||||
|
||||
The other feature is the proposal for [adding headers with the command name to kubectl requests](https://github.com/kubernetes/enhancements/tree/master/keps/sig-cli/859-kubectl-headers). We have always set the user-agent information when doing those kind of requests, but the proposal is to add what command the user put in so that we can enable more telemetry, and cluster administrators can determine the usage patterns of how people are using the cluster. I'm really excited about these kind of features coming into play.
|
||||
|
||||
**CRAIG BOX: You're the first release lead from the Asia-Pacific region, or more accurately, outside of the US and Europe. Most meetings in the Kubernetes ecosystem are traditionally in the window of overlap between the US and Europe, in the morning in California and the evening here in the UK. What's it been like to work outside of the time zones that the community had previously been operating in?**
|
||||
|
||||
NABARUN PAL: It has been a fun and a challenging proposition, I would say. In the last two-ish years that I have been contributing to Kubernetes, the community has also transformed from a lot of early morning Pacific calls to more towards async processes. For example, we in the release team have transformed our processes so we don't do updates in the calls anymore. What we do is ask for updates ahead of time, and then in the call, we just discuss things which need to be discussed synchronously in the team.
|
||||
|
||||
We leverage the meetings right now more for discussions. But we also don't come to decisions in those discussions, because if any stakeholder is not present on the call, it puts them at a disadvantage. We are trying to talk more on Slack, publicly, or talk on mailing lists. That's where most of the discussion should happen, and also to gain lazy consensus. What I mean by lazy consensus is come up with a pre-decision kind of thing, but then also invite feedback from the broader community about what people would like them to see about that specific thing being discussed. This is where we as a community are also transforming a lot, but there is a lot more headroom to grow.
|
||||
|
||||
The release team also started to have EU/APAC burndown meetings. In addition to having one meeting focused towards the US and European time zones, we also do a meeting which is more suited towards European and Asia-Pacific time zones. One of the driving factors for those decisions was that the release team is seeing a lot of participation from a variety of time zones. To give you one metric, we had release team members this cycle from UTC+8 all through UTC-8 - 16 hours of span. It's really difficult to accommodate all of those zones in a single meeting. And it's not just those 16 hours of span - what about the other eight hours?
|
||||
|
||||
**CRAIG BOX: Yeah, you're missing New Zealand. You could add another 5 hours of span right there.**
|
||||
|
||||
NABARUN PAL: Exactly. So we will always miss people in meetings, and that's why we should also innovate more, have different kinds of meetings. But that also may not be very sustainable in the future. Will people attend duplicate meetings? Will people follow both of the meetings? More meetings is one of the solutions.
|
||||
|
||||
The other solution is you have threaded discussions on some medium, be it Slack or be it a mailing list. Then, people can just pitch in whenever it is work time for them. Then, at the end of the day, a 24-hour rolling period, you digest it, and then push it out as meeting notes. That's what the Contributor Experience Special Interest Group is doing - shout-out to them for moving to that process. I may be wrong here, but I think once every two weeks, they do async updates on Slack. And that is a really nice thing to have, improving variety of geographies that people can contribute from.
|
||||
|
||||
**CRAIG BOX: Once you've put everything together that you hope to be in your release, you create a release candidate build. How do you motivate people to test those?**
|
||||
|
||||
NABARUN PAL: That's a very interesting question. It is difficult for us to motivate people into trying out these candidates. It's mostly people who are passionate about Kubernetes who try out the release candidates and see for themselves what the bugs are. I remember [Dims tweeting out a call](https://twitter.com/dims/status/1377272238420934656) that if somebody tries out the release candidate and finds a good bug or caveat, they could get a callout in the KubeCon keynote. That's one of the incentives - if you want to be called out in a KubeCon keynote, please try our release candidates.
|
||||
|
||||
**CRAIG BOX: Or get a new pair of Kubernetes socks?**
|
||||
|
||||
NABARUN PAL: We would love to give out goodies to people who try out our release candidates and find bugs. For example, if you want the brand new release team logo as a sticker, just hit me up. If you find a bug in a 1.22 release candidate, I would love to be able to send you some coupon codes for the store. Don't quote me on this, but do reach out.
|
||||
|
||||
**CRAIG BOX: Now the release is out, is it time for you to put your feet up? What more things do you have to do, and how do you feel about the path ahead for yourself?**
|
||||
|
||||
NABARUN PAL: I was discussing this with the team yesterday. Even after the release, we had kind of a water-cooler conversation. I just pasted in a Zoom link to all the release team members and said, hey, do you want to chat? One of the things that I realized that I'm really missing is the daily burndowns right now. I will be around in the release team and the SIG Release meetings, helping out the new lead in transitioning. And even my job, right now, is not over. I'm working with Taylor, who is the emeritus advisor for 1.21, on figuring out some of the mechanics for the next release cycle. I'm also documenting what all we did as part of the process and as part of the process changes, and making sure the next release cycle is up and running.
|
||||
|
||||
**CRAIG BOX: We've done a lot of these release lead interviews now, and there's a question which we always like to ask, which is, what will you write down in the transition envelope? Savitha Raghunathan is the release lead for 1.22. What is the advice that you will pass on to her?**
|
||||
|
||||
NABARUN PAL: Three words-- **Do, Delegate, and Defer**. Categorize things into those three buckets as to what you should do right away, what you need to defer, and things that you can delegate to your shadows or other release team members. That's one of the mantras that works really well when leading a team. It is not just in the context of the release team, but it's in the context of managing any team.
|
||||
|
||||
The other bit is **over-communicate**. No amount of communication is enough. What I've realized is the community is always willing to help you. One of the big examples that I can give is the day before release was supposed to happen, we were seeing a lot of test failures, and then one of the community members had an idea-- why don't you just send an email? I was like, "that sounds good. We can send an email mentioning all the flakes and call out for help to the broader Kubernetes developer community." And eventually, once we sent out the email, lots of people came in to help us in de-flaking the tests and trying to find out the root cause as to why those tests were failing so often. Big shout out to Antonio and all the SIG Network folks who came to pitch in.
|
||||
|
||||
No matter how many names I mention, it will never be enough. A lot of people, even outside the release team, have helped us a lot with this release. And that's where the release theme comes in - **Power to the Community**. I'm really stoked by how this community behaves and how people are willing to help you all the time. It's not about what they're telling you to do, but it's what they're also interested in, they're passionate about.
|
||||
|
||||
**CRAIG BOX: One of the things you're passionate about is Formula One. Do you think Lewis Hamilton is going to take it away this year?**
|
||||
|
||||
NABARUN PAL: It's a fair probability that Lewis will win the title this year as well.
|
||||
|
||||
**CRAIG BOX: Which would take him to eight all time career wins. And thus-- [he's currently tied with Michael Schumacher](https://www.nytimes.com/2020/11/15/sports/autoracing/lewis-hamilton-schumacher-formula-one-record.html)-- would pull him ahead.**
|
||||
|
||||
NABARUN PAL: Yes. Michael Schumacher was my first favorite F1 driver, I would say. It feels a bit heartbreaking to see someone break Michael's record.
|
||||
|
||||
**CRAIG BOX: How do you feel about [Michael Schumacher's son joining the contest?](https://www.formula1.com/en/latest/article.breaking-mick-schumacher-to-race-for-haas-in-2021-as-famous-surname-returns.66XTVfSt80GrZe91lvWVwJ.html)**
|
||||
|
||||
NABARUN PAL: I feel good. Mick Schumacher is in the fray right now. And I wish we could see him, in a few years, in a Ferrari. The Schumacher family back to Ferrari would be really great to see. But then, my fan favorite has always been McLaren, partly because I like the chemistry of Lando and Carlos over the last two years. It was heartbreaking to see Carlos go to Ferrari. But then we have Lando and Daniel Ricciardo in the team. They're also fun people.
|
||||
|
||||
---
|
||||
|
||||
_[Nabarun Pal](https://twitter.com/theonlynabarun) is on the Tanzu team at VMware and served as the Kubernetes 1.21 release team lead._
|
||||
|
||||
_You can find the [Kubernetes Podcast from Google](http://www.kubernetespodcast.com/) at [@KubernetesPod](https://twitter.com/KubernetesPod) on Twitter, and you can [subscribe](https://kubernetespodcast.com/subscribe/) so you never miss an episode._
|
||||
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 20 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:#fbfbfb;}.cls-2{fill:#64c3a5;}.cls-2,.cls-3,.cls-4,.cls-5{fill-rule:evenodd;}.cls-3{fill:#e9d661;}.cls-4{fill:#0582bd;}.cls-5{fill:#808285;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-3.21396" y="-3.67916" width="223.25536" height="134.51136"/><path class="cls-2" d="M109.66922,82.43741A19.57065,19.57065,0,0,1,90.35516,66.01248a19.57588,19.57588,0,0,1,17.35089-16.32394A19.571,19.571,0,0,0,96.842,72.59509a13.28048,13.28048,0,0,0,12.82726,9.84232"/><path class="cls-3" d="M107.70538,49.68854q.96877-.09621,1.96384-.09714a19.59034,19.59034,0,0,1,5.971.93243c-1.19879,3.42362-2.9112,5.60261-4.58257,5.4263a13.51316,13.51316,0,0,0-1.38838-.07249,13.2911,13.2911,0,0,0-12.94535,16.2528,19.572,19.572,0,0,1,10.98151-22.4419"/><path class="cls-4" d="M118.5549,59.2884c-1.24844-1.1244-.77543-3.85447.96614-7.03615a19.56137,19.56137,0,1,1-29.16566,13.762,19.57091,19.57091,0,0,0,19.31384,16.42316,13.27982,13.27982,0,0,0,8.88568-23.149"/><path class="cls-5" d="M148.72465,56.68991a6.07242,6.07242,0,0,0-9.10641,5.25828v24.793H133.331v-24.793a12.36017,12.36017,0,0,1,18.53664-10.70293l-3.143,5.44465Zm24.605-2.97568a12.35685,12.35685,0,0,1,21.57057,8.234v24.793h-6.28659v-24.793a6.07039,6.07039,0,1,0-12.14078,0v24.793h-6.28662v-24.793a6.07006,6.07006,0,1,0-12.14012,0v24.793h-6.28747v-24.793a12.35715,12.35715,0,0,1,21.571-8.234m-79.275-11.71068a6.07292,6.07292,0,0,0-9.10642,5.25869v3.15422h6.60732l-2.79511,6.27307H84.94817V86.74119H78.66091v-39.479A12.3589,12.3589,0,0,1,97.19756,36.55965L94.625,42.333l-.57036-.32949ZM20.49076,54.8028a13.15543,13.15543,0,0,1,10.7037-5.2114c7.03714,0,12.74106,5.1005,12.74106,11.39221l-.01237,16.34832c0,6.29168-5.704,11.39208-12.74112,11.39208s-12.741-5.1004-12.741-11.39208c0-5.26947,3.663-9.84144,9.772-11.47815l9.43621-2.52868.01242-2.34149c0-2.82005-2.895-5.106-6.46627-5.106a7.12669,7.12669,0,0,0-5.22007,2.0919l-.66586.73592L20.49076,54.8028ZM37.64921,69.84037l-.00073,7.49156c-.00018,2.81872-2.89507,5.10548-6.46645,5.10548s-6.46627-2.28565-6.46627-5.10548c0-2.41256,2.2001-4.61169,5.09086-5.38735l7.84259-2.10421Zm29.58343-32.952v14.2779a13.83819,13.83819,0,0,0-6.46716-1.57488c-7.03708,0-12.74094,5.1005-12.74094,11.39221V77.33193c0,6.29168,5.70386,11.39208,12.74094,11.39208s12.74117-5.1004,12.74117-11.39208V36.88838Zm0,24.09523V77.33193c0,2.81983-2.89487,5.10548-6.46628,5.10548s-6.46627-2.28565-6.46627-5.10548V60.98361c0-2.82005,2.89487-5.106,6.46627-5.106s6.46628,2.28592,6.46628,5.106"/></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:transparent;}.cls-2{fill:#64c3a5;}.cls-2,.cls-3,.cls-4,.cls-5{fill-rule:evenodd;}.cls-3{fill:#e9d661;}.cls-4{fill:#0582bd;}.cls-5{fill:#808285;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-3.21396" y="-3.67916" width="223.25536" height="134.51136"/><path class="cls-2" d="M109.66922,82.43741A19.57065,19.57065,0,0,1,90.35516,66.01248a19.57588,19.57588,0,0,1,17.35089-16.32394A19.571,19.571,0,0,0,96.842,72.59509a13.28048,13.28048,0,0,0,12.82726,9.84232"/><path class="cls-3" d="M107.70538,49.68854q.96877-.09621,1.96384-.09714a19.59034,19.59034,0,0,1,5.971.93243c-1.19879,3.42362-2.9112,5.60261-4.58257,5.4263a13.51316,13.51316,0,0,0-1.38838-.07249,13.2911,13.2911,0,0,0-12.94535,16.2528,19.572,19.572,0,0,1,10.98151-22.4419"/><path class="cls-4" d="M118.5549,59.2884c-1.24844-1.1244-.77543-3.85447.96614-7.03615a19.56137,19.56137,0,1,1-29.16566,13.762,19.57091,19.57091,0,0,0,19.31384,16.42316,13.27982,13.27982,0,0,0,8.88568-23.149"/><path class="cls-5" d="M148.72465,56.68991a6.07242,6.07242,0,0,0-9.10641,5.25828v24.793H133.331v-24.793a12.36017,12.36017,0,0,1,18.53664-10.70293l-3.143,5.44465Zm24.605-2.97568a12.35685,12.35685,0,0,1,21.57057,8.234v24.793h-6.28659v-24.793a6.07039,6.07039,0,1,0-12.14078,0v24.793h-6.28662v-24.793a6.07006,6.07006,0,1,0-12.14012,0v24.793h-6.28747v-24.793a12.35715,12.35715,0,0,1,21.571-8.234m-79.275-11.71068a6.07292,6.07292,0,0,0-9.10642,5.25869v3.15422h6.60732l-2.79511,6.27307H84.94817V86.74119H78.66091v-39.479A12.3589,12.3589,0,0,1,97.19756,36.55965L94.625,42.333l-.57036-.32949ZM20.49076,54.8028a13.15543,13.15543,0,0,1,10.7037-5.2114c7.03714,0,12.74106,5.1005,12.74106,11.39221l-.01237,16.34832c0,6.29168-5.704,11.39208-12.74112,11.39208s-12.741-5.1004-12.741-11.39208c0-5.26947,3.663-9.84144,9.772-11.47815l9.43621-2.52868.01242-2.34149c0-2.82005-2.895-5.106-6.46627-5.106a7.12669,7.12669,0,0,0-5.22007,2.0919l-.66586.73592L20.49076,54.8028ZM37.64921,69.84037l-.00073,7.49156c-.00018,2.81872-2.89507,5.10548-6.46645,5.10548s-6.46627-2.28565-6.46627-5.10548c0-2.41256,2.2001-4.61169,5.09086-5.38735l7.84259-2.10421Zm29.58343-32.952v14.2779a13.83819,13.83819,0,0,0-6.46716-1.57488c-7.03708,0-12.74094,5.1005-12.74094,11.39221V77.33193c0,6.29168,5.70386,11.39208,12.74094,11.39208s12.74117-5.1004,12.74117-11.39208V36.88838Zm0,24.09523V77.33193c0,2.81983-2.89487,5.10548-6.46628,5.10548s-6.46627-2.28565-6.46627-5.10548V60.98361c0-2.82005,2.89487-5.106,6.46627-5.106s6.46628,2.28592,6.46628,5.106"/></svg>
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:#fbfbfb;}.cls-2{fill:#040606;}</style></defs><title>kubernetes.io-54664</title><rect class="cls-1" x="-4.55738" y="-4.48481" width="223.25536" height="134.51136"/><path class="cls-2" d="M169.05853,71.307c.23549,6.07483,5.42615,10.38072,14.09569,10.38072,7.0783,0,12.91766-3.06693,12.91766-9.85009,0-4.71846-2.65436-7.49024-8.78885-8.66954l-4.77685-.94382c-3.06756-.59028-5.19066-1.17992-5.19066-3.0079,0-2.00568,2.06471-2.89047,4.65943-2.89047,3.77525,0,5.3081,1.887,5.42678,4.1288H194.951c-.41258-5.89838-5.1304-9.8501-12.73994-9.8501-7.845,0-12.50382,4.30588-12.50382,9.90912,0,6.84157,5.54483,7.96247,10.3217,8.84662l3.95171.70834c2.83082.53062,4.06977,1.35638,4.06977,3.0079,0,1.47444-1.41541,2.94887-4.77748,2.94887-4.89553,0-6.488-2.53631-6.54705-4.71845Zm-27.4259-5.13164a8.58413,8.58413,0,0,1,8.557-8.61113q.02706-.00009.05409,0a8.58415,8.58415,0,0,1,8.61115,8.557q.00009.02706,0,.0541a8.58413,8.58413,0,0,1-8.55641,8.61177q-.02738.00009-.05473,0a8.58413,8.58413,0,0,1-8.61113-8.557q-.00009-.02738,0-.05473M158.79589,81.098h7.49149V50.95811h-7.49149v2.41825a15.58033,15.58033,0,1,0-9.01133,28.37034q.05285.00018.10567,0a15.47693,15.47693,0,0,0,8.90566-2.77179ZM106.59844,66.17532a8.58413,8.58413,0,0,1,8.557-8.61113q.02706-.00009.05409,0a8.58414,8.58414,0,0,1,8.61114,8.557q.00009.02706,0,.05409a8.58413,8.58413,0,0,1-8.55641,8.61177q-.02738.00009-.05473,0a8.58413,8.58413,0,0,1-8.61113-8.557q-.00009-.02738,0-.05473m17.16387-25.47987V53.37636a15.58048,15.58048,0,1,0-9.01195,28.37034q.05251.00018.105,0a15.48233,15.48233,0,0,0,8.90691-2.77179V81.098h7.49023V40.69545ZM96.21772,50.95811H88.72811V81.098h7.49023Zm0-10.26266H88.72811v7.49023h7.49023ZM60.41805,66.17532a8.58414,8.58414,0,0,1,8.557-8.61113q.02673-.00009.05346,0a8.58414,8.58414,0,0,1,8.61114,8.557q.00009.02706,0,.05409a8.58414,8.58414,0,0,1-8.55642,8.61177q-.02736.00009-.05472,0a8.58412,8.58412,0,0,1-8.61113-8.557q-.00009-.02738,0-.05473M77.58067,40.69545V53.37636A15.58033,15.58033,0,1,0,68.56935,81.7467q.05283.00018.10567,0a15.4769,15.4769,0,0,0,8.90565-2.77179V81.098h7.4915V40.69545ZM25.38259,66.176a8.58414,8.58414,0,0,1,8.557-8.61114q.02736-.00009.05472,0a8.58414,8.58414,0,0,1,8.61114,8.557q.00009.027,0,.05409a8.58414,8.58414,0,0,1-8.55642,8.61176q-.02736.00009-.05472,0a8.58413,8.58413,0,0,1-8.61177-8.55641q-.00009-.02768,0-.05535m17.16388,14.9227H50.038V50.95872H42.54647V53.377a15.58048,15.58048,0,1,0-9.01069,28.37035q.0522.00016.10441,0a15.48032,15.48032,0,0,0,8.90628-2.77179Z"/></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:transparent;}.cls-2{fill:#040606;}</style></defs><title>kubernetes.io-54664</title><rect class="cls-1" x="-4.55738" y="-4.48481" width="223.25536" height="134.51136"/><path class="cls-2" d="M169.05853,71.307c.23549,6.07483,5.42615,10.38072,14.09569,10.38072,7.0783,0,12.91766-3.06693,12.91766-9.85009,0-4.71846-2.65436-7.49024-8.78885-8.66954l-4.77685-.94382c-3.06756-.59028-5.19066-1.17992-5.19066-3.0079,0-2.00568,2.06471-2.89047,4.65943-2.89047,3.77525,0,5.3081,1.887,5.42678,4.1288H194.951c-.41258-5.89838-5.1304-9.8501-12.73994-9.8501-7.845,0-12.50382,4.30588-12.50382,9.90912,0,6.84157,5.54483,7.96247,10.3217,8.84662l3.95171.70834c2.83082.53062,4.06977,1.35638,4.06977,3.0079,0,1.47444-1.41541,2.94887-4.77748,2.94887-4.89553,0-6.488-2.53631-6.54705-4.71845Zm-27.4259-5.13164a8.58413,8.58413,0,0,1,8.557-8.61113q.02706-.00009.05409,0a8.58415,8.58415,0,0,1,8.61115,8.557q.00009.02706,0,.0541a8.58413,8.58413,0,0,1-8.55641,8.61177q-.02738.00009-.05473,0a8.58413,8.58413,0,0,1-8.61113-8.557q-.00009-.02738,0-.05473M158.79589,81.098h7.49149V50.95811h-7.49149v2.41825a15.58033,15.58033,0,1,0-9.01133,28.37034q.05285.00018.10567,0a15.47693,15.47693,0,0,0,8.90566-2.77179ZM106.59844,66.17532a8.58413,8.58413,0,0,1,8.557-8.61113q.02706-.00009.05409,0a8.58414,8.58414,0,0,1,8.61114,8.557q.00009.02706,0,.05409a8.58413,8.58413,0,0,1-8.55641,8.61177q-.02738.00009-.05473,0a8.58413,8.58413,0,0,1-8.61113-8.557q-.00009-.02738,0-.05473m17.16387-25.47987V53.37636a15.58048,15.58048,0,1,0-9.01195,28.37034q.05251.00018.105,0a15.48233,15.48233,0,0,0,8.90691-2.77179V81.098h7.49023V40.69545ZM96.21772,50.95811H88.72811V81.098h7.49023Zm0-10.26266H88.72811v7.49023h7.49023ZM60.41805,66.17532a8.58414,8.58414,0,0,1,8.557-8.61113q.02673-.00009.05346,0a8.58414,8.58414,0,0,1,8.61114,8.557q.00009.02706,0,.05409a8.58414,8.58414,0,0,1-8.55642,8.61177q-.02736.00009-.05472,0a8.58412,8.58412,0,0,1-8.61113-8.557q-.00009-.02738,0-.05473M77.58067,40.69545V53.37636A15.58033,15.58033,0,1,0,68.56935,81.7467q.05283.00018.10567,0a15.4769,15.4769,0,0,0,8.90565-2.77179V81.098h7.4915V40.69545ZM25.38259,66.176a8.58414,8.58414,0,0,1,8.557-8.61114q.02736-.00009.05472,0a8.58414,8.58414,0,0,1,8.61114,8.557q.00009.027,0,.05409a8.58414,8.58414,0,0,1-8.55642,8.61176q-.02736.00009-.05472,0a8.58413,8.58413,0,0,1-8.61177-8.55641q-.00009-.02768,0-.05535m17.16388,14.9227H50.038V50.95872H42.54647V53.377a15.58048,15.58048,0,1,0-9.01069,28.37035q.0522.00016.10441,0a15.48032,15.48032,0,0,0,8.90628-2.77179Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:#fbfbfb;}.cls-2{fill:#57565a;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-3.37342" y="-3.34411" width="223.25536" height="134.51136"/><path class="cls-2" d="M81.14242,56.12567,77.99668,64.0731h6.29149l-3.14575-7.94743Zm7.0534,17.78238-2.58263-6.49093h-8.9411L74.089,73.90805h-3.775l9.17231-23.114h3.31256l9.17318,23.114Z"/><path class="cls-2" d="M102.9876,62.3189a2.97367,2.97367,0,0,0-2.74772-1.35853A2.91125,2.91125,0,0,0,97.4913,62.3189a3.7299,3.7299,0,0,0-.43087,1.48937v4.23808A3.73648,3.73648,0,0,0,97.4913,69.537a3.40988,3.40988,0,0,0,5.4963,0,7.0611,7.0611,0,0,0,.66165-3.60929,7.3468,7.3468,0,0,0-.66165-3.60884Zm2.94694,8.8744a6.31949,6.31949,0,0,1-5.69466,3.07919,6.89537,6.89537,0,0,1-3.17945-.72845v7.64965H93.68261v-23.379h3.37782v.49738a6.8926,6.8926,0,0,1,3.17945-.72842,6.31935,6.31935,0,0,1,5.69466,3.079,10.006,10.006,0,0,1,1.09252,5.29783,10.16391,10.16391,0,0,1-1.09252,5.23285Z"/><path class="cls-2" d="M118.79367,62.3189a2.97667,2.97667,0,0,0-2.74944-1.35853,2.9108,2.9108,0,0,0-2.74859,1.35853,3.75853,3.75853,0,0,0-.43,1.48937v4.23808a3.76517,3.76517,0,0,0,.43,1.49068,3.41159,3.41159,0,0,0,5.498,0,7.07027,7.07027,0,0,0,.66078-3.60929,7.35645,7.35645,0,0,0-.66078-3.60884Zm2.94608,8.8744a6.32,6.32,0,0,1-5.69552,3.07919,6.88941,6.88941,0,0,1-3.1786-.72845v7.64965h-3.3778v-23.379h3.3778v.49738a6.88664,6.88664,0,0,1,3.1786-.72842,6.31981,6.31981,0,0,1,5.69552,3.079,10.00267,10.00267,0,0,1,1.093,5.29783,10.16449,10.16449,0,0,1-1.093,5.23285Z"/><path class="cls-2" d="M132.96442,54.20565h-3.80825v16.259h3.80825c6.58968,0,6.35717-2.25263,6.35717-8.113,0-5.8944.23251-8.14595-6.35717-8.14595Zm9.60232,13.179c-.828,5.53-4.6687,6.52343-9.60232,6.52343h-7.31875v-23.114h7.31875c4.93362,0,8.7743.96057,9.60232,6.52326a36.3302,36.3302,0,0,1,.26577,5.03426,36.58042,36.58042,0,0,1-.26577,5.033Z"/><polygon class="cls-2" points="146.109 73.908 146.109 57.55 149.52 57.55 149.52 73.908 146.109 73.908 146.109 73.908"/><polygon class="cls-2" points="146.109 54.565 146.109 50.638 149.52 50.638 149.52 54.565 146.109 54.565 146.109 54.565"/><path class="cls-2" d="M161.67111,61.45749a3.97853,3.97853,0,0,0-2.185-.66277c-1.35871,0-3.08048.79467-3.08048,2.352V73.90805h-3.30952V57.71553h3.30952v.49609a7.36373,7.36373,0,0,1,3.08048-.662,8.37517,8.37517,0,0,1,3.676.86135l-1.491,3.04647Z"/><path class="cls-2" d="M173.35993,62.25243a3.00221,3.00221,0,0,0-2.71661-1.39145,3.30382,3.30382,0,0,0-3.609,2.98125h6.72194a4.32873,4.32873,0,0,0-.3963-1.5898ZM166.934,67.11957a5.0516,5.0516,0,0,0,.66295,2.352,3.97682,3.97682,0,0,0,3.345,1.48937,4.29333,4.29333,0,0,0,3.44307-1.55606l2.71705,2.01943a7.84563,7.84563,0,0,1-6.12728,2.78251,7.20688,7.20688,0,0,1-6.22535-2.94833,9.72791,9.72791,0,0,1-1.2589-5.397,9.71813,9.71813,0,0,1,1.2589-5.39724,6.77573,6.77573,0,0,1,5.92674-2.88061,6.353,6.353,0,0,1,5.5313,2.91333c1.19191,1.78819,1.02553,4.53689.99181,6.62261Z"/><path class="cls-2" d="M186.53109,74.17309c-4.70242,0-7.48386-3.54363-7.48386-8.411,0-4.90111,2.78144-8.44475,7.48386-8.44475,2.31728,0,3.84152.62923,6.2258,3.17962l-2.48411,2.18509c-1.78787-1.92-2.51607-2.18509-3.74169-2.18509a3.67433,3.67433,0,0,0-3.14532,1.49064,6.08445,6.08445,0,0,0-.86174,3.77449,6.04264,6.04264,0,0,0,.86174,3.74221,3.59542,3.59542,0,0,0,3.14532,1.48939c1.22562,0,1.95382-.26505,3.74169-2.15137l2.48411,2.18534c-2.38428,2.51638-3.90852,3.14543-6.2258,3.14543Z"/><path class="cls-2" d="M194.70206,57.54967V53.72892l3.24471-.55054v4.37129h2.88082v3.04669h-2.88082V69.6035a2.65978,2.65978,0,0,0,.03327.7282.3886.3886,0,0,0,.3963.23233h2.0878v3.344h-2.0878a3.50427,3.50427,0,0,1-3.07832-1.655,4.8599,4.8599,0,0,1-.596-2.64952V57.54967Z"/><polygon class="cls-2" points="16.87 77.995 30.665 71.993 37.34 52.213 30.585 41.486 16.87 77.995 16.87 77.995"/><polygon class="cls-2" points="30.277 38.06 47.2 64.828 57.151 60.51 41.284 38.06 30.277 38.06 30.277 38.06"/><polygon class="cls-2" points="64.356 59.132 14.131 80.907 24.836 88.213 58.498 73.908 64.356 59.132 64.356 59.132"/></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:transparent;}.cls-2{fill:#57565a;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-3.37342" y="-3.34411" width="223.25536" height="134.51136"/><path class="cls-2" d="M81.14242,56.12567,77.99668,64.0731h6.29149l-3.14575-7.94743Zm7.0534,17.78238-2.58263-6.49093h-8.9411L74.089,73.90805h-3.775l9.17231-23.114h3.31256l9.17318,23.114Z"/><path class="cls-2" d="M102.9876,62.3189a2.97367,2.97367,0,0,0-2.74772-1.35853A2.91125,2.91125,0,0,0,97.4913,62.3189a3.7299,3.7299,0,0,0-.43087,1.48937v4.23808A3.73648,3.73648,0,0,0,97.4913,69.537a3.40988,3.40988,0,0,0,5.4963,0,7.0611,7.0611,0,0,0,.66165-3.60929,7.3468,7.3468,0,0,0-.66165-3.60884Zm2.94694,8.8744a6.31949,6.31949,0,0,1-5.69466,3.07919,6.89537,6.89537,0,0,1-3.17945-.72845v7.64965H93.68261v-23.379h3.37782v.49738a6.8926,6.8926,0,0,1,3.17945-.72842,6.31935,6.31935,0,0,1,5.69466,3.079,10.006,10.006,0,0,1,1.09252,5.29783,10.16391,10.16391,0,0,1-1.09252,5.23285Z"/><path class="cls-2" d="M118.79367,62.3189a2.97667,2.97667,0,0,0-2.74944-1.35853,2.9108,2.9108,0,0,0-2.74859,1.35853,3.75853,3.75853,0,0,0-.43,1.48937v4.23808a3.76517,3.76517,0,0,0,.43,1.49068,3.41159,3.41159,0,0,0,5.498,0,7.07027,7.07027,0,0,0,.66078-3.60929,7.35645,7.35645,0,0,0-.66078-3.60884Zm2.94608,8.8744a6.32,6.32,0,0,1-5.69552,3.07919,6.88941,6.88941,0,0,1-3.1786-.72845v7.64965h-3.3778v-23.379h3.3778v.49738a6.88664,6.88664,0,0,1,3.1786-.72842,6.31981,6.31981,0,0,1,5.69552,3.079,10.00267,10.00267,0,0,1,1.093,5.29783,10.16449,10.16449,0,0,1-1.093,5.23285Z"/><path class="cls-2" d="M132.96442,54.20565h-3.80825v16.259h3.80825c6.58968,0,6.35717-2.25263,6.35717-8.113,0-5.8944.23251-8.14595-6.35717-8.14595Zm9.60232,13.179c-.828,5.53-4.6687,6.52343-9.60232,6.52343h-7.31875v-23.114h7.31875c4.93362,0,8.7743.96057,9.60232,6.52326a36.3302,36.3302,0,0,1,.26577,5.03426,36.58042,36.58042,0,0,1-.26577,5.033Z"/><polygon class="cls-2" points="146.109 73.908 146.109 57.55 149.52 57.55 149.52 73.908 146.109 73.908 146.109 73.908"/><polygon class="cls-2" points="146.109 54.565 146.109 50.638 149.52 50.638 149.52 54.565 146.109 54.565 146.109 54.565"/><path class="cls-2" d="M161.67111,61.45749a3.97853,3.97853,0,0,0-2.185-.66277c-1.35871,0-3.08048.79467-3.08048,2.352V73.90805h-3.30952V57.71553h3.30952v.49609a7.36373,7.36373,0,0,1,3.08048-.662,8.37517,8.37517,0,0,1,3.676.86135l-1.491,3.04647Z"/><path class="cls-2" d="M173.35993,62.25243a3.00221,3.00221,0,0,0-2.71661-1.39145,3.30382,3.30382,0,0,0-3.609,2.98125h6.72194a4.32873,4.32873,0,0,0-.3963-1.5898ZM166.934,67.11957a5.0516,5.0516,0,0,0,.66295,2.352,3.97682,3.97682,0,0,0,3.345,1.48937,4.29333,4.29333,0,0,0,3.44307-1.55606l2.71705,2.01943a7.84563,7.84563,0,0,1-6.12728,2.78251,7.20688,7.20688,0,0,1-6.22535-2.94833,9.72791,9.72791,0,0,1-1.2589-5.397,9.71813,9.71813,0,0,1,1.2589-5.39724,6.77573,6.77573,0,0,1,5.92674-2.88061,6.353,6.353,0,0,1,5.5313,2.91333c1.19191,1.78819,1.02553,4.53689.99181,6.62261Z"/><path class="cls-2" d="M186.53109,74.17309c-4.70242,0-7.48386-3.54363-7.48386-8.411,0-4.90111,2.78144-8.44475,7.48386-8.44475,2.31728,0,3.84152.62923,6.2258,3.17962l-2.48411,2.18509c-1.78787-1.92-2.51607-2.18509-3.74169-2.18509a3.67433,3.67433,0,0,0-3.14532,1.49064,6.08445,6.08445,0,0,0-.86174,3.77449,6.04264,6.04264,0,0,0,.86174,3.74221,3.59542,3.59542,0,0,0,3.14532,1.48939c1.22562,0,1.95382-.26505,3.74169-2.15137l2.48411,2.18534c-2.38428,2.51638-3.90852,3.14543-6.2258,3.14543Z"/><path class="cls-2" d="M194.70206,57.54967V53.72892l3.24471-.55054v4.37129h2.88082v3.04669h-2.88082V69.6035a2.65978,2.65978,0,0,0,.03327.7282.3886.3886,0,0,0,.3963.23233h2.0878v3.344h-2.0878a3.50427,3.50427,0,0,1-3.07832-1.655,4.8599,4.8599,0,0,1-.596-2.64952V57.54967Z"/><polygon class="cls-2" points="16.87 77.995 30.665 71.993 37.34 52.213 30.585 41.486 16.87 77.995 16.87 77.995"/><polygon class="cls-2" points="30.277 38.06 47.2 64.828 57.151 60.51 41.284 38.06 30.277 38.06 30.277 38.06"/><polygon class="cls-2" points="64.356 59.132 14.131 80.907 24.836 88.213 58.498 73.908 64.356 59.132 64.356 59.132"/></svg>
|
||||
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 224 KiB After Width: | Height: | Size: 224 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:#fbfbfb;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-3.00001" y="-3.45836" width="223.25536" height="134.51136"/><g id="layer1"><path id="path14" d="M52.57518,56.39988v16.0054h8.94419l-1.2105,3.09349H48.6747V56.39991h3.90048"/><path id="path16" d="M127.89467,65.07506c2.48824-.94148,5.38-3.09349,5.38-6.65769,0-4.43848-3.83322-6.65769-9.28044-6.65769h-7.12845V75.49877h4.23673V65.74759h2.48823l6.59044,9.75118h4.77473l-7.0612-10.42368Zm-4.70747-2.35373h-2.08473V54.58412h2.62273c3.42972,0,5.31272,1.076,5.31272,4.035,0,3.16072-2.28649,4.10223-5.85071,4.10223"/><path id="path18" d="M68.98407,56.39988l.60525,1.47949L62.19187,75.49874h3.63148l1.614-3.90048h8.40619l1.68124,3.90048h4.304L73.3553,56.39988H68.98407Zm-.33625,12.30668,2.89174-7.06121,2.959,7.06121H68.64783"/><path id="path28" d="M41.27726,62.78859a5.40414,5.40414,0,0,0,4.10222-5.24547c0-5.78347-6.99395-5.78347-9.21318-5.78347H28.7016V75.49874h7.12845c4.16947,0,10.89442-1.00874,10.89442-6.85945C46.72447,65.41131,44.77423,63.32659,41.27726,62.78859Zm-5.649-8.13721c3.16072,0,5.31271.33625,5.31271,3.16073,0,3.83322-3.90047,3.63146-5.78345,3.63146h-2.152V54.58412l2.62273.06726Zm.06724,17.75387-2.69-.06726V64.537h2.48823c3.766,0,6.7922.538,6.7922,3.90048,0,3.29522-2.48823,3.96772-6.59046,3.96772"/><path id="path30" d="M98.84287,56.39988h3.96772V75.49874H98.84287Zm12.23941,0-8.06994,9.14595,8.13719,9.95294h4.50571L107.4508,65.34408l7.59921-8.9442h-3.96773"/><path id="path40" d="M80.95449,65.34405c0,6.25421,3.90048,10.49094,9.21318,10.49094a10.18329,10.18329,0,0,0,6.38871-1.95023l-.94149-1.883A9.90036,9.90036,0,0,1,91.17642,73.145c-3.42973,0-5.918-2.48823-5.918-7.66644,0-4.16946,1.54675-6.65769,4.50572-6.65769,1.614,0,2.959.538,3.497,2.152l3.42972-.87425c-.33625-1.345-2.152-3.96771-7.12845-3.96771-4.573,0-8.60794,3.09349-8.60794,9.21318"/><path id="path50" d="M171.67412,56.39988h3.90048V75.49874h-3.90048Zm12.23941,0-8.13721,9.14595,8.13721,9.95294h4.64021L180.282,65.34408l7.5992-8.9442h-3.96771"/><path id="path52" d="M153.71849,65.34405c0,6.25421,3.83322,10.49094,9.07869,10.49094a10.11878,10.11878,0,0,0,6.456-1.95023l-.94148-1.883A9.953,9.953,0,0,1,163.806,73.145c-3.42973,0-5.8507-2.48823-5.8507-7.66644,0-4.16946,1.54674-6.65769,4.573-6.65769a3.35862,3.35862,0,0,1,3.497,2.152l3.36248-.87425c-.33625-1.345-2.08475-3.96771-7.0612-3.96771-4.64021,0-8.60795,3.09349-8.60795,9.21318"/><path id="path54" d="M143.16032,56.13087c-5.17821,0-8.94419,3.09349-8.94419,9.81844s3.56423,9.88568,8.94419,9.88568,8.9442-3.16072,8.9442-9.88568S148.33853,56.13087,143.16032,56.13087Zm0,17.01414c-3.96771,0-4.90922-3.228-4.90922-7.1957,0-3.90048.94148-7.26295,4.90922-7.26295s4.90922,3.36247,4.90922,7.26295c0,3.96772-.94148,7.1957-4.90922,7.1957"/></g></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:transparent;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-3.00001" y="-3.45836" width="223.25536" height="134.51136"/><g id="layer1"><path id="path14" d="M52.57518,56.39988v16.0054h8.94419l-1.2105,3.09349H48.6747V56.39991h3.90048"/><path id="path16" d="M127.89467,65.07506c2.48824-.94148,5.38-3.09349,5.38-6.65769,0-4.43848-3.83322-6.65769-9.28044-6.65769h-7.12845V75.49877h4.23673V65.74759h2.48823l6.59044,9.75118h4.77473l-7.0612-10.42368Zm-4.70747-2.35373h-2.08473V54.58412h2.62273c3.42972,0,5.31272,1.076,5.31272,4.035,0,3.16072-2.28649,4.10223-5.85071,4.10223"/><path id="path18" d="M68.98407,56.39988l.60525,1.47949L62.19187,75.49874h3.63148l1.614-3.90048h8.40619l1.68124,3.90048h4.304L73.3553,56.39988H68.98407Zm-.33625,12.30668,2.89174-7.06121,2.959,7.06121H68.64783"/><path id="path28" d="M41.27726,62.78859a5.40414,5.40414,0,0,0,4.10222-5.24547c0-5.78347-6.99395-5.78347-9.21318-5.78347H28.7016V75.49874h7.12845c4.16947,0,10.89442-1.00874,10.89442-6.85945C46.72447,65.41131,44.77423,63.32659,41.27726,62.78859Zm-5.649-8.13721c3.16072,0,5.31271.33625,5.31271,3.16073,0,3.83322-3.90047,3.63146-5.78345,3.63146h-2.152V54.58412l2.62273.06726Zm.06724,17.75387-2.69-.06726V64.537h2.48823c3.766,0,6.7922.538,6.7922,3.90048,0,3.29522-2.48823,3.96772-6.59046,3.96772"/><path id="path30" d="M98.84287,56.39988h3.96772V75.49874H98.84287Zm12.23941,0-8.06994,9.14595,8.13719,9.95294h4.50571L107.4508,65.34408l7.59921-8.9442h-3.96773"/><path id="path40" d="M80.95449,65.34405c0,6.25421,3.90048,10.49094,9.21318,10.49094a10.18329,10.18329,0,0,0,6.38871-1.95023l-.94149-1.883A9.90036,9.90036,0,0,1,91.17642,73.145c-3.42973,0-5.918-2.48823-5.918-7.66644,0-4.16946,1.54675-6.65769,4.50572-6.65769,1.614,0,2.959.538,3.497,2.152l3.42972-.87425c-.33625-1.345-2.152-3.96771-7.12845-3.96771-4.573,0-8.60794,3.09349-8.60794,9.21318"/><path id="path50" d="M171.67412,56.39988h3.90048V75.49874h-3.90048Zm12.23941,0-8.13721,9.14595,8.13721,9.95294h4.64021L180.282,65.34408l7.5992-8.9442h-3.96771"/><path id="path52" d="M153.71849,65.34405c0,6.25421,3.83322,10.49094,9.07869,10.49094a10.11878,10.11878,0,0,0,6.456-1.95023l-.94148-1.883A9.953,9.953,0,0,1,163.806,73.145c-3.42973,0-5.8507-2.48823-5.8507-7.66644,0-4.16946,1.54674-6.65769,4.573-6.65769a3.35862,3.35862,0,0,1,3.497,2.152l3.36248-.87425c-.33625-1.345-2.08475-3.96771-7.0612-3.96771-4.64021,0-8.60795,3.09349-8.60795,9.21318"/><path id="path54" d="M143.16032,56.13087c-5.17821,0-8.94419,3.09349-8.94419,9.81844s3.56423,9.88568,8.94419,9.88568,8.9442-3.16072,8.9442-9.88568S148.33853,56.13087,143.16032,56.13087Zm0,17.01414c-3.96771,0-4.90922-3.228-4.90922-7.1957,0-3.90048.94148-7.26295,4.90922-7.26295s4.90922,3.36247,4.90922,7.26295c0,3.96772-.94148,7.1957-4.90922,7.1957"/></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 9.2 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:#fbfbfb;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-3.55202" y="-3.16104" width="223.25536" height="134.51136"/><path id="path5" d="M141.73824,63.05113H127.82345l2.25647-3.85486c.93932-1.59742,1.78587-2.16178,3.19675-2.16178,1.40994,0,1.88056,1.12776,1.12871,2.5377h14.197l1.4109-2.5377c1.034-1.88055,1.034-3.94955-1.50463-3.94955h-25.0097c-2.25648,0-4.04329.28218-5.35949,2.44492l-4.41922,7.52127c-1.2215,2.16274-1.12776,3.94956,1.88056,3.94956h14.3854L127.636,71.13676a3.487,3.487,0,0,1-3.47894,1.88056c-1.69307,0-1.59837-1.12776-.84654-2.25552H109.20724l-1.69307,2.82084c-1.034,1.78681-.18748,3.38519,2.25648,3.38519h24.82127a6.07295,6.07295,0,0,0,5.35949-2.91457l4.23078-7.05162C145.12343,65.21387,144.65281,63.05113,141.73824,63.05113Z"/><path id="path7" d="M202.14279,57.7299a2.01608,2.01608,0,1,0,2.06708,2.00395A2.04547,2.04547,0,0,0,202.14279,57.7299Zm0,3.63676a1.62259,1.62259,0,1,1,1.673-1.63377A1.64448,1.64448,0,0,1,202.14279,61.36666Z"/><path id="path9" d="M109.67787,53.08494H88.42834c-2.91458,0-6.67569,0-8.93217,3.94955l-9.4028,15.98283c-1.31619,2.16274-.18748,3.94956,2.25648,3.94956H97.07833c2.53865,0,4.137-.7528,6.11133-3.94956l9.40279-15.98283C113.814,54.96645,111.9334,53.08494,109.67787,53.08494ZM97.73642,59.19627l-7.05065,11.9405c-.94028,1.69307-1.78682,1.88055-3.94955,1.88055s-2.7271-.75184-2.068-1.88055l7.14535-11.94049a3.9896,3.9896,0,0,1,4.0433-2.16179C97.64364,57.03449,98.6767,57.59885,97.73642,59.19627Z"/><path id="path11" d="M72.44455,53.08494H45.17837L33.42631,73.01732h-25.95l.01294,3.94956H59.846c3.47893,0,4.60669-1.69308,5.35949-3.00928l2.81988-4.88887c.7528-1.3162.7528-2.82084-.75184-3.66642a5.94452,5.94452,0,0,0,4.79513-3.19676l2.82085-4.79514C76.30036,55.06019,74.60728,53.08494,72.44455,53.08494ZM58.436,69.16342,57.02512,71.419a2.662,2.662,0,0,1-2.6324,1.59837H47.43485l3.57554-6.01663H57.777C58.99942,67.00069,58.99942,68.12845,58.436,69.16342Zm5.9229-9.96715L62.948,61.45275a2.662,2.662,0,0,1-2.6324,1.59838H53.35774l3.57268-6.01664h6.76943C64.92327,57.03449,64.92327,58.16225,64.35891,59.19627Z"/><path id="path13" d="M203.20455,59.20871a.55269.55269,0,0,0-.25635-.485,1.13731,1.13731,0,0,0-.56532-.10809h-1.01107v2.25457h.34244V59.83046h.40462l.66193,1.0388h.3941l-.7021-1.0388C202.88507,59.81994,203.20455,59.6535,203.20455,59.20871Zm-1.11341.34244h-.37687V58.872h.5988c.29173,0,.54809.03922.54809.331C202.86211,59.60854,202.41636,59.55115,202.09114,59.55115Z"/><path id="polygon1317" d="M168.49306,57.03164h35.25806l-.011-3.94955H156.741L142.73151,76.964h32.71941l2.35022-3.94955H159.09122l3.57267-6.01664h18.70993l2.25649-3.94955H165.01508Z"/></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:transparent;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-3.55202" y="-3.16104" width="223.25536" height="134.51136"/><path id="path5" d="M141.73824,63.05113H127.82345l2.25647-3.85486c.93932-1.59742,1.78587-2.16178,3.19675-2.16178,1.40994,0,1.88056,1.12776,1.12871,2.5377h14.197l1.4109-2.5377c1.034-1.88055,1.034-3.94955-1.50463-3.94955h-25.0097c-2.25648,0-4.04329.28218-5.35949,2.44492l-4.41922,7.52127c-1.2215,2.16274-1.12776,3.94956,1.88056,3.94956h14.3854L127.636,71.13676a3.487,3.487,0,0,1-3.47894,1.88056c-1.69307,0-1.59837-1.12776-.84654-2.25552H109.20724l-1.69307,2.82084c-1.034,1.78681-.18748,3.38519,2.25648,3.38519h24.82127a6.07295,6.07295,0,0,0,5.35949-2.91457l4.23078-7.05162C145.12343,65.21387,144.65281,63.05113,141.73824,63.05113Z"/><path id="path7" d="M202.14279,57.7299a2.01608,2.01608,0,1,0,2.06708,2.00395A2.04547,2.04547,0,0,0,202.14279,57.7299Zm0,3.63676a1.62259,1.62259,0,1,1,1.673-1.63377A1.64448,1.64448,0,0,1,202.14279,61.36666Z"/><path id="path9" d="M109.67787,53.08494H88.42834c-2.91458,0-6.67569,0-8.93217,3.94955l-9.4028,15.98283c-1.31619,2.16274-.18748,3.94956,2.25648,3.94956H97.07833c2.53865,0,4.137-.7528,6.11133-3.94956l9.40279-15.98283C113.814,54.96645,111.9334,53.08494,109.67787,53.08494ZM97.73642,59.19627l-7.05065,11.9405c-.94028,1.69307-1.78682,1.88055-3.94955,1.88055s-2.7271-.75184-2.068-1.88055l7.14535-11.94049a3.9896,3.9896,0,0,1,4.0433-2.16179C97.64364,57.03449,98.6767,57.59885,97.73642,59.19627Z"/><path id="path11" d="M72.44455,53.08494H45.17837L33.42631,73.01732h-25.95l.01294,3.94956H59.846c3.47893,0,4.60669-1.69308,5.35949-3.00928l2.81988-4.88887c.7528-1.3162.7528-2.82084-.75184-3.66642a5.94452,5.94452,0,0,0,4.79513-3.19676l2.82085-4.79514C76.30036,55.06019,74.60728,53.08494,72.44455,53.08494ZM58.436,69.16342,57.02512,71.419a2.662,2.662,0,0,1-2.6324,1.59837H47.43485l3.57554-6.01663H57.777C58.99942,67.00069,58.99942,68.12845,58.436,69.16342Zm5.9229-9.96715L62.948,61.45275a2.662,2.662,0,0,1-2.6324,1.59838H53.35774l3.57268-6.01664h6.76943C64.92327,57.03449,64.92327,58.16225,64.35891,59.19627Z"/><path id="path13" d="M203.20455,59.20871a.55269.55269,0,0,0-.25635-.485,1.13731,1.13731,0,0,0-.56532-.10809h-1.01107v2.25457h.34244V59.83046h.40462l.66193,1.0388h.3941l-.7021-1.0388C202.88507,59.81994,203.20455,59.6535,203.20455,59.20871Zm-1.11341.34244h-.37687V58.872h.5988c.29173,0,.54809.03922.54809.331C202.86211,59.60854,202.41636,59.55115,202.09114,59.55115Z"/><path id="polygon1317" d="M168.49306,57.03164h35.25806l-.011-3.94955H156.741L142.73151,76.964h32.71941l2.35022-3.94955H159.09122l3.57267-6.01664h18.70993l2.25649-3.94955H165.01508Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:#fbfbfb;}.cls-2{fill:#0071f7;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-3.55202" y="-3.16104" width="223.25536" height="134.51136"/><path class="cls-2" d="M174.27862,87.85821a5.22494,5.22494,0,0,1-.67887,7.12815,5.66277,5.66277,0,0,1-7.46759-.67888l-11.88024-15.2746L142.71111,93.968c-1.69718,2.37606-5.09153,2.37606-7.46758.67888a4.96011,4.96011,0,0,1-1.01831-7.12815l13.57742-17.65065L134.22522,52.21747a5.32925,5.32925,0,0,1,8.48589-6.44927l11.54081,15.2746,11.88024-14.59574c1.69718-2.376,4.75211-2.71548,7.46759-1.0183,2.376,1.69717,2.376,5.09153.67887,7.46758l-13.238,17.31121Zm-61.77727-2.03662a15.64926,15.64926,0,0,1-15.95348-15.614,15.95716,15.95716,0,0,1,31.907,0A16.08546,16.08546,0,0,1,112.50135,85.82159Zm-46.84212,0a15.64926,15.64926,0,0,1-15.95347-15.614,15.95716,15.95716,0,0,1,31.907,0A15.64926,15.64926,0,0,1,65.65923,85.82159Zm46.84212-41.41114A26.28086,26.28086,0,0,0,89.41973,57.98787,26.42342,26.42342,0,0,0,65.99867,44.41045,27.90043,27.90043,0,0,0,50.0452,49.502V27.77811a5.22038,5.22038,0,0,0-5.09153-5.09154,5.297,5.297,0,0,0-5.431,5.09154V70.547A26.00829,26.00829,0,0,0,65.65923,96.00466,26.718,26.718,0,0,0,89.08029,82.0878a26.58818,26.58818,0,0,0,23.08162,13.91686,26.22192,26.22192,0,0,0,26.476-26.13654C138.97732,55.95126,127.09708,44.41045,112.50135,44.41045Z"/></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:transparent;}.cls-2{fill:#0071f7;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-3.55202" y="-3.16104" width="223.25536" height="134.51136"/><path class="cls-2" d="M174.27862,87.85821a5.22494,5.22494,0,0,1-.67887,7.12815,5.66277,5.66277,0,0,1-7.46759-.67888l-11.88024-15.2746L142.71111,93.968c-1.69718,2.37606-5.09153,2.37606-7.46758.67888a4.96011,4.96011,0,0,1-1.01831-7.12815l13.57742-17.65065L134.22522,52.21747a5.32925,5.32925,0,0,1,8.48589-6.44927l11.54081,15.2746,11.88024-14.59574c1.69718-2.376,4.75211-2.71548,7.46759-1.0183,2.376,1.69717,2.376,5.09153.67887,7.46758l-13.238,17.31121Zm-61.77727-2.03662a15.64926,15.64926,0,0,1-15.95348-15.614,15.95716,15.95716,0,0,1,31.907,0A16.08546,16.08546,0,0,1,112.50135,85.82159Zm-46.84212,0a15.64926,15.64926,0,0,1-15.95347-15.614,15.95716,15.95716,0,0,1,31.907,0A15.64926,15.64926,0,0,1,65.65923,85.82159Zm46.84212-41.41114A26.28086,26.28086,0,0,0,89.41973,57.98787,26.42342,26.42342,0,0,0,65.99867,44.41045,27.90043,27.90043,0,0,0,50.0452,49.502V27.77811a5.22038,5.22038,0,0,0-5.09153-5.09154,5.297,5.297,0,0,0-5.431,5.09154V70.547A26.00829,26.00829,0,0,0,65.65923,96.00466,26.718,26.718,0,0,0,89.08029,82.0878a26.58818,26.58818,0,0,0,23.08162,13.91686,26.22192,26.22192,0,0,0,26.476-26.13654C138.97732,55.95126,127.09708,44.41045,112.50135,44.41045Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 215 127"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:#fbfbfb;}.cls-3{fill:#192534;}.cls-4{mask:url(#mask);}.cls-5{mask:url(#mask-2-2);}.cls-6{mask:url(#mask-3);}</style><mask id="mask" x="14.75095" y="70.72244" width="32.48851" height="10.3304" maskUnits="userSpaceOnUse"><g id="mask-2"><polygon id="path-1" class="cls-1" points="14.751 81.053 14.751 70.722 47.239 70.722 47.239 81.053 14.751 81.053"/></g></mask><mask id="mask-2-2" x="14.75095" y="60.57418" width="32.48851" height="10.3304" maskUnits="userSpaceOnUse"><g id="mask-4"><polygon id="path-3" class="cls-1" points="14.751 70.905 14.751 60.574 47.239 60.574 47.239 70.905 14.751 70.905"/></g></mask><mask id="mask-3" x="14.75079" y="45.87467" width="32.48853" height="14.92678" maskUnits="userSpaceOnUse"><g id="mask-6"><polygon id="path-5" class="cls-1" points="14.751 60.801 14.751 45.875 47.239 45.875 47.239 60.801 14.751 60.801"/></g></mask></defs><title>kubernetes.io-logos</title><rect class="cls-2" x="-3.55202" y="-3.16104" width="223.25536" height="134.51136"/><g id="Symbols"><g id="Mobile-Header"><g id="Group-4"><g id="Mobile-Logo"><g id="Group"><g id="Group-3"><path id="Fill-1" class="cls-3" d="M190.28379,79.32487h-6.37906V54.34018h6.37906v3.41436a10.33414,10.33414,0,0,1,7.73637-4.03515v6.41449a8.21414,8.21414,0,0,0-1.75906-.15516c-2.10911,0-4.92212,1.24163-5.97731,2.84489ZM173.10344,64.47949a5.69574,5.69574,0,0,0-5.97731-5.53592c-3.96771,0-5.67637,3.05266-5.97732,5.53592ZM167.5278,79.94566c-7.38379,0-12.9595-5.12161-12.9595-13.13943,0-7.24181,5.174-13.08684,12.55783-13.08684,7.234,0,12.15607,5.58723,12.15607,13.76022v1.4481H161.24952c.40168,3.15535,2.86336,5.79371,6.98219,5.79371a10.15786,10.15786,0,0,0,6.47972-2.48319l2.813,4.24168c-2.41134,2.27549-6.22917,3.46575-9.99665,3.46575Zm-19.24929-.62079h-6.43068V60.08257h-4.018V54.34018h4.018V52.99592c0-5.32809,3.31543-8.68991,8.18843-8.68991a8.489,8.489,0,0,1,6.32989,2.32674l-2.41135,3.88a3.50681,3.50681,0,0,0-2.66312-1.03509c-1.75782,0-3.01317,1.19026-3.01317,3.51828v1.34426h4.92207v5.74239h-4.92207Zm-16.426,0H125.4218V60.08257h-4.0194V54.34018h4.0194V52.99592c0-5.32809,3.31541-8.68991,8.18843-8.68991a8.48418,8.48418,0,0,1,6.3286,2.32674l-2.41012,3.88a3.50683,3.50683,0,0,0-2.66312-1.03509c-1.75782,0-3.01318,1.19026-3.01318,3.51828v1.34426h4.92212v5.74239h-4.92212v19.2423Zm-14.43053,0h-6.38022V76.16952a11.21263,11.21263,0,0,1-8.53978,3.77613c-5.32385,0-7.83586-3.00012-7.83586-7.86259V54.34018h6.379v15.157c0,3.46574,1.75911,4.60345,4.4714,4.60345a7.07632,7.07632,0,0,0,5.52531-2.8449V54.34017H117.422v24.9847ZM71.87264,71.307a7.0348,7.0348,0,0,0,5.4762,2.79359c3.7171,0,6.17877-2.8975,6.17877-7.24181,0-4.34567-2.46168-7.29441-6.17877-7.29441a6.9786,6.9786,0,0,0-5.47621,2.8975V71.307Zm0,8.01788h-6.379V43.734h6.379V57.54807a9.2539,9.2539,0,0,1,7.48587-3.82868c6.17748,0,10.74961,4.96639,10.74961,13.13944,0,8.32821-4.62118,13.08683-10.74961,13.08683a9.33043,9.33043,0,0,1-7.48587-3.82745v3.20666Z"/></g><g id="Group-6"><g class="cls-4"><path id="Fill-4" class="cls-3" d="M47.00136,72.68049l-3.69521-1.83918a1.4583,1.4583,0,0,0-1.15329,0L31.57117,76.108a1.455,1.455,0,0,1-1.15194,0L19.83748,70.84131a1.45828,1.45828,0,0,0-1.15328,0L14.989,72.68049c-.31738.15841-.31738.416,0,.57308L30.41923,80.934a1.45553,1.45553,0,0,0,1.15194,0l15.43019-7.68046c.31738-.15706.31738-.41467,0-.57308"/></g></g><g id="Group-9"><g class="cls-5"><path id="Fill-7" class="cls-3" d="M47.00136,62.53223l-3.69521-1.83917a1.45872,1.45872,0,0,0-1.15329,0L31.57117,65.95984a1.46694,1.46694,0,0,1-1.15194,0L19.83748,60.69306a1.4587,1.4587,0,0,0-1.15328,0L14.989,62.53223c-.31738.15842-.31738.416,0,.5745l15.43024,7.67905a1.45553,1.45553,0,0,0,1.15194,0l15.43019-7.67905c.31738-.15848.31738-.41608,0-.5745"/></g></g><g id="Group-12"><g class="cls-6"><path id="Fill-10" class="cls-3" d="M14.98887,53.6031l15.43018,7.08965a1.58033,1.58033,0,0,0,1.15194,0L47.00123,53.6031c.31744-.14628.31744-.38408,0-.52907L31.571,45.98438a1.56676,1.56676,0,0,0-1.15194,0L14.98887,53.074c-.31744.145-.31744.38279,0,.52907"/></g></g></g></g></g></g></g></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 215 127"><defs><style>.cls-1{fill:#fff;}.cls-2{fill:transparent;}.cls-3{fill:#192534;}.cls-4{mask:url(#mask);}.cls-5{mask:url(#mask-2-2);}.cls-6{mask:url(#mask-3);}</style><mask id="mask" x="14.75095" y="70.72244" width="32.48851" height="10.3304" maskUnits="userSpaceOnUse"><g id="mask-2"><polygon id="path-1" class="cls-1" points="14.751 81.053 14.751 70.722 47.239 70.722 47.239 81.053 14.751 81.053"/></g></mask><mask id="mask-2-2" x="14.75095" y="60.57418" width="32.48851" height="10.3304" maskUnits="userSpaceOnUse"><g id="mask-4"><polygon id="path-3" class="cls-1" points="14.751 70.905 14.751 60.574 47.239 60.574 47.239 70.905 14.751 70.905"/></g></mask><mask id="mask-3" x="14.75079" y="45.87467" width="32.48853" height="14.92678" maskUnits="userSpaceOnUse"><g id="mask-6"><polygon id="path-5" class="cls-1" points="14.751 60.801 14.751 45.875 47.239 45.875 47.239 60.801 14.751 60.801"/></g></mask></defs><title>kubernetes.io-logos</title><rect class="cls-2" x="-3.55202" y="-3.16104" width="223.25536" height="134.51136"/><g id="Symbols"><g id="Mobile-Header"><g id="Group-4"><g id="Mobile-Logo"><g id="Group"><g id="Group-3"><path id="Fill-1" class="cls-3" d="M190.28379,79.32487h-6.37906V54.34018h6.37906v3.41436a10.33414,10.33414,0,0,1,7.73637-4.03515v6.41449a8.21414,8.21414,0,0,0-1.75906-.15516c-2.10911,0-4.92212,1.24163-5.97731,2.84489ZM173.10344,64.47949a5.69574,5.69574,0,0,0-5.97731-5.53592c-3.96771,0-5.67637,3.05266-5.97732,5.53592ZM167.5278,79.94566c-7.38379,0-12.9595-5.12161-12.9595-13.13943,0-7.24181,5.174-13.08684,12.55783-13.08684,7.234,0,12.15607,5.58723,12.15607,13.76022v1.4481H161.24952c.40168,3.15535,2.86336,5.79371,6.98219,5.79371a10.15786,10.15786,0,0,0,6.47972-2.48319l2.813,4.24168c-2.41134,2.27549-6.22917,3.46575-9.99665,3.46575Zm-19.24929-.62079h-6.43068V60.08257h-4.018V54.34018h4.018V52.99592c0-5.32809,3.31543-8.68991,8.18843-8.68991a8.489,8.489,0,0,1,6.32989,2.32674l-2.41135,3.88a3.50681,3.50681,0,0,0-2.66312-1.03509c-1.75782,0-3.01317,1.19026-3.01317,3.51828v1.34426h4.92207v5.74239h-4.92207Zm-16.426,0H125.4218V60.08257h-4.0194V54.34018h4.0194V52.99592c0-5.32809,3.31541-8.68991,8.18843-8.68991a8.48418,8.48418,0,0,1,6.3286,2.32674l-2.41012,3.88a3.50683,3.50683,0,0,0-2.66312-1.03509c-1.75782,0-3.01318,1.19026-3.01318,3.51828v1.34426h4.92212v5.74239h-4.92212v19.2423Zm-14.43053,0h-6.38022V76.16952a11.21263,11.21263,0,0,1-8.53978,3.77613c-5.32385,0-7.83586-3.00012-7.83586-7.86259V54.34018h6.379v15.157c0,3.46574,1.75911,4.60345,4.4714,4.60345a7.07632,7.07632,0,0,0,5.52531-2.8449V54.34017H117.422v24.9847ZM71.87264,71.307a7.0348,7.0348,0,0,0,5.4762,2.79359c3.7171,0,6.17877-2.8975,6.17877-7.24181,0-4.34567-2.46168-7.29441-6.17877-7.29441a6.9786,6.9786,0,0,0-5.47621,2.8975V71.307Zm0,8.01788h-6.379V43.734h6.379V57.54807a9.2539,9.2539,0,0,1,7.48587-3.82868c6.17748,0,10.74961,4.96639,10.74961,13.13944,0,8.32821-4.62118,13.08683-10.74961,13.08683a9.33043,9.33043,0,0,1-7.48587-3.82745v3.20666Z"/></g><g id="Group-6"><g class="cls-4"><path id="Fill-4" class="cls-3" d="M47.00136,72.68049l-3.69521-1.83918a1.4583,1.4583,0,0,0-1.15329,0L31.57117,76.108a1.455,1.455,0,0,1-1.15194,0L19.83748,70.84131a1.45828,1.45828,0,0,0-1.15328,0L14.989,72.68049c-.31738.15841-.31738.416,0,.57308L30.41923,80.934a1.45553,1.45553,0,0,0,1.15194,0l15.43019-7.68046c.31738-.15706.31738-.41467,0-.57308"/></g></g><g id="Group-9"><g class="cls-5"><path id="Fill-7" class="cls-3" d="M47.00136,62.53223l-3.69521-1.83917a1.45872,1.45872,0,0,0-1.15329,0L31.57117,65.95984a1.46694,1.46694,0,0,1-1.15194,0L19.83748,60.69306a1.4587,1.4587,0,0,0-1.15328,0L14.989,62.53223c-.31738.15842-.31738.416,0,.5745l15.43024,7.67905a1.45553,1.45553,0,0,0,1.15194,0l15.43019-7.67905c.31738-.15848.31738-.41608,0-.5745"/></g></g><g id="Group-12"><g class="cls-6"><path id="Fill-10" class="cls-3" d="M14.98887,53.6031l15.43018,7.08965a1.58033,1.58033,0,0,0,1.15194,0L47.00123,53.6031c.31744-.14628.31744-.38408,0-.52907L31.571,45.98438a1.56676,1.56676,0,0,0-1.15194,0L14.98887,53.074c-.31744.145-.31744.38279,0,.52907"/></g></g></g></g></g></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
|
Before Width: | Height: | Size: 6.7 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 9.0 KiB After Width: | Height: | Size: 9.0 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 215 127"><defs><style>.cls-1{fill:#fbfbfb;}.cls-2,.cls-3{fill-rule:evenodd;}.cls-2{fill:url(#linear-gradient);}.cls-3{fill:url(#linear-gradient-2);}</style><linearGradient id="linear-gradient" x1="-3137.65754" y1="1644.36414" x2="-3137.70622" y2="1644.36292" gradientTransform="matrix(2793, 0, 0, -441.00006, 8763675.71297, 725229.10048)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f5286e"/><stop offset="1" stop-color="#fa461e"/></linearGradient><linearGradient id="linear-gradient-2" x1="-3134.50784" y1="1645.52546" x2="-3134.55653" y2="1645.47965" gradientTransform="matrix(800, 0, 0, -776, 2507658.98376, 1276974.5)" xlink:href="#linear-gradient"/></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-3.55202" y="-3.16104" width="223.25536" height="134.51136"/><path class="cls-2" d="M73.12738,75.22779a11.43076,11.43076,0,0,0,7.99043-3.25709L77.915,69.25159a6.54848,6.54848,0,0,1-4.78767,2.18113,6.27512,6.27512,0,1,1,0-12.54865A6.54851,6.54851,0,0,1,77.915,61.0652l3.20276-2.71911A11.30858,11.30858,0,0,0,73.12738,55.089c-5.89573,0-10.92371,4.58875-10.92371,10.05486C62.20367,70.61115,67.23166,75.22779,73.12738,75.22779ZM87.2185,62.96274V60.24363H82.847V74.8885h4.37024V67.89326c0-2.74823,2.06429-4.504,5.29615-4.504V59.90555A5.81225,5.81225,0,0,0,87.21723,62.964ZM101.398,75.22779c4.57892,0,8.41035-3.51278,8.41035-7.67626s-3.83144-7.64715-8.41035-7.64715c-4.60807,0-8.46857,3.48368-8.46857,7.64715S96.79,75.22779,101.398,75.22779Zm0-3.48372a4.17862,4.17862,0,1,1,4.25-4.19254A4.2883,4.2883,0,0,1,101.398,71.74407Zm13.67233,3.14321h3.92121l2.90169-9.20544,2.87388,9.20544h3.91994l5.267-14.64366H129.675l-2.93333,9.12063-3.05221-9.12063H120.068l-3.05221,9.12063-2.93333-9.12063h-4.27915l5.267,14.64366Zm31.95657-19.7995v7.25216a6.48235,6.48235,0,0,0-5.20633-2.43556c-4.12993,0-7.12271,3.17228-7.12271,7.64715,0,4.50393,2.99273,7.67626,7.12144,7.67626a6.48139,6.48139,0,0,0,5.20758-2.43556V74.8885h4.37024V55.089h-4.37024v-.00121Zm-3.95028,16.65629a4.17829,4.17829,0,0,1,0-8.356,4.18457,4.18457,0,0,1,0,8.356ZM159.533,59.45116a1.52877,1.52877,0,0,1,1.466-1.6431,2.32868,2.32868,0,0,1,1.49515.48107l1.0486-2.52038a5.82958,5.82958,0,0,0-3.562-1.27474,4.36676,4.36676,0,0,0-4.63845,4.47492v1.27469h-2.125v3.34317h2.125V74.88728h4.18943V63.58679h3.352V60.24363h-3.352v-.79247h.00127Zm7.47558-1.21778a2.24007,2.24007,0,1,0,0-4.47609,2.24316,2.24316,0,1,0,0,4.47609Zm-2.21356,16.6539h4.369V60.24363h-4.37024V74.8885l.00126-.00122ZM176.46128,62.964V60.24362H172.091V74.88849h4.37024V67.89326c0-2.74823,2.06428-4.504,5.29615-4.504V59.90555a5.81228,5.81228,0,0,0-5.29615,3.05845Zm14.24029,8.61049a3.72844,3.72844,0,0,1-3.6809-2.66336h11.16279c0-5.523-2.8435-9.0067-7.69063-9.0067-4.52078,0-7.96131,3.20012-7.96131,7.6193,0,4.50393,3.59107,7.70411,8.1991,7.70411a9.76074,9.76074,0,0,0,6.31568-2.26594l-2.78279-2.69a5.79593,5.79593,0,0,1-3.562,1.30259Zm-.03038-8.01677a3.204,3.204,0,0,1,3.32165,2.37987h-6.91269a3.73543,3.73543,0,0,1,3.59228-2.37987h-.00124Z"/><path class="cls-3" d="M48.815,64.51747H41.02529v-7.5563H33.23554v-7.5563H48.815Zm3.89487,0H44.92016A11.51324,11.51324,0,0,1,33.23554,75.85073a11.33911,11.33911,0,1,1,0-22.66768v-7.5563c-10.75594,0-19.47437,8.45767-19.47437,18.89072S22.4796,83.407,33.23554,83.407,52.70991,74.94936,52.70991,64.5163Z"/></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 215 127"><defs><style>.cls-1{fill:transparent;}.cls-2,.cls-3{fill-rule:evenodd;}.cls-2{fill:url(#linear-gradient);}.cls-3{fill:url(#linear-gradient-2);}</style><linearGradient id="linear-gradient" x1="-3137.65754" y1="1644.36414" x2="-3137.70622" y2="1644.36292" gradientTransform="matrix(2793, 0, 0, -441.00006, 8763675.71297, 725229.10048)" gradientUnits="userSpaceOnUse"><stop offset="0" stop-color="#f5286e"/><stop offset="1" stop-color="#fa461e"/></linearGradient><linearGradient id="linear-gradient-2" x1="-3134.50784" y1="1645.52546" x2="-3134.55653" y2="1645.47965" gradientTransform="matrix(800, 0, 0, -776, 2507658.98376, 1276974.5)" xlink:href="#linear-gradient"/></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-3.55202" y="-3.16104" width="223.25536" height="134.51136"/><path class="cls-2" d="M73.12738,75.22779a11.43076,11.43076,0,0,0,7.99043-3.25709L77.915,69.25159a6.54848,6.54848,0,0,1-4.78767,2.18113,6.27512,6.27512,0,1,1,0-12.54865A6.54851,6.54851,0,0,1,77.915,61.0652l3.20276-2.71911A11.30858,11.30858,0,0,0,73.12738,55.089c-5.89573,0-10.92371,4.58875-10.92371,10.05486C62.20367,70.61115,67.23166,75.22779,73.12738,75.22779ZM87.2185,62.96274V60.24363H82.847V74.8885h4.37024V67.89326c0-2.74823,2.06429-4.504,5.29615-4.504V59.90555A5.81225,5.81225,0,0,0,87.21723,62.964ZM101.398,75.22779c4.57892,0,8.41035-3.51278,8.41035-7.67626s-3.83144-7.64715-8.41035-7.64715c-4.60807,0-8.46857,3.48368-8.46857,7.64715S96.79,75.22779,101.398,75.22779Zm0-3.48372a4.17862,4.17862,0,1,1,4.25-4.19254A4.2883,4.2883,0,0,1,101.398,71.74407Zm13.67233,3.14321h3.92121l2.90169-9.20544,2.87388,9.20544h3.91994l5.267-14.64366H129.675l-2.93333,9.12063-3.05221-9.12063H120.068l-3.05221,9.12063-2.93333-9.12063h-4.27915l5.267,14.64366Zm31.95657-19.7995v7.25216a6.48235,6.48235,0,0,0-5.20633-2.43556c-4.12993,0-7.12271,3.17228-7.12271,7.64715,0,4.50393,2.99273,7.67626,7.12144,7.67626a6.48139,6.48139,0,0,0,5.20758-2.43556V74.8885h4.37024V55.089h-4.37024v-.00121Zm-3.95028,16.65629a4.17829,4.17829,0,0,1,0-8.356,4.18457,4.18457,0,0,1,0,8.356ZM159.533,59.45116a1.52877,1.52877,0,0,1,1.466-1.6431,2.32868,2.32868,0,0,1,1.49515.48107l1.0486-2.52038a5.82958,5.82958,0,0,0-3.562-1.27474,4.36676,4.36676,0,0,0-4.63845,4.47492v1.27469h-2.125v3.34317h2.125V74.88728h4.18943V63.58679h3.352V60.24363h-3.352v-.79247h.00127Zm7.47558-1.21778a2.24007,2.24007,0,1,0,0-4.47609,2.24316,2.24316,0,1,0,0,4.47609Zm-2.21356,16.6539h4.369V60.24363h-4.37024V74.8885l.00126-.00122ZM176.46128,62.964V60.24362H172.091V74.88849h4.37024V67.89326c0-2.74823,2.06428-4.504,5.29615-4.504V59.90555a5.81228,5.81228,0,0,0-5.29615,3.05845Zm14.24029,8.61049a3.72844,3.72844,0,0,1-3.6809-2.66336h11.16279c0-5.523-2.8435-9.0067-7.69063-9.0067-4.52078,0-7.96131,3.20012-7.96131,7.6193,0,4.50393,3.59107,7.70411,8.1991,7.70411a9.76074,9.76074,0,0,0,6.31568-2.26594l-2.78279-2.69a5.79593,5.79593,0,0,1-3.562,1.30259Zm-.03038-8.01677a3.204,3.204,0,0,1,3.32165,2.37987h-6.91269a3.73543,3.73543,0,0,1,3.59228-2.37987h-.00124Z"/><path class="cls-3" d="M48.815,64.51747H41.02529v-7.5563H33.23554v-7.5563H48.815Zm3.89487,0H44.92016A11.51324,11.51324,0,0,1,33.23554,75.85073a11.33911,11.33911,0,1,1,0-22.66768v-7.5563c-10.75594,0-19.47437,8.45767-19.47437,18.89072S22.4796,83.407,33.23554,83.407,52.70991,74.94936,52.70991,64.5163Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 215 127"><defs><style>.cls-1{fill:none;}.cls-2{fill:#fbfbfb;}.cls-3{clip-path:url(#clip-path);}.cls-4{fill:#ee3248;fill-rule:evenodd;}</style><clipPath id="clip-path"><rect class="cls-1" x="4.70501" y="-8.81268" width="206.90403" height="145.3255"/></clipPath></defs><rect class="cls-2" x="-3.37342" y="-3.34411" width="223.25536" height="134.51135"/><g class="cls-3"><g class="cls-3"><path class="cls-4" d="M28.02166,50.76936l7.69058-.0617c6.9525.12305,7.75228,4.1837,4.61435,13.41275-2.64567,7.87531-6.76768,12.67414-14.58165,12.61279h-6.091ZM169.22325,61.044c4.55274-11.01316,10.52065-15.19686,22.76431-15.50454,10.9518-.24609,15.81224,4.79908,11.813,17.41187C199.49376,76.67151,191.67987,82.209,179.86693,82.209c-12.98175.06134-16.24263-7.87514-10.64368-21.165m8.429.73843c2.83006-7.01411,6.95215-11.87463,13.04345-11.93633,5.47555-.06125,6.46007,3.938,3.99905,12.36706-3.13794,10.82842-7.69068,15.5659-13.90466,15.44286-6.89106-.06135-6.768-6.82946-3.13784-15.87359m-15.07382-8.67536,2.09172-6.02932a34.76316,34.76316,0,0,0-10.95146-1.66134c-7.62924-.0616-13.35114,2.33806-15.6892,7.69066-3.69162,8.183,1.4766,10.70564,7.69084,13.59749,9.10583,4.245,3.876,11.56684-4.86069,10.82842-3.50688-.3077-6.58311-1.90724-9.65961-3.38384l-1.96859,6.15264A33.79646,33.79646,0,0,0,142.64393,82.209c9.0444-.55369,14.64308-4.184,16.91972-9.90595,2.584-6.52159-1.41525-10.52064-7.38324-12.42789-12.42831-3.99939-4.98338-15.75088,10.398-6.76811M95.57659,46.15492a19.153,19.153,0,0,1,2.215,3.62993L87.76306,81.47059H93.854l8.36766-26.45618,9.59791,26.45618h8.61375l-.36939-.98451,10.89012-34.33116h-6.15273l-7.99827,25.34837-9.22879-25.34837c-3.999,0-7.99836.06135-11.99767,0m-34.39259,0a14.395,14.395,0,0,1,2.21468,3.62993L53.43173,81.47059H79.826L81.05656,77.533H63.21437L67.152,65.16635H78.96492l1.23051-3.87627H68.3825L71.95081,49.9695H89.17822L90.347,46.15492c-9.72121,0-19.44208.06135-29.163,0m-42.26817,0a16.4482,16.4482,0,0,1,2.21468,3.62993L11.102,81.47059h8.61366l5.04517-.06135c14.766,0,21.77988-7.32179,24.73333-16.85828,4.245-13.5973-.92316-18.33469-13.47418-18.33469Z"/></g></g></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 215 127"><defs><style>.cls-1{fill:none;}.cls-2{fill:transparent;}.cls-3{clip-path:url(#clip-path);}.cls-4{fill:#ee3248;fill-rule:evenodd;}</style><clipPath id="clip-path"><rect class="cls-1" x="4.70501" y="-8.81268" width="206.90403" height="145.3255"/></clipPath></defs><rect class="cls-2" x="-3.37342" y="-3.34411" width="223.25536" height="134.51135"/><g class="cls-3"><g class="cls-3"><path class="cls-4" d="M28.02166,50.76936l7.69058-.0617c6.9525.12305,7.75228,4.1837,4.61435,13.41275-2.64567,7.87531-6.76768,12.67414-14.58165,12.61279h-6.091ZM169.22325,61.044c4.55274-11.01316,10.52065-15.19686,22.76431-15.50454,10.9518-.24609,15.81224,4.79908,11.813,17.41187C199.49376,76.67151,191.67987,82.209,179.86693,82.209c-12.98175.06134-16.24263-7.87514-10.64368-21.165m8.429.73843c2.83006-7.01411,6.95215-11.87463,13.04345-11.93633,5.47555-.06125,6.46007,3.938,3.99905,12.36706-3.13794,10.82842-7.69068,15.5659-13.90466,15.44286-6.89106-.06135-6.768-6.82946-3.13784-15.87359m-15.07382-8.67536,2.09172-6.02932a34.76316,34.76316,0,0,0-10.95146-1.66134c-7.62924-.0616-13.35114,2.33806-15.6892,7.69066-3.69162,8.183,1.4766,10.70564,7.69084,13.59749,9.10583,4.245,3.876,11.56684-4.86069,10.82842-3.50688-.3077-6.58311-1.90724-9.65961-3.38384l-1.96859,6.15264A33.79646,33.79646,0,0,0,142.64393,82.209c9.0444-.55369,14.64308-4.184,16.91972-9.90595,2.584-6.52159-1.41525-10.52064-7.38324-12.42789-12.42831-3.99939-4.98338-15.75088,10.398-6.76811M95.57659,46.15492a19.153,19.153,0,0,1,2.215,3.62993L87.76306,81.47059H93.854l8.36766-26.45618,9.59791,26.45618h8.61375l-.36939-.98451,10.89012-34.33116h-6.15273l-7.99827,25.34837-9.22879-25.34837c-3.999,0-7.99836.06135-11.99767,0m-34.39259,0a14.395,14.395,0,0,1,2.21468,3.62993L53.43173,81.47059H79.826L81.05656,77.533H63.21437L67.152,65.16635H78.96492l1.23051-3.87627H68.3825L71.95081,49.9695H89.17822L90.347,46.15492c-9.72121,0-19.44208.06135-29.163,0m-42.26817,0a16.4482,16.4482,0,0,1,2.21468,3.62993L11.102,81.47059h8.61366l5.04517-.06135c14.766,0,21.77988-7.32179,24.73333-16.85828,4.245-13.5973-.92316-18.33469-13.47418-18.33469Z"/></g></g></svg>
|
||||
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:#fbfbfb;}.cls-2{fill:#005da5;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-4.55738" y="-3.79362" width="223.25536" height="134.51136"/><path d="M70.73011,68.57377c-7.72723,0-10.07255-2.04907-10.07255-4.666V54.5512h5.061v8.83817c0,2.14782,2.24658,2.74033,5.25847,2.74033a39.0795,39.0795,0,0,0,4.71533-.1975V54.57589h5.061V68.006A79.45679,79.45679,0,0,1,70.73011,68.57377Z"/><polygon points="25.502 68.228 25.502 62.575 15.529 62.575 15.529 68.228 10.468 68.228 10.468 54.527 15.529 54.527 15.529 60.131 25.502 60.131 25.502 54.527 30.563 54.527 30.563 68.228 25.502 68.228"/><path d="M92.40584,57.26684h13.677V54.52651H91.34428c-3.9994,0-5.3819.71594-5.3819,2.7897V68.25283h5.061V62.5253H106.0581V60.08123H91.02333V58.1309C91.048,57.61246,91.34428,57.26684,92.40584,57.26684Z"/><path d="M116.501,57.26684c-1.08626,0-1.35782.34562-1.35782.83938v1.99969h15.03476v2.34533H115.14315v2.1972c0,.49375.29625.83938,1.35782.83938h13.67694v2.74032H115.4394c-3.9994,0-5.3819-.71594-5.3819-2.7897V57.29153c0-2.07377,1.3825-2.78971,5.3819-2.78971h14.73852v2.74033H116.501Z"/><path class="cls-2" d="M135.28825,65.66063c0-.69125.395-.93813,1.58-.93813h2.02439c1.16032,0,1.58.24688,1.58.93813V67.3147c0,.69126-.395.93813-1.58.93813h-2.02439c-1.16032,0-1.58-.24687-1.58-.93813Z"/><path d="M45.72154,59.785a50.47135,50.47135,0,0,0-8.1716.64187c-1.45657.22219-2.09845.79-2.09845,2.02439v3.45627c0,1.23438.64188,1.77751,2.09845,2.02438a50.47023,50.47023,0,0,0,8.1716.64188,66.931,66.931,0,0,0,9.85037-.61719V59.069c0-4.29564-1.65407-4.54252-7.25816-4.54252H37.05619v2.37H48.1903c2.09845,0,2.29595.56782,2.29595,1.82689V59.785Zm0,6.51753a24.08331,24.08331,0,0,1-4.1722-.32094c-.71595-.12344-1.03688-.395-1.03688-.98751V63.38937c0-.61719.32094-.88876,1.03688-.98751a24.08232,24.08232,0,0,1,4.1722-.32093h4.74V66.1297C49.49875,66.22845,47.62249,66.30251,45.72154,66.30251Z"/><path d="M152.17459,68.42564c-3.9994,0-7.1841-2.32063-7.1841-6.98659,0-4.22159,2.81438-6.9866,7.38159-6.9866a9.10468,9.10468,0,0,1,3.82659.74063l-.64188,1.13563a7.75929,7.75929,0,0,0-3.06127-.59251c-3.30814,0-5.1844,2.22189-5.1844,5.77691,0,3.82658,2.24657,5.62878,4.78941,5.62878a7.32732,7.32732,0,0,0,2.1972-.27157V61.76h-3.11065V60.62435h5.28316V67.7097A12.10491,12.10491,0,0,1,152.17459,68.42564Z"/><path d="M165.259,58.7481a4.6438,4.6438,0,0,0-1.35782-.17282,4.308,4.308,0,0,0-1.65407.27157v9.38129h-2.17251V58.15559a12.37618,12.37618,0,0,1,4.51783-.74063c.49375,0,1.03688.04938,1.16032.04938Z"/><path d="M172.44312,68.42564c-3.5797,0-5.20908-2.32063-5.20908-5.53s1.62938-5.50534,5.20908-5.50534,5.20908,2.32063,5.20908,5.50534S176.02283,68.42564,172.44312,68.42564Zm0-9.92442c-2.29594,0-3.06127,1.9997-3.06127,4.36971s.76531,4.3944,3.06127,4.3944,3.06127-2.02439,3.06127-4.3944S174.76376,58.50122,172.44312,58.50122Z"/><path d="M185.57694,68.42564c-3.16,0-4.81409-1.08625-4.81409-3.481V57.58778h2.14783v7.431c0,1.48126.86407,2.22189,2.691,2.22189A7.23093,7.23093,0,0,0,187.947,66.895V57.58778h2.14783V67.63564A12.37028,12.37028,0,0,1,185.57694,68.42564Z"/><path d="M197.89607,68.401a9.11009,9.11009,0,0,1-2.04907-.24688v4.32034h-2.12313V58.1309a10.93672,10.93672,0,0,1,4.09814-.74062c3.77721,0,5.851,2.09844,5.851,5.33252C203.64829,66.27782,201.377,68.401,197.89607,68.401Zm-.17281-9.94912a5.46342,5.46342,0,0,0-1.87626.27157v8.34441a5.51753,5.51753,0,0,0,1.58.22219c2.691,0,4.07346-1.62938,4.07346-4.46846C201.50046,60.15529,200.48827,58.45184,197.72326,58.45184Z"/></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:transparent;}.cls-2{fill:#005da5;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-4.55738" y="-3.79362" width="223.25536" height="134.51136"/><path d="M70.73011,68.57377c-7.72723,0-10.07255-2.04907-10.07255-4.666V54.5512h5.061v8.83817c0,2.14782,2.24658,2.74033,5.25847,2.74033a39.0795,39.0795,0,0,0,4.71533-.1975V54.57589h5.061V68.006A79.45679,79.45679,0,0,1,70.73011,68.57377Z"/><polygon points="25.502 68.228 25.502 62.575 15.529 62.575 15.529 68.228 10.468 68.228 10.468 54.527 15.529 54.527 15.529 60.131 25.502 60.131 25.502 54.527 30.563 54.527 30.563 68.228 25.502 68.228"/><path d="M92.40584,57.26684h13.677V54.52651H91.34428c-3.9994,0-5.3819.71594-5.3819,2.7897V68.25283h5.061V62.5253H106.0581V60.08123H91.02333V58.1309C91.048,57.61246,91.34428,57.26684,92.40584,57.26684Z"/><path d="M116.501,57.26684c-1.08626,0-1.35782.34562-1.35782.83938v1.99969h15.03476v2.34533H115.14315v2.1972c0,.49375.29625.83938,1.35782.83938h13.67694v2.74032H115.4394c-3.9994,0-5.3819-.71594-5.3819-2.7897V57.29153c0-2.07377,1.3825-2.78971,5.3819-2.78971h14.73852v2.74033H116.501Z"/><path class="cls-2" d="M135.28825,65.66063c0-.69125.395-.93813,1.58-.93813h2.02439c1.16032,0,1.58.24688,1.58.93813V67.3147c0,.69126-.395.93813-1.58.93813h-2.02439c-1.16032,0-1.58-.24687-1.58-.93813Z"/><path d="M45.72154,59.785a50.47135,50.47135,0,0,0-8.1716.64187c-1.45657.22219-2.09845.79-2.09845,2.02439v3.45627c0,1.23438.64188,1.77751,2.09845,2.02438a50.47023,50.47023,0,0,0,8.1716.64188,66.931,66.931,0,0,0,9.85037-.61719V59.069c0-4.29564-1.65407-4.54252-7.25816-4.54252H37.05619v2.37H48.1903c2.09845,0,2.29595.56782,2.29595,1.82689V59.785Zm0,6.51753a24.08331,24.08331,0,0,1-4.1722-.32094c-.71595-.12344-1.03688-.395-1.03688-.98751V63.38937c0-.61719.32094-.88876,1.03688-.98751a24.08232,24.08232,0,0,1,4.1722-.32093h4.74V66.1297C49.49875,66.22845,47.62249,66.30251,45.72154,66.30251Z"/><path d="M152.17459,68.42564c-3.9994,0-7.1841-2.32063-7.1841-6.98659,0-4.22159,2.81438-6.9866,7.38159-6.9866a9.10468,9.10468,0,0,1,3.82659.74063l-.64188,1.13563a7.75929,7.75929,0,0,0-3.06127-.59251c-3.30814,0-5.1844,2.22189-5.1844,5.77691,0,3.82658,2.24657,5.62878,4.78941,5.62878a7.32732,7.32732,0,0,0,2.1972-.27157V61.76h-3.11065V60.62435h5.28316V67.7097A12.10491,12.10491,0,0,1,152.17459,68.42564Z"/><path d="M165.259,58.7481a4.6438,4.6438,0,0,0-1.35782-.17282,4.308,4.308,0,0,0-1.65407.27157v9.38129h-2.17251V58.15559a12.37618,12.37618,0,0,1,4.51783-.74063c.49375,0,1.03688.04938,1.16032.04938Z"/><path d="M172.44312,68.42564c-3.5797,0-5.20908-2.32063-5.20908-5.53s1.62938-5.50534,5.20908-5.50534,5.20908,2.32063,5.20908,5.50534S176.02283,68.42564,172.44312,68.42564Zm0-9.92442c-2.29594,0-3.06127,1.9997-3.06127,4.36971s.76531,4.3944,3.06127,4.3944,3.06127-2.02439,3.06127-4.3944S174.76376,58.50122,172.44312,58.50122Z"/><path d="M185.57694,68.42564c-3.16,0-4.81409-1.08625-4.81409-3.481V57.58778h2.14783v7.431c0,1.48126.86407,2.22189,2.691,2.22189A7.23093,7.23093,0,0,0,187.947,66.895V57.58778h2.14783V67.63564A12.37028,12.37028,0,0,1,185.57694,68.42564Z"/><path d="M197.89607,68.401a9.11009,9.11009,0,0,1-2.04907-.24688v4.32034h-2.12313V58.1309a10.93672,10.93672,0,0,1,4.09814-.74062c3.77721,0,5.851,2.09844,5.851,5.33252C203.64829,66.27782,201.377,68.401,197.89607,68.401Zm-.17281-9.94912a5.46342,5.46342,0,0,0-1.87626.27157v8.34441a5.51753,5.51753,0,0,0,1.58.22219c2.691,0,4.07346-1.62938,4.07346-4.46846C201.50046,60.15529,200.48827,58.45184,197.72326,58.45184Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215.9892 128.40633"><defs><style>.cls-1{fill:#f9f9f9;}.cls-2{fill:#4c81c2;}</style></defs><title>ibm_featured_logo</title><rect class="cls-1" x="-5.9997" y="-8.99955" width="229.48853" height="143.9928"/><polygon class="cls-2" points="190.441 33.693 162.454 33.693 164.178 28.868 190.441 28.868 190.441 33.693"/><path class="cls-2" d="M115.83346,28.867l25.98433-.003,1.7014,4.83715c.01251-.00687-27.677.00593-27.677,0C115.84224,33.69422,115.82554,28.867,115.83346,28.867Z"/><path class="cls-2" d="M95.19668,28.86593A18.6894,18.6894,0,0,1,106.37358,33.7s-47.10052.00489-47.10052,0V28.86488Z"/><rect class="cls-2" x="22.31176" y="28.86593" width="32.72063" height="4.82558"/><path class="cls-2" d="M190.44115,42.74673h-31.194s1.70142-4.79994,1.691-4.80193h29.50305Z"/><polygon class="cls-2" points="146.734 42.753 115.832 42.753 115.832 37.944 145.041 37.944 146.734 42.753"/><path class="cls-2" d="M110.04127,37.94271a12.47,12.47,0,0,1,1.35553,4.80214H59.28193V37.94271Z"/><rect class="cls-2" x="22.31176" y="37.94271" width="32.72063" height="4.80214"/><polygon class="cls-2" points="156.056 51.823 157.768 46.998 181.191 47.005 181.191 51.812 156.056 51.823"/><polygon class="cls-2" points="148.237 46.997 149.944 51.823 125.046 51.823 125.046 46.997 148.237 46.997"/><path class="cls-2" d="M111.81,46.99627a15.748,15.748,0,0,1-.68923,4.82641H96.85137V46.99627Z"/><rect class="cls-2" x="31.43162" y="47.01973" width="14.06406" height="4.8019"/><rect class="cls-2" x="68.7486" y="46.99627" width="14.03976" height="4.82537"/><path class="cls-2" d="M138.87572,57.03292s.004,3.65225.001,3.65913H125.04558V55.89h26.35583l1.637,4.4773c.00773.00292,1.57841-4.48815,1.58153-4.47835h26.56223V60.692h-13.763c-.00124-.00687-.00771-3.65819-.00771-3.65819l-1.273,3.65819-25.99183-.00687Z"/><path class="cls-2" d="M68.7486,55.889h40.30365v-.00188a18.13723,18.13723,0,0,1-3.99812,4.80494s-36.30647.00668-36.30647,0Z"/><rect class="cls-2" x="31.43162" y="55.88794" width="14.06406" height="4.80316"/><rect class="cls-2" x="167.41912" y="64.94348" width="13.76302" height="4.80212"/><path class="cls-2" d="M138.87572,64.94348H125.04558V69.7456c-.00688-.0025,13.83411.00167,13.83411,0C138.87969,69.7431,138.89532,64.94348,138.87572,64.94348Z"/><path class="cls-2" d="M164.63927,64.94348c-.06255-.007-1.61218,4.79962-1.67723,4.80212l-19.60378.00835c-.01543-.00751-1.72371-4.81745-1.725-4.81047Z"/><path class="cls-2" d="M68.74672,64.94233H104.985a23.7047,23.7047,0,0,1,4.32076,4.80327c.06609-.0025-40.5581.00167-40.5581,0Z"/><path class="cls-2" d="M45.49359,69.74436v-4.802H31.45487V69.7431Z"/><rect class="cls-2" x="167.41912" y="73.99693" width="13.76198" height="4.80295"/><rect class="cls-2" x="125.04474" y="73.99693" width="13.83097" height="4.80212"/><path class="cls-2" d="M159.74351,78.8224c.00376-.02169,1.69745-4.82964,1.72373-4.82547H144.80219c-.029-.00209,1.70848,4.80378,1.70848,4.80378S159.7404,78.84241,159.74351,78.8224Z"/><path class="cls-2" d="M68.74766,78.79905c0,.01919-.00094-4.80212,0-4.803H82.9958s.01272,4.80462,0,4.80462C82.98224,78.80072,68.74766,78.79489,68.74766,78.79905Z"/><path class="cls-2" d="M111.30529,73.9961a13.94783,13.94783,0,0,1,.89542,4.825H97.10364v-4.825Z"/><rect class="cls-2" x="31.45487" y="73.9961" width="14.03872" height="4.80171"/><rect class="cls-2" x="167.41912" y="82.86525" width="23.0212" height="4.80421"/><rect class="cls-2" x="115.83139" y="82.86525" width="23.04432" height="4.80421"/><polygon class="cls-2" points="156.647 87.669 149.618 87.669 147.931 82.865 158.272 82.865 156.647 87.669"/><path class="cls-2" d="M22.3099,82.86525v4.80212H55.008c.01366.00751-.01469-4.79919,0-4.79919Z"/><path class="cls-2" d="M111.60237,82.86525c-.3442,1.58445-.65962,3.5158-1.81732,4.80421l-.43175-.00209H59.28005V82.86525Z"/><polygon class="cls-2" points="153.461 96.733 152.814 96.733 151.171 91.92 155.147 91.92 153.461 96.733"/><rect class="cls-2" x="167.41788" y="91.91953" width="23.02244" height="4.82547"/><path class="cls-2" d="M59.27307,96.73333V91.92745s47.24073.00585,47.37623.00585A17.945,17.945,0,0,1,94.43864,96.745l-35.15859-.00959"/><rect class="cls-2" x="115.83139" y="91.91953" width="23.04432" height="4.82547"/><path class="cls-2" d="M55.008,91.94079s-.01469,4.79253,0,4.79253c.01366,0-32.6885.0196-32.69809.00961-.00888-.00961.00875-4.81548,0-4.81548S54.9933,91.95664,55.008,91.94079Z"/></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215.9892 128.40633"><defs><style>.cls-1{fill:transparent;}.cls-2{fill:#4c81c2;}</style></defs><title>ibm_featured_logo</title><rect class="cls-1" x="-5.9997" y="-8.99955" width="229.48853" height="143.9928"/><polygon class="cls-2" points="190.441 33.693 162.454 33.693 164.178 28.868 190.441 28.868 190.441 33.693"/><path class="cls-2" d="M115.83346,28.867l25.98433-.003,1.7014,4.83715c.01251-.00687-27.677.00593-27.677,0C115.84224,33.69422,115.82554,28.867,115.83346,28.867Z"/><path class="cls-2" d="M95.19668,28.86593A18.6894,18.6894,0,0,1,106.37358,33.7s-47.10052.00489-47.10052,0V28.86488Z"/><rect class="cls-2" x="22.31176" y="28.86593" width="32.72063" height="4.82558"/><path class="cls-2" d="M190.44115,42.74673h-31.194s1.70142-4.79994,1.691-4.80193h29.50305Z"/><polygon class="cls-2" points="146.734 42.753 115.832 42.753 115.832 37.944 145.041 37.944 146.734 42.753"/><path class="cls-2" d="M110.04127,37.94271a12.47,12.47,0,0,1,1.35553,4.80214H59.28193V37.94271Z"/><rect class="cls-2" x="22.31176" y="37.94271" width="32.72063" height="4.80214"/><polygon class="cls-2" points="156.056 51.823 157.768 46.998 181.191 47.005 181.191 51.812 156.056 51.823"/><polygon class="cls-2" points="148.237 46.997 149.944 51.823 125.046 51.823 125.046 46.997 148.237 46.997"/><path class="cls-2" d="M111.81,46.99627a15.748,15.748,0,0,1-.68923,4.82641H96.85137V46.99627Z"/><rect class="cls-2" x="31.43162" y="47.01973" width="14.06406" height="4.8019"/><rect class="cls-2" x="68.7486" y="46.99627" width="14.03976" height="4.82537"/><path class="cls-2" d="M138.87572,57.03292s.004,3.65225.001,3.65913H125.04558V55.89h26.35583l1.637,4.4773c.00773.00292,1.57841-4.48815,1.58153-4.47835h26.56223V60.692h-13.763c-.00124-.00687-.00771-3.65819-.00771-3.65819l-1.273,3.65819-25.99183-.00687Z"/><path class="cls-2" d="M68.7486,55.889h40.30365v-.00188a18.13723,18.13723,0,0,1-3.99812,4.80494s-36.30647.00668-36.30647,0Z"/><rect class="cls-2" x="31.43162" y="55.88794" width="14.06406" height="4.80316"/><rect class="cls-2" x="167.41912" y="64.94348" width="13.76302" height="4.80212"/><path class="cls-2" d="M138.87572,64.94348H125.04558V69.7456c-.00688-.0025,13.83411.00167,13.83411,0C138.87969,69.7431,138.89532,64.94348,138.87572,64.94348Z"/><path class="cls-2" d="M164.63927,64.94348c-.06255-.007-1.61218,4.79962-1.67723,4.80212l-19.60378.00835c-.01543-.00751-1.72371-4.81745-1.725-4.81047Z"/><path class="cls-2" d="M68.74672,64.94233H104.985a23.7047,23.7047,0,0,1,4.32076,4.80327c.06609-.0025-40.5581.00167-40.5581,0Z"/><path class="cls-2" d="M45.49359,69.74436v-4.802H31.45487V69.7431Z"/><rect class="cls-2" x="167.41912" y="73.99693" width="13.76198" height="4.80295"/><rect class="cls-2" x="125.04474" y="73.99693" width="13.83097" height="4.80212"/><path class="cls-2" d="M159.74351,78.8224c.00376-.02169,1.69745-4.82964,1.72373-4.82547H144.80219c-.029-.00209,1.70848,4.80378,1.70848,4.80378S159.7404,78.84241,159.74351,78.8224Z"/><path class="cls-2" d="M68.74766,78.79905c0,.01919-.00094-4.80212,0-4.803H82.9958s.01272,4.80462,0,4.80462C82.98224,78.80072,68.74766,78.79489,68.74766,78.79905Z"/><path class="cls-2" d="M111.30529,73.9961a13.94783,13.94783,0,0,1,.89542,4.825H97.10364v-4.825Z"/><rect class="cls-2" x="31.45487" y="73.9961" width="14.03872" height="4.80171"/><rect class="cls-2" x="167.41912" y="82.86525" width="23.0212" height="4.80421"/><rect class="cls-2" x="115.83139" y="82.86525" width="23.04432" height="4.80421"/><polygon class="cls-2" points="156.647 87.669 149.618 87.669 147.931 82.865 158.272 82.865 156.647 87.669"/><path class="cls-2" d="M22.3099,82.86525v4.80212H55.008c.01366.00751-.01469-4.79919,0-4.79919Z"/><path class="cls-2" d="M111.60237,82.86525c-.3442,1.58445-.65962,3.5158-1.81732,4.80421l-.43175-.00209H59.28005V82.86525Z"/><polygon class="cls-2" points="153.461 96.733 152.814 96.733 151.171 91.92 155.147 91.92 153.461 96.733"/><rect class="cls-2" x="167.41788" y="91.91953" width="23.02244" height="4.82547"/><path class="cls-2" d="M59.27307,96.73333V91.92745s47.24073.00585,47.37623.00585A17.945,17.945,0,0,1,94.43864,96.745l-35.15859-.00959"/><rect class="cls-2" x="115.83139" y="91.91953" width="23.04432" height="4.82547"/><path class="cls-2" d="M55.008,91.94079s-.01469,4.79253,0,4.79253c.01366,0-32.6885.0196-32.69809.00961-.00888-.00961.00875-4.81548,0-4.81548S54.9933,91.95664,55.008,91.94079Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 59 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:#fbfbfb;}.cls-2{fill:#0191e9;}.cls-3{fill:#0091e9;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-4.04384" y="-3.09231" width="223.25536" height="134.51136"/><path class="cls-2" d="M45.52289,58.40931v.67992q0,13.93346-.00007,27.86692c0,1.38065-.53827,1.91475-1.93728,1.91529q-5.28807.002-10.57613-.00008c-1.38822-.00063-1.92493-.54092-1.925-1.93233q-.00046-24.54695-.00005-49.09388c0-1.353.57919-1.92554,1.94686-1.92565,3.80461-.00032,7.60928.01,11.41379-.00895a2.04535,2.04535,0,0,1,1.71751.81129Q54.03893,46.45059,61.924,56.17238q4.04849,4.99347,8.103,9.98208c.07192.08853.12491.2127.32189.21055V65.8111q0-13.98573.00015-27.97148c0-1.36549.55959-1.92,1.93681-1.92011q5.28806-.00056,10.57612,0c1.34222.00018,1.90831.58125,1.90846,1.96856q.00156,14.66543.00056,29.33085,0,9.85536-.00062,19.71075A2.263,2.263,0,0,1,84.52869,88.14a1.37319,1.37319,0,0,1-1.04378.69444,5.03028,5.03028,0,0,1-.6784.03606c-3.76971.002-7.53949-.01164-11.30906.01172a2.24873,2.24873,0,0,1-1.91838-.92957Q62.60826,79.30668,55.596,70.69411q-4.824-5.946-9.65083-11.88973A1.04432,1.04432,0,0,0,45.52289,58.40931Z"/><path class="cls-3" d="M123.01876,56.06019c-.2594-1.23634-.48657-2.48055-.78675-3.70693a1.60083,1.60083,0,0,1,1.699-2.14585c3.24478.05866,6.49131.01913,9.73714.02113A1.51454,1.51454,0,0,1,135.39865,51.95q.00269,17.59165,0,35.18331a1.50965,1.50965,0,0,1-1.72062,1.73444q-4.89491.01271-9.78984.00037a1.51127,1.51127,0,0,1-1.62212-2.05353c.25809-1.184.504-2.37063.75558-3.55756-.358.33974-.71292.66321-1.053,1.00145a19.61428,19.61428,0,0,1-5.08847,4.04243,16.514,16.514,0,0,1-8.88021,1.51593,18.6292,18.6292,0,0,1-7.80715-2.40237A19.19129,19.19129,0,0,1,91.61794,77.127a22.109,22.109,0,0,1-1.24153-9.90284A20.27607,20.27607,0,0,1,95.94859,54.708a18.01769,18.01769,0,0,1,10.63178-5.53131,17.6862,17.6862,0,0,1,7.30216.3216,15.14214,15.14214,0,0,1,7.36191,4.72185c.56309.63191,1.13169,1.25893,1.69777,1.8882Zm-9.77385,22.141a8.79066,8.79066,0,1,0,.14059-17.58031,8.79085,8.79085,0,1,0-.14059,17.58031Z"/><path class="cls-3" d="M162.37991,77.63555c.49774-1.75171.99389-3.48281,1.48143-5.21633q2.78715-9.91015,5.57042-19.82139a3.04284,3.04284,0,0,1,3.14933-2.36811q5.00009-.00879,10.00019-.001c1.19946.00084,1.72.6945,1.36948,1.8371q-3.41624,11.13649-6.839,22.271-1.962,6.38839-3.92252,12.77725a2.069,2.069,0,0,1-2.39972,1.75589q-8.42949.00264-16.859.0004a2.08773,2.08773,0,0,1-2.45568-1.82338q-5.3462-17.42612-10.69272-34.85212c-.04576-.14911-.10449-.29524-.13769-.447a1.19831,1.19831,0,0,1,1.16194-1.50906c3.56019-.01552,7.12059-.02529,10.68066-.00068a3.01084,3.01084,0,0,1,2.7849,2.42663q1.102,3.90333,2.20008,7.80776,2.35458,8.35854,4.70637,16.71786A.84887.84887,0,0,0,162.37991,77.63555Z"/></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:transparent;}.cls-2{fill:#0191e9;}.cls-3{fill:#0091e9;}</style></defs><title>kubernetes.io-logos</title><rect class="cls-1" x="-4.04384" y="-3.09231" width="223.25536" height="134.51136"/><path class="cls-2" d="M45.52289,58.40931v.67992q0,13.93346-.00007,27.86692c0,1.38065-.53827,1.91475-1.93728,1.91529q-5.28807.002-10.57613-.00008c-1.38822-.00063-1.92493-.54092-1.925-1.93233q-.00046-24.54695-.00005-49.09388c0-1.353.57919-1.92554,1.94686-1.92565,3.80461-.00032,7.60928.01,11.41379-.00895a2.04535,2.04535,0,0,1,1.71751.81129Q54.03893,46.45059,61.924,56.17238q4.04849,4.99347,8.103,9.98208c.07192.08853.12491.2127.32189.21055V65.8111q0-13.98573.00015-27.97148c0-1.36549.55959-1.92,1.93681-1.92011q5.28806-.00056,10.57612,0c1.34222.00018,1.90831.58125,1.90846,1.96856q.00156,14.66543.00056,29.33085,0,9.85536-.00062,19.71075A2.263,2.263,0,0,1,84.52869,88.14a1.37319,1.37319,0,0,1-1.04378.69444,5.03028,5.03028,0,0,1-.6784.03606c-3.76971.002-7.53949-.01164-11.30906.01172a2.24873,2.24873,0,0,1-1.91838-.92957Q62.60826,79.30668,55.596,70.69411q-4.824-5.946-9.65083-11.88973A1.04432,1.04432,0,0,0,45.52289,58.40931Z"/><path class="cls-3" d="M123.01876,56.06019c-.2594-1.23634-.48657-2.48055-.78675-3.70693a1.60083,1.60083,0,0,1,1.699-2.14585c3.24478.05866,6.49131.01913,9.73714.02113A1.51454,1.51454,0,0,1,135.39865,51.95q.00269,17.59165,0,35.18331a1.50965,1.50965,0,0,1-1.72062,1.73444q-4.89491.01271-9.78984.00037a1.51127,1.51127,0,0,1-1.62212-2.05353c.25809-1.184.504-2.37063.75558-3.55756-.358.33974-.71292.66321-1.053,1.00145a19.61428,19.61428,0,0,1-5.08847,4.04243,16.514,16.514,0,0,1-8.88021,1.51593,18.6292,18.6292,0,0,1-7.80715-2.40237A19.19129,19.19129,0,0,1,91.61794,77.127a22.109,22.109,0,0,1-1.24153-9.90284A20.27607,20.27607,0,0,1,95.94859,54.708a18.01769,18.01769,0,0,1,10.63178-5.53131,17.6862,17.6862,0,0,1,7.30216.3216,15.14214,15.14214,0,0,1,7.36191,4.72185c.56309.63191,1.13169,1.25893,1.69777,1.8882Zm-9.77385,22.141a8.79066,8.79066,0,1,0,.14059-17.58031,8.79085,8.79085,0,1,0-.14059,17.58031Z"/><path class="cls-3" d="M162.37991,77.63555c.49774-1.75171.99389-3.48281,1.48143-5.21633q2.78715-9.91015,5.57042-19.82139a3.04284,3.04284,0,0,1,3.14933-2.36811q5.00009-.00879,10.00019-.001c1.19946.00084,1.72.6945,1.36948,1.8371q-3.41624,11.13649-6.839,22.271-1.962,6.38839-3.92252,12.77725a2.069,2.069,0,0,1-2.39972,1.75589q-8.42949.00264-16.859.0004a2.08773,2.08773,0,0,1-2.45568-1.82338q-5.3462-17.42612-10.69272-34.85212c-.04576-.14911-.10449-.29524-.13769-.447a1.19831,1.19831,0,0,1,1.16194-1.50906c3.56019-.01552,7.12059-.02529,10.68066-.00068a3.01084,3.01084,0,0,1,2.7849,2.42663q1.102,3.90333,2.20008,7.80776,2.35458,8.35854,4.70637,16.71786A.84887.84887,0,0,0,162.37991,77.63555Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
@@ -1 +1 @@
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:#fbfbfb;}.cls-2{fill:#006cb7;}</style></defs><title>nokia</title><rect class="cls-1" x="-3.35417" y="-4.36563" width="223.25536" height="134.51136"/><polygon class="cls-2" points="23.535 77.585 14.624 77.585 14.624 48.305 30.04 48.305 47.717 70.171 47.717 48.305 56.626 48.305 56.626 77.585 41.529 77.585 23.535 55.356 23.535 77.585"/><path class="cls-2" d="M86.96953,70.53817c2.03268,0,2.74956-.11608,3.23784-.54371.45706-.39991.65794-.91707.65794-2.63643V58.4191c0-1.72-.20088-2.23418-.65794-2.63711-.48828-.42873-1.20515-.53939-3.23783-.53939H72.49669c-2.03268,0-2.74592.11066-3.233.53939-.45946.40293-.65671.91714-.65671,2.63711V67.358c0,1.71936.19725,2.23652.65671,2.63643.48711.42763,1.20035.54371,3.233.54371Zm12.2923-2.0014c0,4.06413-.74575,5.47257-1.97375,6.81726-1.89554,2.00436-4.6451,2.60576-9.9469,2.60576H72.12862c-5.30181,0-8.05253-.6014-9.94327-2.60576-1.2328-1.34469-1.97732-2.75313-1.97732-6.81726V57.2488c0-4.07017.74452-5.478,1.97732-6.82508,1.89074-2.00442,4.64146-2.60343,9.94327-2.60343H87.34118c5.3018,0,8.05135.599,9.9469,2.60343,1.228,1.34709,1.97375,2.75491,1.97375,6.82508Z"/><path class="cls-2" d="M127.93816,48.305h12.28866L123.64069,62.0021l18.7126,15.58666H129.19743L112.21318,62.31364Zm-15.725,29.28376h-9.30942V48.305h9.30942Z"/><rect class="cls-2" x="144.07442" y="48.305" width="9.31421" height="29.28376"/><path class="cls-2" d="M171.34711,66.124h11.57544L177.1324,55.52643Zm17.53874,11.46113L186.1315,72.486H168.11293l-2.72431,5.09914H155.10136L171.60454,48.305h11.57784l16.50553,29.28013Z"/></svg>
|
||||
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 215 127"><defs><style>.cls-1{fill:transparent;}.cls-2{fill:#006cb7;}</style></defs><title>nokia</title><rect class="cls-1" x="-3.35417" y="-4.36563" width="223.25536" height="134.51136"/><polygon class="cls-2" points="23.535 77.585 14.624 77.585 14.624 48.305 30.04 48.305 47.717 70.171 47.717 48.305 56.626 48.305 56.626 77.585 41.529 77.585 23.535 55.356 23.535 77.585"/><path class="cls-2" d="M86.96953,70.53817c2.03268,0,2.74956-.11608,3.23784-.54371.45706-.39991.65794-.91707.65794-2.63643V58.4191c0-1.72-.20088-2.23418-.65794-2.63711-.48828-.42873-1.20515-.53939-3.23783-.53939H72.49669c-2.03268,0-2.74592.11066-3.233.53939-.45946.40293-.65671.91714-.65671,2.63711V67.358c0,1.71936.19725,2.23652.65671,2.63643.48711.42763,1.20035.54371,3.233.54371Zm12.2923-2.0014c0,4.06413-.74575,5.47257-1.97375,6.81726-1.89554,2.00436-4.6451,2.60576-9.9469,2.60576H72.12862c-5.30181,0-8.05253-.6014-9.94327-2.60576-1.2328-1.34469-1.97732-2.75313-1.97732-6.81726V57.2488c0-4.07017.74452-5.478,1.97732-6.82508,1.89074-2.00442,4.64146-2.60343,9.94327-2.60343H87.34118c5.3018,0,8.05135.599,9.9469,2.60343,1.228,1.34709,1.97375,2.75491,1.97375,6.82508Z"/><path class="cls-2" d="M127.93816,48.305h12.28866L123.64069,62.0021l18.7126,15.58666H129.19743L112.21318,62.31364Zm-15.725,29.28376h-9.30942V48.305h9.30942Z"/><rect class="cls-2" x="144.07442" y="48.305" width="9.31421" height="29.28376"/><path class="cls-2" d="M171.34711,66.124h11.57544L177.1324,55.52643Zm17.53874,11.46113L186.1315,72.486H168.11293l-2.72431,5.09914H155.10136L171.60454,48.305h11.57784l16.50553,29.28013Z"/></svg>
|
||||
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |