Compare commits
675 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 30f0d4d542 | |||
| dc19b3109d | |||
| 6c315b73de | |||
| 090f7c9608 | |||
| ba0ba4930c | |||
| 37b086593d | |||
| dcc5633e03 | |||
| 38c9367671 | |||
| f326993ce4 | |||
| ed33fe51d4 | |||
| 6ac0388165 | |||
| 5ad1c725e0 | |||
| af1f6d5a2d | |||
| 6c3971d9f4 | |||
| cd91dac59e | |||
| e6c26bc7bb | |||
| f6bbed52a5 | |||
| 9a71927012 | |||
| c1d1b06685 | |||
| d79cb68bad | |||
| 3cfd1547b8 | |||
| 6da81db4a0 | |||
| 9243bd883d | |||
| 7fa8b63fa8 | |||
| df563da532 | |||
| d65ecfb3c9 | |||
| 6b47f60f90 | |||
| 40ff2f7e72 | |||
| 99013d17c8 | |||
| 63afe80021 | |||
| 43a94011fa | |||
| 10b8dc7856 | |||
| d920926f12 | |||
| d8e8fb9ffb | |||
| d48512e387 | |||
| 100daaa794 | |||
| b8aa4c6610 | |||
| 92e1be4711 | |||
| 7d3f209c87 | |||
| b7b1bc94e0 | |||
| b7ca839623 | |||
| 115ef91c5c | |||
| 9cce2b2f5a | |||
| 3d84ec254a | |||
| 13fd2d0f51 | |||
| 2ed1a1351c | |||
| dfbd0b16b4 | |||
| 438420ee21 | |||
| 9b15f8d77b | |||
| 57ad5d1cf6 | |||
| c8179efc20 | |||
| facd9bcce7 | |||
| 297ad056d3 | |||
| 696ca85aff | |||
| 800d359972 | |||
| 4cdf55fedc | |||
| 9ce54855d5 | |||
| 505387b463 | |||
| 8053e08125 | |||
| eaa52cf2fc | |||
| 12307b9501 | |||
| acbca1f251 | |||
| 55acc53d69 | |||
| a607d39b88 | |||
| 2d77413f91 | |||
| 40073e8abb | |||
| 8bd4011d41 | |||
| c4e4b3afcf | |||
| 29dab8af2b | |||
| 9f4214fc2c | |||
| fccaae6c37 | |||
| 4f526d0426 | |||
| 807ccaed78 | |||
| b6c33e695b | |||
| dccb59fddd | |||
| b6b25fc934 | |||
| e13b255f89 | |||
| 3bf7d6658a | |||
| 043a6941fe | |||
| 7764c02e78 | |||
| eddd78c28d | |||
| 809473a677 | |||
| 37af1f8318 | |||
| 221454da15 | |||
| d1b975da52 | |||
| 6854e84203 | |||
| 60466527e0 | |||
| 05b7a64d8f | |||
| cfadb36c12 | |||
| f6fec80790 | |||
| fce57824ce | |||
| e4af4e9898 | |||
| d57ed65fe8 | |||
| 7768c3bad3 | |||
| b6b96c82a5 | |||
| b206adba72 | |||
| 414e9722ae | |||
| 6792ba4aa2 | |||
| e353591f0e | |||
| c05b84a302 | |||
| 17daa9837f | |||
| 447049890d | |||
| 088c3c3ad4 | |||
| f08a13eae9 | |||
| 68dac29744 | |||
| 180db357d0 | |||
| 590e1beff9 | |||
| e22898914c | |||
| 8e992ec358 | |||
| 06a80c510c | |||
| 2ce643f56b | |||
| e85042f01d | |||
| 00a0eabf78 | |||
| 296750f249 | |||
| 7da7a46211 | |||
| d4107d0a08 | |||
| c224a7ab66 | |||
| b401010d3a | |||
| d4b42e9c7e | |||
| ef32f29d08 | |||
| 8f9bdf5bad | |||
| 538a80d428 | |||
| 75fc7284a8 | |||
| 36f168a1fe | |||
| 5f96e8a39a | |||
| b144d991a0 | |||
| 2fe806fc00 | |||
| 7dc36c1fff | |||
| d05fd38de8 | |||
| 4ba1d79c61 | |||
| 863d58bef3 | |||
| 763513ccce | |||
| f0cd49a007 | |||
| 7cdcff7813 | |||
| 7b9d2ff299 | |||
| 42c2e06e6a | |||
| 9c9d359fb3 | |||
| 4282f695c9 | |||
| 501d851eef | |||
| 069a2dabc6 | |||
| 0d19a29ef6 | |||
| 0a33b3e910 | |||
| 183b19d686 | |||
| 6f8c97f4d2 | |||
| f5c7bc79ff | |||
| bdf2b6ee49 | |||
| 29f5fa0990 | |||
| bf71f21a5b | |||
| 172a9add67 | |||
| c163956f8d | |||
| eb2a462951 | |||
| 7085715c47 | |||
| e889494348 | |||
| d239db84cf | |||
| 96074a1d64 | |||
| 09c97f4245 | |||
| fe780e07a5 | |||
| da2a9dad77 | |||
| ab51c87e77 | |||
| 3191d64cbb | |||
| be37f8f986 | |||
| b40a74416d | |||
| 4c6b8cc087 | |||
| 01b2be0b45 | |||
| c3af1df5c6 | |||
| 8d9c3938e4 | |||
| c5e149cc42 | |||
| 4e0ef3cddf | |||
| 7cc984d66b | |||
| ad8f009317 | |||
| db94608ba2 | |||
| 0386c39df1 | |||
| a0a51fb032 | |||
| 32b334711c | |||
| b8e1d8853a | |||
| a806d93a53 | |||
| f7648e7c27 | |||
| 7efaa0e1c2 | |||
| ba34326fa0 | |||
| b65d0a30c9 | |||
| d01672cd2d | |||
| 3ab1fa20bc | |||
| 664c27ae9f | |||
| b66a83d5a6 | |||
| 088cfc2c6f | |||
| 975b93efc1 | |||
| 7a41f3feb6 | |||
| 3ced6dbc2e | |||
| 4d9c7e1990 | |||
| bbc6835fc5 | |||
| 630cce61de | |||
| 7071b5e753 | |||
| 6ab05fbf1c | |||
| f3ae692dab | |||
| 1ec090cc7c | |||
| 1ee7bf7281 | |||
| e803967e16 | |||
| 8e3132bbe4 | |||
| 3175e9a9b6 | |||
| 9b5e645d92 | |||
| a804035cff | |||
| 617f0f7e08 | |||
| 47d2aa9bfd | |||
| fcdbb3a920 | |||
| 567c32ef78 | |||
| c96bb862d5 | |||
| c2d59f0c83 | |||
| 2dcf7a36bb | |||
| 60c6921576 | |||
| d0d6f4ca48 | |||
| 458548ace1 | |||
| fa668f520d | |||
| 1fdc1ebe55 | |||
| 7be7d6b519 | |||
| f1e7d0bda9 | |||
| df5fecc5c8 | |||
| 44dcf9b7dc | |||
| 5e581ccf3e | |||
| 99426f4c55 | |||
| bdaa82e79a | |||
| ee23982f7b | |||
| 4dce53334c | |||
| 6d30fc54da | |||
| 151f2968ba | |||
| a551d2673e | |||
| 8ae1fa3dcb | |||
| 3f01be882e | |||
| f7ad8644e9 | |||
| b3110014de | |||
| 582ef6dc4b | |||
| 04d12196a1 | |||
| 0e0440367c | |||
| dd77deabed | |||
| f251dd790e | |||
| c507a52d17 | |||
| 886771cf24 | |||
| 940e5e3a36 | |||
| 2958b30314 | |||
| 6b464aa960 | |||
| b1993b2135 | |||
| 491b701c91 | |||
| 68d5fe503f | |||
| 740e079849 | |||
| b71c9927e4 | |||
| e1fcf04cc1 | |||
| b3f34cd55b | |||
| 3abc2a301d | |||
| d8595aa4ea | |||
| 133af46f89 | |||
| ac31bb8270 | |||
| deef42e849 | |||
| 1c5e5248ad | |||
| 458f80b77a | |||
| 1cbcd2b596 | |||
| 61c6266815 | |||
| b1db56f615 | |||
| 979686122a | |||
| 56f8a68444 | |||
| 1bc38a5bab | |||
| 5e4a1ed081 | |||
| 172900f9aa | |||
| 3456093031 | |||
| b50ffef3fb | |||
| 1407f52478 | |||
| a238ed8ced | |||
| c235b99649 | |||
| 50471b3395 | |||
| 4d7aecf5de | |||
| adee25b768 | |||
| ec03295bf0 | |||
| a06df4d14a | |||
| 76f9a1b785 | |||
| 34cb50be94 | |||
| e06617a5a1 | |||
| 9443291066 | |||
| d360cee992 | |||
| 5f22fabf80 | |||
| f88f28bced | |||
| e610c89cc4 | |||
| c62eb411cc | |||
| 4cba37750b | |||
| 6a35189e21 | |||
| abe3171d0a | |||
| a380fec339 | |||
| 1abe7577cc | |||
| 40bf97accf | |||
| 7dcfaf0b87 | |||
| b86ebf1991 | |||
| 0c6b5c6c3f | |||
| e6ec869ca7 | |||
| f6bb5e6d44 | |||
| e1212ea63b | |||
| 8f30034cc2 | |||
| e6a7773fe4 | |||
| 742af56ffe | |||
| 94f02ff83d | |||
| af34e80f7e | |||
| f2e481abd8 | |||
| dbedb28b51 | |||
| 923aeb8bda | |||
| 5e5d91e3c2 | |||
| a15d5c1223 | |||
| 6dc694a161 | |||
| 0d7bcf5e6e | |||
| c3e5ad74c5 | |||
| 06416ac6e8 | |||
| 92c897998b | |||
| a562f77ce0 | |||
| 034a978c5f | |||
| 6b675d9b69 | |||
| a642102dc8 | |||
| a2fbc82bd0 | |||
| b9ca35076b | |||
| 1564ae52b7 | |||
| fd9ff4c4e0 | |||
| 04f2e50caa | |||
| 8ab16cb669 | |||
| 4bb9a3a6af | |||
| 2ef4477df3 | |||
| 764225a7a0 | |||
| 8b97c4265f | |||
| 6f83f5070a | |||
| dd595ae05b | |||
| 3c20c4da09 | |||
| eb57603fcb | |||
| 1cbd24e888 | |||
| 06104e35a3 | |||
| d30c4a7c78 | |||
| 11f3e0fec1 | |||
| 650d632519 | |||
| 3213006abc | |||
| 29b3f2b99a | |||
| b1cae4beb6 | |||
| 6d133c64d5 | |||
| ae56b5bf07 | |||
| 30023fb5b5 | |||
| 4508f114f9 | |||
| 474ae68f25 | |||
| eeb1367c64 | |||
| 180a9b6abc | |||
| fc9b83e95d | |||
| 58867752f5 | |||
| 83bfcd018f | |||
| fb7a756a77 | |||
| 741292ddb6 | |||
| 47ae58f3c4 | |||
| 5310464183 | |||
| da2ebff417 | |||
| fd3b6e66d8 | |||
| f5e5175247 | |||
| 8f6de25c98 | |||
| 69cfd63def | |||
| 0a76c67c5b | |||
| c295346b05 | |||
| b61c95f072 | |||
| a512e93e9d | |||
| a7192a9e9a | |||
| 8261341295 | |||
| c5a79de79c | |||
| b89155a351 | |||
| 142bf7dcc4 | |||
| 0b9dca5a36 | |||
| 4731f33d48 | |||
| 363db9d8af | |||
| 406fe2683b | |||
| 4806f01d8f | |||
| 65eacf1145 | |||
| b807813244 | |||
| dfb8b79b15 | |||
| dc053ed54f | |||
| 7022b43bc2 | |||
| 8e490b4251 | |||
| ce82d6301d | |||
| f8c25df156 | |||
| 632b2ba474 | |||
| e854c082ad | |||
| 17daf981f7 | |||
| cd69b5b1e3 | |||
| fe734530ba | |||
| 3c262fa8d8 | |||
| b8c5b72111 | |||
| 1a81cfd224 | |||
| 8140e9c2cf | |||
| 771a20326e | |||
| e71b14fa5c | |||
| 33da5e4fb1 | |||
| 3ed3018153 | |||
| 0ce865cc76 | |||
| 4e5e79f35f | |||
| 0fca22e659 | |||
| dec125aa53 | |||
| 2aea9f9424 | |||
| 3e48da5f8b | |||
| 183fc3d41c | |||
| e1eb525f01 | |||
| 1c634023f6 | |||
| 523bb2a1fd | |||
| a8009333b1 | |||
| 3ac0584953 | |||
| 40399ff636 | |||
| aaca71474e | |||
| 4e3f6ae0e3 | |||
| 3a5b4c74d3 | |||
| 886f15554f | |||
| 87f0e317ab | |||
| 5a24d6d681 | |||
| a334d932e1 | |||
| 07c4b9f6f8 | |||
| 2c9b093c37 | |||
| 5d0f273f34 | |||
| 2a597e3789 | |||
| ec8fd54d0f | |||
| fe9a0c1447 | |||
| e79c6662f5 | |||
| a35d5d3320 | |||
| f1ffbe9599 | |||
| 068818e1c6 | |||
| a5fe6ae18b | |||
| 01cea0c713 | |||
| 3137a4926a | |||
| 3808e4ccd7 | |||
| 49dea6f23b | |||
| 809c1b8ebe | |||
| 896c2ddd18 | |||
| 34ff10be2f | |||
| 0123149feb | |||
| eccf13d47b | |||
| c3b483c49f | |||
| 9197fb5822 | |||
| 58322206bd | |||
| 822d00df62 | |||
| 715ccb48e8 | |||
| 2f351db5bb | |||
| b51f5a2e2c | |||
| 10d678bfc8 | |||
| 3a993cdadc | |||
| 94aab012c0 | |||
| 380fc42886 | |||
| 601fd27c56 | |||
| 76938f5b68 | |||
| 1c04cedd41 | |||
| efbf64d09d | |||
| 50db7c5b29 | |||
| 667c1818dc | |||
| 554d6b7e9f | |||
| 25a3aac7b7 | |||
| a70480af00 | |||
| ed4770e3d8 | |||
| 34ab8024ec | |||
| d584b78bed | |||
| 7bd4d8ba44 | |||
| c4e1940170 | |||
| e93aaf7028 | |||
| 0b192ad9ec | |||
| 30b425b991 | |||
| aa1c435df3 | |||
| 8c1b7a6f5c | |||
| ee10fefec8 | |||
| c999e614f2 | |||
| 34f61c10e8 | |||
| 83d5b27667 | |||
| f2184920af | |||
| a045b3987d | |||
| af059b3b3c | |||
| 456a3ddcd6 | |||
| 29e432d419 | |||
| 24fc013242 | |||
| a21e061dcb | |||
| 5cf0e08b5b | |||
| d2266ed0eb | |||
| aa04248251 | |||
| 9dc31d6302 | |||
| 7b69821e5e | |||
| 8904a7f862 | |||
| c5ca457297 | |||
| 5095cf60df | |||
| 93c5edce64 | |||
| 13b7c5eb5c | |||
| a7b66a78a3 | |||
| f1ecafcdb1 | |||
| bd7607a066 | |||
| 91356cfbd2 | |||
| e82a2e2a58 | |||
| 60b5018738 | |||
| 72c93f9b52 | |||
| 960bb03b30 | |||
| 74d8327f6d | |||
| 58f20b10fa | |||
| d4c2da211e | |||
| 27039ac3b6 | |||
| 03b53f2aa9 | |||
| ab7d2c1b3c | |||
| 8dd5d7b8ad | |||
| abf9560874 | |||
| 1d1f2a8696 | |||
| 180091299b | |||
| b01dd765a9 | |||
| 4635787521 | |||
| 265a2fc996 | |||
| 77b4ffa696 | |||
| 041100bd2a | |||
| d0bdf37c1f | |||
| 05c1dfe76c | |||
| 0da9c85fd4 | |||
| 4dee823504 | |||
| 2638f4f087 | |||
| 37a51088f7 | |||
| ac44956a75 | |||
| 0d9e568d1b | |||
| ed63f9a8ce | |||
| 2e3758381d | |||
| f348728060 | |||
| a3a2233e6c | |||
| c222e9da33 | |||
| 4702554cb6 | |||
| 9b3f420bd9 | |||
| 76e1bfc55d | |||
| 0366fcc114 | |||
| 2ab877198b | |||
| 5df783425d | |||
| 2553649598 | |||
| 566f61f4b9 | |||
| 04d6793544 | |||
| cfaf34835c | |||
| 7c97c392ed | |||
| 36ebe59068 | |||
| 710a17c10d | |||
| 2fb161e033 | |||
| 38033ae6bf | |||
| 7bafe3557f | |||
| 7b42b5f9dd | |||
| e56a7296ca | |||
| 8a865cf1d3 | |||
| ff088c2256 | |||
| 4fa487f722 | |||
| 3512bc673b | |||
| 7267a33db7 | |||
| f4c8ba82c5 | |||
| 4c85470449 | |||
| c72ac0ab6b | |||
| 515f62be08 | |||
| ae45c11b3b | |||
| 17050a7fd2 | |||
| 1b33b95669 | |||
| 57260ac2d4 | |||
| 62b3570acd | |||
| f59b154f6f | |||
| 27a450f450 | |||
| 4a1f2c2b55 | |||
| 6ceec5095e | |||
| a9e63ea61d | |||
| 885864b9bc | |||
| 6673b5229c | |||
| 49169de6aa | |||
| 010b294cb2 | |||
| e42b16b6d2 | |||
| 6e1ec38daa | |||
| 93729a843a | |||
| 87401ac54b | |||
| 9f3ab47c8b | |||
| 32e912fc87 | |||
| 926d049a84 | |||
| 7a69c3d78c | |||
| 803ff36c78 | |||
| 03d1539a86 | |||
| e26872cb31 | |||
| baf1b7ef0d | |||
| a65374ff0c | |||
| 4d33d8073d | |||
| 13c366c09e | |||
| 4499f48856 | |||
| 2f1ae18bfc | |||
| 123b54b101 | |||
| fdd7240594 | |||
| 6620b309e5 | |||
| 51662f0c84 | |||
| 446606a43a | |||
| 34018d3695 | |||
| 5f71daa575 | |||
| b7e410bb57 | |||
| 2e3810e6ab | |||
| 2d98e5c1a5 | |||
| b3819339f3 | |||
| ada6673c7d | |||
| 97a5a10ae4 | |||
| 7db2dd4ddc | |||
| c125531513 | |||
| a4c608ae15 | |||
| 09af0b070f | |||
| bb6684e16f | |||
| c95524d506 | |||
| 839854fe7b | |||
| 3bac04bf7a | |||
| 5cc692a6fd | |||
| 83139a2acf | |||
| c9d032988e | |||
| 5dda4058f1 | |||
| 02d938a3d5 | |||
| 72d37e9a33 | |||
| 632c2de064 | |||
| 24d587a9c5 | |||
| 007caa5ef1 | |||
| 494f011dd2 | |||
| cff68f53af | |||
| 5253297f52 | |||
| 5424759ab1 | |||
| 4f390bc64f | |||
| ae0844f477 | |||
| 7815d386ef | |||
| b6149571ce | |||
| 7ce1b540c6 | |||
| ced286161c | |||
| 5823b154ab | |||
| bfe683c3fd | |||
| f7403f1d7e | |||
| 87eae080f7 | |||
| 1e3981a853 | |||
| 97d9607b69 | |||
| 27a185be87 | |||
| 70a2934d02 | |||
| 69cc2e60a2 | |||
| a3c2b257c7 | |||
| 631d1d1135 | |||
| e64c482469 | |||
| d268a3eaf4 | |||
| 592d61c55c | |||
| e3368b9733 | |||
| bf0e238e2b | |||
| 6193bb1cc9 | |||
| 1b4557f0d3 | |||
| a92dced983 | |||
| 011178a5da | |||
| 96fb6e2415 | |||
| 0ac53c2f97 | |||
| 2973296f28 | |||
| cef56d1d95 | |||
| 2d3f9f9682 | |||
| 17db79a875 | |||
| f9d4fd18e4 | |||
| 6e42b5f6ce | |||
| 087ba3c961 | |||
| bce5bae19c | |||
| 6cb33d02c4 | |||
| 214e749bf7 | |||
| 9891d65d3e | |||
| 248173bf81 | |||
| c4bbf9a8c7 | |||
| af5cc6a17f | |||
| a4f3a25f54 | |||
| db6506f640 | |||
| 2955de4f67 | |||
| bd9b561ad1 | |||
| fa9cb16339 | |||
| a32a2a59c2 | |||
| 2027ed39bb | |||
| bf3ccfd7af | |||
| 3b605dd247 | |||
| a631ff3cc9 | |||
| 90130cf93c | |||
| c317ac00d8 | |||
| d6ee95c6a1 | |||
| 147bb4cf02 | |||
| 6f1c745bb6 | |||
| e28cec48e9 | |||
| 095b4bcf54 | |||
| b3bfa8a906 | |||
| 2dcac11129 | |||
| c87772cd92 | |||
| 4f31ff9aec | |||
| 10c6bc9e65 | |||
| 105bf6e1f2 | |||
| c273184db4 | |||
| b5c01fe816 | |||
| 582d2079ea | |||
| e8727e886e |
@@ -0,0 +1,3 @@
|
||||
> NOTE: Please check the “Allow edits from maintainers” box below to allow
|
||||
> reviewers fix problems on your patch and speed up the review process.
|
||||
> Please delete this note before submitting the pull request.
|
||||
@@ -24,3 +24,4 @@ Session.vim
|
||||
tags
|
||||
|
||||
kubernetes.github.io.iml
|
||||
_redirects
|
||||
|
||||
+20
-2
@@ -7,15 +7,33 @@ install:
|
||||
- export PATH=$GOPATH/bin:$PATH
|
||||
- mkdir -p $HOME/gopath/src/k8s.io
|
||||
- mv $TRAVIS_BUILD_DIR $HOME/gopath/src/k8s.io/kubernetes.github.io
|
||||
|
||||
# (1) Fetch dependencies for us to run the tests in test/examples_test.go
|
||||
- go get -t -v k8s.io/kubernetes.github.io/test
|
||||
- git clone --depth=50 --branch=master https://github.com/kubernetes/md-check $HOME/gopath/src/k8s.io/md-check
|
||||
- go get -t -v k8s.io/md-check
|
||||
|
||||
# The dependencies are complicated for test/examples_test.go
|
||||
# k8s.io/kubernetes/pkg is a dependency, which in turn depends on apimachinery
|
||||
# but we also have apimachinery directly as one of our dependencies, which causes a conflict.
|
||||
# Additionally, we get symlinks when we clone the directory. The below steps do the following:
|
||||
|
||||
# (a) Replace the symlink with the actual dependencies from kubernetes/staging/src/
|
||||
# (b) copy all the vendored files to $GOPATH/src
|
||||
- rm $GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/apimachinery
|
||||
- rm $GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/apiserver
|
||||
- rm $GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/client-go
|
||||
- rm $GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/sample-apiserver
|
||||
- rm $GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/kube-aggregator
|
||||
- cp -r $GOPATH/src/k8s.io/kubernetes/vendor/* $GOPATH/src/
|
||||
- rm -rf $GOPATH/src/k8s.io/kubernetes/vendor/*
|
||||
- cp -r $GOPATH/src/k8s.io/kubernetes/staging/src/* $GOPATH/src/
|
||||
- cp -r $GOPATH/src/k8s.io/apimachinery/vendor/* $GOPATH/src/
|
||||
- rm -rf $GOPATH/src/k8s.io/apimachinery/vendor/*
|
||||
|
||||
# (2) Fetch md-check along with all its dependencies.
|
||||
- git clone --depth=50 --branch=master https://github.com/kubernetes/md-check $HOME/gopath/src/k8s.io/md-check
|
||||
- go get -t -v k8s.io/md-check
|
||||
|
||||
# (3) Fetch mungedocs
|
||||
- go get -v k8s.io/kubernetes/cmd/mungedocs
|
||||
|
||||
script:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.PHONY: all build build-preview help serve
|
||||
.PHONY: all build build-preview generate-redirects help serve
|
||||
|
||||
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)
|
||||
@@ -11,5 +11,8 @@ build: ## Build site with production settings and put deliverables in _site.
|
||||
build-preview: ## Build site with drafts and future posts enabled.
|
||||
jekyll build --drafts --future
|
||||
|
||||
generate-redirects: ## Generate a redirects file and copy it into the _site directory.
|
||||
mkdir -p _site && REDIRECTS_PATH=_site/_redirects ruby redirects.rb
|
||||
|
||||
serve: ## Boot the development server.
|
||||
jekyll serve
|
||||
|
||||
+53
-8
@@ -3,27 +3,72 @@ abstract: "Detailed explanations of Kubernetes system concepts and abstractions.
|
||||
toc:
|
||||
- docs/concepts/index.md
|
||||
|
||||
- title: Kubectl Command Line
|
||||
- title: Overview
|
||||
section:
|
||||
- docs/concepts/tools/kubectl/object-management-overview.md
|
||||
- docs/concepts/overview/what-is-kubernetes.md
|
||||
- docs/concepts/overview/components.md
|
||||
- title: Working with Kubernetes Objects
|
||||
section:
|
||||
- docs/concepts/overview/working-with-objects/kubernetes-objects.md
|
||||
- docs/concepts/overview/working-with-objects/labels.md
|
||||
- docs/concepts/overview/working-with-objects/annotations.md
|
||||
- docs/concepts/overview/kubernetes-api.md
|
||||
|
||||
- title: Kubernetes Objects
|
||||
- title: Containers
|
||||
section:
|
||||
- docs/concepts/abstractions/overview.md
|
||||
- docs/concepts/abstractions/pod.md
|
||||
- docs/concepts/containers/images.md
|
||||
- docs/concepts/containers/container-lifecycle-hooks.md
|
||||
|
||||
- title: Workloads
|
||||
section:
|
||||
- title: Pods
|
||||
section:
|
||||
- docs/concepts/workloads/pods/pod-overview.md
|
||||
- docs/concepts/workloads/pods/pod-lifecycle.md
|
||||
- docs/concepts/workloads/pods/init-containers.md
|
||||
- title: Controllers
|
||||
section:
|
||||
- docs/concepts/abstractions/controllers/statefulsets.md
|
||||
- docs/concepts/workloads/controllers/statefulset.md
|
||||
- docs/concepts/workloads/controllers/petset.md
|
||||
- docs/concepts/workloads/controllers/garbage-collection.md
|
||||
- title: Jobs
|
||||
section:
|
||||
- docs/concepts/jobs/run-to-completion-finite-workloads.md
|
||||
|
||||
- title: Object Metadata
|
||||
- title: Cluster Administration
|
||||
section:
|
||||
- docs/concepts/object-metadata/annotations.md
|
||||
- docs/concepts/cluster-administration/manage-deployment.md
|
||||
- docs/concepts/cluster-administration/networking.md
|
||||
- docs/concepts/cluster-administration/network-plugins.md
|
||||
- docs/concepts/cluster-administration/logging.md
|
||||
- docs/concepts/cluster-administration/audit.md
|
||||
- docs/concepts/cluster-administration/resource-usage-monitoring.md
|
||||
- docs/concepts/cluster-administration/out-of-resource.md
|
||||
- docs/concepts/cluster-administration/multiple-clusters.md
|
||||
- docs/concepts/cluster-administration/federation.md
|
||||
- docs/concepts/cluster-administration/federation-service-discovery.md
|
||||
- docs/concepts/cluster-administration/guaranteed-scheduling-critical-addon-pods.md
|
||||
- docs/concepts/cluster-administration/static-pod.md
|
||||
- docs/concepts/cluster-administration/sysctl-cluster.md
|
||||
- docs/concepts/cluster-administration/access-cluster.md
|
||||
- docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig.md
|
||||
|
||||
- title: Storage
|
||||
section:
|
||||
- docs/concepts/storage/volumes.md
|
||||
|
||||
- title: Services, Load Balancing, and Networking
|
||||
section:
|
||||
- docs/concepts/services-networking/dns-pod-service.md
|
||||
- docs/concepts/services-networking/connect-applications-service.md
|
||||
|
||||
- title: Configuration
|
||||
section:
|
||||
- docs/concepts/configuration/overview.md
|
||||
- docs/concepts/configuration/container-command-args.md
|
||||
- docs/concepts/configuration/manage-compute-resources-container.md
|
||||
|
||||
- title: Policies
|
||||
section:
|
||||
- docs/concepts/policy/container-capabilities.md
|
||||
- docs/concepts/policy/resource-quotas.md
|
||||
|
||||
+10
-24
@@ -3,17 +3,9 @@ abstract: "How to get started, and accomplish tasks, using Kubernetes."
|
||||
toc:
|
||||
- docs/user-guide/index.md
|
||||
|
||||
- title: Getting Started
|
||||
section:
|
||||
- docs/whatisk8s.md
|
||||
- docs/getting-started-guides/kubeadm.md
|
||||
- docs/getting-started-guides/kops.md
|
||||
- docs/getting-started-guides/kargo.md
|
||||
- docs/hellonode.md
|
||||
- docs/getting-started-guides/kubectl.md
|
||||
- docs/getting-started-guides/binary_release.md
|
||||
- title: Online Training Course
|
||||
path: https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615
|
||||
- docs/whatisk8s.md
|
||||
|
||||
- docs/user-guide/index.md
|
||||
|
||||
- title: Accessing the Cluster
|
||||
section:
|
||||
@@ -22,20 +14,15 @@ toc:
|
||||
- docs/user-guide/sharing-clusters.md
|
||||
- docs/user-guide/kubeconfig-file.md
|
||||
|
||||
- docs/user-guide/index.md
|
||||
|
||||
- docs/user-guide/ui.md
|
||||
|
||||
- title: Workload Deployment and Management
|
||||
section:
|
||||
- docs/user-guide/quick-start.md
|
||||
- docs/user-guide/deploying-applications.md
|
||||
- docs/user-guide/managing-deployments.md
|
||||
- docs/user-guide/replication-controller/operations.md
|
||||
- docs/user-guide/resizing-a-replication-controller.md
|
||||
- docs/user-guide/rolling-updates.md
|
||||
- docs/user-guide/update-demo/index.md
|
||||
- docs/user-guide/secrets/walkthrough.md
|
||||
- docs/user-guide/configmap/index.md
|
||||
- docs/user-guide/horizontal-pod-autoscaling/walkthrough.md
|
||||
- docs/user-guide/config-best-practices.md
|
||||
@@ -67,18 +54,12 @@ toc:
|
||||
- title: Containers and Pods
|
||||
section:
|
||||
- docs/user-guide/pods/multi-container.md
|
||||
- docs/user-guide/pods/init-container.md
|
||||
- docs/user-guide/pod-templates.md
|
||||
- docs/user-guide/containers.md
|
||||
- docs/user-guide/environment-guide/index.md
|
||||
- docs/user-guide/compute-resources.md
|
||||
- docs/user-guide/pod-states.md
|
||||
- docs/user-guide/liveness/index.md
|
||||
- docs/user-guide/container-environment.md
|
||||
- docs/user-guide/node-selection/index.md
|
||||
- docs/user-guide/downward-api/index.md
|
||||
- docs/user-guide/downward-api/volume/index.md
|
||||
- docs/user-guide/persistent-volumes/walkthrough.md
|
||||
- docs/user-guide/petset/bootstrapping/index.md
|
||||
|
||||
- title: Monitoring, Logging, and Debugging Containers
|
||||
@@ -89,7 +70,6 @@ toc:
|
||||
- docs/user-guide/logging/overview.md
|
||||
- docs/user-guide/logging/stackdriver.md
|
||||
- docs/user-guide/logging/elasticsearch.md
|
||||
- docs/user-guide/getting-into-containers.md
|
||||
- docs/user-guide/connecting-to-applications-proxy.md
|
||||
- docs/user-guide/connecting-to-applications-port-forward.md
|
||||
- title: Using Explorer to Examine the Runtime Environment
|
||||
@@ -119,11 +99,14 @@ toc:
|
||||
- title: Running Kubernetes on Custom Solutions
|
||||
section:
|
||||
- docs/getting-started-guides/scratch.md
|
||||
- docs/getting-started-guides/kubeadm.md
|
||||
- title: Custom Cloud Solutions
|
||||
section:
|
||||
- docs/getting-started-guides/coreos/index.md
|
||||
- docs/getting-started-guides/ubuntu/index.md
|
||||
- docs/getting-started-guides/rackspace.md
|
||||
- docs/getting-started-guides/kops.md
|
||||
- docs/getting-started-guides/kargo.md
|
||||
- title: On-Premise VMs
|
||||
section:
|
||||
- docs/getting-started-guides/coreos/index.md
|
||||
@@ -164,6 +147,7 @@ toc:
|
||||
- docs/getting-started-guides/ubuntu/troubleshooting.md
|
||||
- docs/getting-started-guides/ubuntu/decommissioning.md
|
||||
- docs/getting-started-guides/ubuntu/calico.md
|
||||
- docs/getting-started-guides/ubuntu/operational-considerations.md
|
||||
- docs/getting-started-guides/ubuntu/glossary.md
|
||||
- docs/getting-started-guides/ubuntu/local.md
|
||||
- docs/getting-started-guides/ubuntu/logging.md
|
||||
@@ -174,11 +158,13 @@ toc:
|
||||
- docs/admin/cluster-large.md
|
||||
- docs/admin/multiple-zones.md
|
||||
- docs/admin/high-availability/index.md
|
||||
- docs/getting-started-guides/binary_release.md
|
||||
|
||||
- title: Administering Clusters
|
||||
section:
|
||||
- docs/admin/index.md
|
||||
- docs/admin/cluster-management.md
|
||||
- docs/admin/upgrade-1-6.md
|
||||
- docs/admin/kubeadm.md
|
||||
- docs/admin/addons.md
|
||||
- docs/admin/audit.md
|
||||
@@ -229,5 +215,5 @@ toc:
|
||||
- title: Federation Components
|
||||
section:
|
||||
- docs/admin/federation-apiserver.md
|
||||
- title : federation-controller-mananger
|
||||
- title : federation-controller-manager
|
||||
path: /docs/admin/federation-controller-manager
|
||||
|
||||
+42
-6
@@ -3,28 +3,55 @@ abstract: "Step-by-step instructions for performing operations with Kubernetes."
|
||||
toc:
|
||||
- docs/tasks/index.md
|
||||
|
||||
- title: Using the kubectl Command-Line
|
||||
section:
|
||||
- docs/tasks/kubectl/install.md
|
||||
- docs/tasks/kubectl/list-all-running-container-images.md
|
||||
- docs/tasks/kubectl/get-shell-running-container.md
|
||||
|
||||
- title: Configuring Pods and Containers
|
||||
section:
|
||||
- docs/tasks/configure-pod-container/define-environment-variable-container.md
|
||||
- docs/tasks/configure-pod-container/define-command-argument-container.md
|
||||
- docs/tasks/configure-pod-container/assign-cpu-ram-container.md
|
||||
- docs/tasks/configure-pod-container/limit-range.md
|
||||
- docs/tasks/configure-pod-container/apply-resource-quota-limit.md
|
||||
- docs/tasks/configure-pod-container/configure-volume-storage.md
|
||||
- docs/tasks/configure-pod-container/configure-persistent-volume-storage.md
|
||||
- docs/tasks/configure-pod-container/environment-variable-expose-pod-information.md
|
||||
- docs/tasks/configure-pod-container/downward-api-volume-expose-pod-information.md
|
||||
- docs/tasks/configure-pod-container/distribute-credentials-secure.md
|
||||
- docs/tasks/configure-pod-container/pull-image-private-registry.md
|
||||
- docs/tasks/configure-pod-container/configure-liveness-readiness-probes.md
|
||||
- docs/tasks/configure-pod-container/communicate-containers-same-pod.md
|
||||
- docs/tasks/configure-pod-container/configure-pod-initialization.md
|
||||
- docs/tasks/configure-pod-container/attach-handler-lifecycle-event.md
|
||||
- docs/tasks/configure-pod-container/configure-pod-disruption-budget.md
|
||||
|
||||
- title: Running Applications
|
||||
section:
|
||||
- docs/tasks/run-application/rolling-update-replication-controller.md
|
||||
|
||||
- title: Running Jobs
|
||||
section:
|
||||
- docs/tasks/job/parallel-processing-expansion.md
|
||||
- docs/tasks/job/coarse-parallel-processing-work-queue/index.md
|
||||
- docs/tasks/job/fine-parallel-processing-work-queue/index.md
|
||||
|
||||
- title: Accessing Applications in a Cluster
|
||||
section:
|
||||
- docs/tasks/access-application-cluster/port-forward-access-application-cluster.md
|
||||
- docs/tasks/access-application-cluster/load-balance-access-application-cluster.md
|
||||
- docs/tasks/access-application-cluster/create-external-load-balancer.md
|
||||
- docs/tasks/access-application-cluster/configure-cloud-provider-firewall.md
|
||||
|
||||
- title: Debugging Applications in a Cluster
|
||||
- title: Monitoring, Logging, and Debugging
|
||||
section:
|
||||
- docs/tasks/debug-application-cluster/determine-reason-pod-failure.md
|
||||
- docs/tasks/debug-application-cluster/debug-init-containers.md
|
||||
- docs/tasks/debug-application-cluster/logging-stackdriver.md
|
||||
- docs/tasks/debug-application-cluster/monitor-node-health.md
|
||||
- docs/tasks/debug-application-cluster/logging-elasticsearch-kibana.md
|
||||
|
||||
- title: Accessing the Kubernetes API
|
||||
section:
|
||||
@@ -32,10 +59,24 @@ toc:
|
||||
|
||||
- title: Administering a Cluster
|
||||
section:
|
||||
- docs/tasks/administer-cluster/overview.md
|
||||
- docs/tasks/administer-cluster/assign-pods-nodes.md
|
||||
- docs/tasks/administer-cluster/dns-horizontal-autoscaling.md
|
||||
- docs/tasks/administer-cluster/safely-drain-node.md
|
||||
- docs/tasks/administer-cluster/change-pv-reclaim-policy.md
|
||||
- docs/tasks/administer-cluster/limit-storage-consumption.md
|
||||
- docs/tasks/administer-cluster/share-configuration.md
|
||||
|
||||
- title: Administering Federation
|
||||
section:
|
||||
- docs/tasks/administer-federation/configmap.md
|
||||
- docs/tasks/administer-federation/daemonset.md
|
||||
- docs/tasks/administer-federation/deployment.md
|
||||
- docs/tasks/administer-federation/events.md
|
||||
- docs/tasks/administer-federation/ingress.md
|
||||
- docs/tasks/administer-federation/namespaces.md
|
||||
- docs/tasks/administer-federation/replicaset.md
|
||||
- docs/tasks/administer-federation/secret.md
|
||||
|
||||
- title: Managing Stateful Applications
|
||||
section:
|
||||
@@ -44,8 +85,3 @@ toc:
|
||||
- docs/tasks/manage-stateful-set/deleting-a-statefulset.md
|
||||
- docs/tasks/manage-stateful-set/debugging-a-statefulset.md
|
||||
- docs/tasks/manage-stateful-set/delete-pods.md
|
||||
|
||||
- title: Troubleshooting
|
||||
section:
|
||||
- docs/tasks/troubleshoot/debug-init-containers.md
|
||||
- docs/tasks/administer-cluster/access-control-identity-management/
|
||||
|
||||
+16
-1
@@ -29,12 +29,21 @@ toc:
|
||||
section:
|
||||
- docs/tutorials/kubernetes-basics/update-intro.html
|
||||
- docs/tutorials/kubernetes-basics/update-interactive.html
|
||||
- title: Online Training Course
|
||||
path: https://www.udacity.com/course/scalable-microservices-with-kubernetes--ud615
|
||||
- docs/tutorials/stateless-application/hello-minikube.md
|
||||
- title: Object Management Using kubectl
|
||||
section:
|
||||
- docs/tutorials/object-management-kubectl/object-management.md
|
||||
- docs/tutorials/object-management-kubectl/imperative-object-management-command.md
|
||||
- docs/tutorials/object-management-kubectl/imperative-object-management-configuration.md
|
||||
- docs/tutorials/object-management-kubectl/declarative-object-management-configuration.md
|
||||
- title: Stateless Applications
|
||||
section:
|
||||
- docs/tutorials/stateless-application/hello-minikube.md
|
||||
- docs/tutorials/stateless-application/run-stateless-application-deployment.md
|
||||
- docs/tutorials/stateless-application/expose-external-ip-address-service.md
|
||||
- docs/tutorials/stateless-application/expose-external-ip-address.md
|
||||
- docs/tutorials/stateless-application/run-stateless-ap-replication-controller.md
|
||||
- title: Stateful Applications
|
||||
section:
|
||||
- docs/tutorials/stateful-application/basic-stateful-set.md
|
||||
@@ -44,6 +53,12 @@ toc:
|
||||
- title: Connecting Applications
|
||||
section:
|
||||
- docs/tutorials/connecting-apps/connecting-frontend-backend.md
|
||||
- title: Clusters
|
||||
section:
|
||||
- docs/tutorials/clusters/apparmor.md
|
||||
- title: Services
|
||||
section:
|
||||
- docs/tutorials/services/source-ip.md
|
||||
- title: Federated Cluster Administration
|
||||
section:
|
||||
- docs/tutorials/federation/set-up-cluster-federation-kubefed.md
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
***NOTE: This feature is beta in Kubernetes 1.5.***
|
||||
+1
-1
@@ -14,7 +14,7 @@
|
||||
{% if ghlink %}<a href="{{ghlink}}" download="{{include.file}}">{% endif %}
|
||||
<code>{{include.file}}</code>
|
||||
{% if ghlink %}</a>{% endif %}
|
||||
<img src="/images/copycode.svg" style="max-height:24px" onClick="copyCode('{{include.file | handleize}}')" title="Copy {{include.file}} to clipboard">
|
||||
<img src="/images/copycode.svg" style="max-height:24px" onclick="copyCode('{{include.file | handleize}}')" title="Copy {{include.file}} to clipboard">
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
+32
-32
@@ -1,34 +1,34 @@
|
||||
<footer>
|
||||
<main class="light-text">
|
||||
<nav>
|
||||
<a href="/docs/hellonode/">Get Started</a>
|
||||
<a href="/docs/">Documentation</a>
|
||||
<a href="http://blog.kubernetes.io/">Blog</a>
|
||||
<a href="/partners/">Partners</a>
|
||||
<a href="/community/">Community</a>
|
||||
<a href="/case-studies/">Case Studies</a>
|
||||
</nav>
|
||||
<div class="social">
|
||||
<div>
|
||||
<a href="https://twitter.com/kubernetesio" class="twitter"><span>twitter</span></a>
|
||||
<a href="https://github.com/kubernetes/kubernetes" class="github"><span>Github</span></a>
|
||||
<a href="http://slack.k8s.io/" class="slack"><span>Slack</span></a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://stackoverflow.com/questions/tagged/kubernetes" class="stack-overflow"><span>Stack Overflow</span></a>
|
||||
<a href="https://groups.google.com/forum/#!forum/kubernetes-users" class="mailing-list"><span>Mailing List</span></a>
|
||||
<a href="https://calendar.google.com/calendar/embed?src=nt2tcnbtbied3l6gi2h29slvc0%40group.calendar.google.com" class="calendar"><span>Events Calendar</span></a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="//get.k8s.io" class="button">Download K8s</a>
|
||||
<a href="https://github.com/kubernetes/kubernetes" class="button">Contribute to the K8s codebase</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="miceType" class="center">
|
||||
© {{ 'now' | date: "%Y" }} The Kubernetes Authors | Documentation Distributed under <a href="https://github.com/kubernetes/kubernetes.github.io/blob/master/LICENSE" class="light-text">CC BY 4.0</a>
|
||||
</div>
|
||||
<div id="miceType" class="center">
|
||||
Copyright © {{ 'now' | date: "%Y" }} The Linux Foundation®. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page: <a href="https://www.linuxfoundation.org/trademark-usage" class="light-text">https://www.linuxfoundation.org/trademark-usage</a>
|
||||
</div>
|
||||
</main>
|
||||
<main class="light-text">
|
||||
<nav>
|
||||
<a href="/docs/hellonode/">Get Started</a>
|
||||
<a href="/docs/">Documentation</a>
|
||||
<a href="http://blog.kubernetes.io/">Blog</a>
|
||||
<a href="/partners/">Partners</a>
|
||||
<a href="/community/">Community</a>
|
||||
<a href="/case-studies/">Case Studies</a>
|
||||
</nav>
|
||||
<div class="social">
|
||||
<div>
|
||||
<a href="https://twitter.com/kubernetesio" class="twitter"><span>twitter</span></a>
|
||||
<a href="https://github.com/kubernetes/kubernetes" class="github"><span>Github</span></a>
|
||||
<a href="http://slack.k8s.io/" class="slack"><span>Slack</span></a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://stackoverflow.com/questions/tagged/kubernetes" class="stack-overflow"><span>Stack Overflow</span></a>
|
||||
<a href="https://groups.google.com/forum/#!forum/kubernetes-users" class="mailing-list"><span>Mailing List</span></a>
|
||||
<a href="https://calendar.google.com/calendar/embed?src=nt2tcnbtbied3l6gi2h29slvc0%40group.calendar.google.com" class="calendar"><span>Events Calendar</span></a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="//get.k8s.io" class="button">Download K8s</a>
|
||||
<a href="https://github.com/kubernetes/kubernetes" class="button">Contribute to the K8s codebase</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="miceType" class="center">
|
||||
© {{ 'now' | date: "%Y" }} The Kubernetes Authors | Documentation Distributed under <a href="https://github.com/kubernetes/kubernetes.github.io/blob/master/LICENSE" class="light-text">CC BY 4.0</a>
|
||||
</div>
|
||||
<div id="miceType" class="center">
|
||||
Copyright © {{ 'now' | date: "%Y" }} The Linux Foundation®. All rights reserved. The Linux Foundation has registered trademarks and uses trademarks. For a list of trademarks of The Linux Foundation, please see our Trademark Usage page: <a href="https://www.linuxfoundation.org/trademark-usage" class="light-text">https://www.linuxfoundation.org/trademark-usage</a>
|
||||
</div>
|
||||
</main>
|
||||
</footer>
|
||||
|
||||
+108
-2
@@ -279,14 +279,120 @@
|
||||
logo: 'harbur',
|
||||
link: 'https://harbur.io/',
|
||||
blurb: 'Based in Barcelona, Harbur is a consulting firm that helps companies deploy self-healing solutions empowered by Container technologies'
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
name: 'Endocode',
|
||||
logo: 'endocode',
|
||||
link: 'https://endocode.com/kubernetes/',
|
||||
blurb: 'Endocode practices and teaches the open source way. Kernel to cluster - Dev to Ops. We offer Kubernetes trainings, services and support.'
|
||||
}
|
||||
},
|
||||
{
|
||||
type: 0,
|
||||
name: 'Spotinst',
|
||||
logo: 'spotinst',
|
||||
link: 'http://blog.spotinst.com/2016/08/04/elastigroup-kubernetes-minions-steroids/',
|
||||
blurb: 'Spotinst uses a prediction algorithm in the Amazon EC2 Spot allowing k8s clusters to increase performance and lower the infrastructure costs'
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
name: 'inwinSTACK',
|
||||
logo: 'inwinstack',
|
||||
link: 'http://www.inwinstack.com/index.php/en/solutions-en/',
|
||||
blurb: 'Our container service leverages OpenStack-based infrastructure and its container orchestration engine Magnum to manage Kubernetes clusters.'
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
name: 'Semantix',
|
||||
logo: 'semantix',
|
||||
link: 'http://www.semantix.com.br/',
|
||||
blurb: 'Semantix is a company that works with data analytics and distributed systems. Kubernetes is used to orchestrate services for our customers.'
|
||||
},
|
||||
{
|
||||
type: 0,
|
||||
name: 'ASM Technologies Limited',
|
||||
logo: 'asm',
|
||||
link: 'http://www.asmtech.com/',
|
||||
blurb: 'Our technology supply chain portfolio enables your software products to be accessible, viable and available more effectively.'
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
name: 'InfraCloud Technologies',
|
||||
logo: 'infracloud',
|
||||
link: 'http://blog.infracloud.io/state-of-kubernetes/',
|
||||
blurb: 'InfraCloud Technologies is software consultancy which provides services in Containers, Cloud and DevOps.'
|
||||
},
|
||||
{
|
||||
type: 0,
|
||||
name: 'SignalFx',
|
||||
logo: 'signalfx',
|
||||
link: 'https://github.com/signalfx/integrations/tree/master/kubernetes',
|
||||
blurb: 'Gain real-time visibility across metrics & the most intelligent alerts for todays architectures, including deep integration with Kubernetes'
|
||||
},
|
||||
{
|
||||
type: 0,
|
||||
name: 'NATS',
|
||||
logo: 'nats',
|
||||
link: 'https://github.com/pires/kubernetes-nats-cluster',
|
||||
blurb: 'NATS is a simple, secure, and scalable cloud native messaging system.'
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
name: 'RX-M',
|
||||
logo: 'rxm',
|
||||
link: 'http://rx-m.com/training/kubernetes-training/',
|
||||
blurb: 'Market neutral Kubernetes Dev, DevOps and Production training and consulting services'
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
name: 'Emerging Technology Advisors',
|
||||
logo: 'eta',
|
||||
link: 'https://www.emergingtechnologyadvisors.com/services/kubernetes.html',
|
||||
blurb: 'ETA helps companies architect, implement, and manage scalable applications using Kubernetes on on public or private cloud.'
|
||||
},
|
||||
{
|
||||
type: 0,
|
||||
name: 'CloudPlex.io',
|
||||
logo: 'cloudplex',
|
||||
link: 'http://www.cloudplex.io',
|
||||
blurb: 'CloudPlex enables operations teams to visually deploy, orchestrate, manage, and monitor infrastructure, applications, and services in public or private cloud.'
|
||||
},
|
||||
{
|
||||
type: 1,
|
||||
name: 'Kumina',
|
||||
logo: 'kumina',
|
||||
link: 'https://www.kumina.nl/managed_kubernetes',
|
||||
blurb: 'Kumina creates Kubernetes solutions on your choice of infrastructure with around-the-clock management and unlimited support.'
|
||||
},
|
||||
{
|
||||
type: 0,
|
||||
name: 'CA Technologies',
|
||||
logo: 'ca',
|
||||
link: 'https://www.ca.com/us/products/application-deployment.html',
|
||||
blurb: 'The RA CDE Kubernetes plugin enables an automated process for pushing changes to production by applying standard Kubernetes YAML files'
|
||||
},
|
||||
{
|
||||
type: 0,
|
||||
name: 'CoScale',
|
||||
logo: 'coscale',
|
||||
link: 'http://www.coscale.com/blog/how-to-monitor-your-kubernetes-cluster',
|
||||
blurb: 'Full stack monitoring of containers and microservices orchestrated by Kubernetes. Powered by anomaly detection to find problems faster.'
|
||||
},
|
||||
{
|
||||
type: 0,
|
||||
name: 'Supergiant.io',
|
||||
logo: 'supergiant',
|
||||
link: 'https://supergiant.io/blog/supergiant-packing-algorithm-unique-save-money',
|
||||
blurb: 'Supergiant autoscales hardware for Kubernetes. Open-source, it makes HA, distributed, stateful apps easy to deploy, manage, and scale.'
|
||||
},
|
||||
{
|
||||
type: 0,
|
||||
name: 'Avi Networks',
|
||||
logo: 'avinetworks',
|
||||
link: 'https://kb.avinetworks.com/avi-vantage-openshift-installation-guide/',
|
||||
blurb: 'Avis elastic application services fabric provides scalable, feature rich & integrated L4-7 networking for K8S environments.'
|
||||
}
|
||||
|
||||
]
|
||||
|
||||
var isvContainer = document.getElementById('isvContainer')
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
|
||||
|
||||
<table style="background-color:#eeeeee">
|
||||
<tr>
|
||||
<td>
|
||||
<p><b>NOTICE</b></p>
|
||||
<p>As of March 14, 2017, the Kubernetes SIG-Docs-Maintainers group have begun migration of the User Guide content as announced previously to the <a href="https://github.com/kubernetes/community/tree/master/sig-docs">SIG Docs community</a> through the <a href="https://groups.google.com/forum/#!forum/kubernetes-sig-docs">kubernetes-sig-docs</a> group and <a href="https://kubernetes.slack.com/messages/sig-docs/">kubernetes.slack.com #sig-docs</a> channel.</p>
|
||||
<p>The user guides within this section are being refactored into topics within Tutorials, Tasks, and Concepts. Anything that has been moved will have a notice placed in its previous location as well as a link to its new location. The reorganization implements the table of contents (ToC) outlined in the <a href="https://docs.google.com/a/google.com/document/d/18hRCIorVarExB2eBVHTUR6eEJ2VVk5xq1iBmkQv8O6I/edit?usp=sharing">kubernetes-docs-toc</a> document and should improve the documentation's findability and readability for a wider range of audiences.</p>
|
||||
<p>For any questions, please contact: <a href="mailto:kubernetes-sig-docs@googlegroups.com">kubernetes-sig-docs@googlegroups.com</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -4275,10 +4275,10 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">host</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the "host" part of the URI as defined in the RFC: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to the<br>
|
||||
IP in the Spec of the parent Ingress.<br>
|
||||
IP in the Spec of the parent Ingress.<br>
|
||||
2. The <code>:</code> delimiter is not respected because ports are not allowed.<br>
|
||||
Currently the port of an Ingress is implicitly :80 for http and<br>
|
||||
:443 for https.<br>
|
||||
Currently the port of an Ingress is implicitly :80 for http and<br>
|
||||
:443 for https.<br>
|
||||
Both these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
|
||||
@@ -4393,10 +4393,10 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">host</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the "host" part of the URI as defined in the RFC: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to the<br>
|
||||
IP in the Spec of the parent Ingress.<br>
|
||||
IP in the Spec of the parent Ingress.<br>
|
||||
2. The <code>:</code> delimiter is not respected because ports are not allowed.<br>
|
||||
Currently the port of an Ingress is implicitly :80 for http and<br>
|
||||
:443 for https.<br>
|
||||
Currently the port of an Ingress is implicitly :80 for http and<br>
|
||||
:443 for https.<br>
|
||||
Both these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
|
||||
@@ -3453,7 +3453,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">nodeSelector</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection/README">http://kubernetes.io/docs/user-guide/node-selection/README</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection">http://kubernetes.io/docs/user-guide/node-selection</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">object</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
@@ -4613,10 +4613,10 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">host</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the "host" part of the URI as defined in the RFC: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to the<br>
|
||||
IP in the Spec of the parent Ingress.<br>
|
||||
IP in the Spec of the parent Ingress.<br>
|
||||
2. The <code>:</code> delimiter is not respected because ports are not allowed.<br>
|
||||
Currently the port of an Ingress is implicitly :80 for http and<br>
|
||||
:443 for https.<br>
|
||||
Currently the port of an Ingress is implicitly :80 for http and<br>
|
||||
:443 for https.<br>
|
||||
Both these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
|
||||
@@ -4172,7 +4172,7 @@ The resulting set of endpoints can be viewed as:<br>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">nodeSelector</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection/README">http://kubernetes.io/docs/user-guide/node-selection/README</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection">http://kubernetes.io/docs/user-guide/node-selection</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">object</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
@@ -8146,7 +8146,7 @@ The resulting set of endpoints can be viewed as:<br>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">unschedulable</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Unschedulable controls node schedulability of new pods. By default, node is schedulable. More info: <a href="http://releases.k8s.io/HEAD/docs/admin/node.md#manual-node-administration"">http://releases.k8s.io/HEAD/docs/admin/node.md#manual-node-administration"</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Unschedulable controls node schedulability of new pods. By default, node is schedulable. More info: <a href="http://releases.k8s.io/HEAD/docs/admin/node.md#manual-node-administration">http://releases.k8s.io/HEAD/docs/admin/node.md#manual-node-administration</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">boolean</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
@@ -8263,4 +8263,4 @@ Last updated 2016-11-17 06:26:10 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
+16
-16
@@ -33,7 +33,7 @@
|
||||
<li><a href="/docs/troubleshooting/" {% if toc.bigheader == "Support" %}class="YAH"{% endif %}>SUPPORT</a></li>
|
||||
</ul>
|
||||
<div id="searchBox">
|
||||
<input type="text" id="search" placeholder="Search" onkeydown="if (event.keyCode==13) window.location.replace('/docs/search/?q=' + this.value)">
|
||||
<input type="text" id="search" placeholder="Search" onkeydown="if (event.keyCode==13) window.location.replace('/docs/search/?q=' + this.value)" autofocus="autofocus">
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
@@ -57,22 +57,22 @@
|
||||
|
||||
{{ content }}
|
||||
|
||||
<p><a href=""><img src="https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/{{ page.path }}?pixel" alt="Analytics" /></a>
|
||||
<p><a href=""><img src="https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/{{ page.path }}?pixel" alt="Analytics" /></a></p>
|
||||
{% if page.url != "/404.html" and page.url != "/docs/search/" %}
|
||||
<script type="text/javascript">
|
||||
PDRTJS_settings_8345992 = {
|
||||
"id" : "8345992",
|
||||
"unique_id" : "{{ page.url }}",
|
||||
"title" : "{{ page.title }}",
|
||||
"permalink" : "http://kubernetes.github.io{{ page.url }}"
|
||||
};
|
||||
(function(d,c,j){if(!document.getElementById(j)){var pd=d.createElement(c),s;pd.id=j;pd.src=('https:'==document.location.protocol)?'https://polldaddy.com/js/rating/rating.js':'http://i0.poll.fm/js/rating/rating.js';s=document.getElementsByTagName(c)[0];s.parentNode.insertBefore(pd,s);}}(document,'script','pd-rating-js'));
|
||||
</script>
|
||||
<a href="" onclick="window.open('https://github.com/kubernetes/kubernetes.github.io/issues/new?title=Issue%20with%20' +
|
||||
window.location.pathname)" class="button issue">Create an Issue</a>
|
||||
<a href="/editdocs#{{ page.path }}" class="button issue">Edit this Page</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
PDRTJS_settings_8345992 = {
|
||||
"id" : "8345992",
|
||||
"unique_id" : "{{ page.url }}",
|
||||
"title" : "{{ page.title }}",
|
||||
"permalink" : "http://kubernetes.github.io{{ page.url }}"
|
||||
};
|
||||
(function(d,c,j){if(!document.getElementById(j)){var pd=d.createElement(c),s;pd.id=j;pd.src=('https:'==document.location.protocol)?'https://polldaddy.com/js/rating/rating.js':'http://i0.poll.fm/js/rating/rating.js';s=document.getElementsByTagName(c)[0];s.parentNode.insertBefore(pd,s);}}(document,'script','pd-rating-js'));
|
||||
</script>
|
||||
<a href="" onclick="window.open('https://github.com/kubernetes/kubernetes.github.io/issues/new?title=Issue%20with%20' +
|
||||
window.location.pathname)" class="button issue">Create an Issue</a>
|
||||
<a href="/editdocs#{{ page.path }}" class="button issue">Edit this Page</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{% include_cached footer.html %}
|
||||
|
||||
+14
-3
@@ -816,9 +816,9 @@ dd
|
||||
font-weight: 500
|
||||
|
||||
p
|
||||
font-size: 14px
|
||||
font-size: 16px
|
||||
font-weight: 300
|
||||
line-height: 1.25em
|
||||
line-height: 1.75em
|
||||
|
||||
p + p
|
||||
margin-top: 10px
|
||||
@@ -856,6 +856,7 @@ dd
|
||||
display: block
|
||||
margin: 20px 0
|
||||
padding: 15px
|
||||
position: relative
|
||||
overflow-x: auto
|
||||
|
||||
h1 code, h2 code, h3 code, h4 code, h5 code, h6 code
|
||||
@@ -893,6 +894,8 @@ dd
|
||||
|
||||
li
|
||||
margin-bottom: 0.75em
|
||||
font-size: 16px
|
||||
line-height: 1.75em
|
||||
|
||||
table
|
||||
width: 100%
|
||||
@@ -1277,7 +1280,7 @@ $feature-box-div-margin-bottom: 40px
|
||||
background-color: $white
|
||||
box-shadow: 0 5px 5px rgba(0,0,0,.24),0 0 5px rgba(0,0,0,.12)
|
||||
|
||||
#calendarWrapper
|
||||
#calendarMeetings
|
||||
position: relative
|
||||
width: 80vw
|
||||
height: 60vw
|
||||
@@ -1285,6 +1288,14 @@ $feature-box-div-margin-bottom: 40px
|
||||
max-height: 900px
|
||||
margin: 20px auto
|
||||
|
||||
#calendarEvents
|
||||
position: relative
|
||||
width: 80vw
|
||||
height: 30vw
|
||||
max-width: 1200px
|
||||
max-height: 450px
|
||||
margin: 20px auto
|
||||
|
||||
iframe
|
||||
position: absolute
|
||||
border: 0
|
||||
|
||||
+77
-77
@@ -6,94 +6,94 @@ cid: caseStudies
|
||||
---
|
||||
|
||||
<section id="hero" class="light-text">
|
||||
<h1>Kubernetes User Case Studies</h1>
|
||||
<h5>A collection of users running Kubernetes in production.</h5>
|
||||
<h1>Kubernetes User Case Studies</h1>
|
||||
<h5>A collection of users running Kubernetes in production.</h5>
|
||||
</section>
|
||||
|
||||
<section id="mainContent">
|
||||
<main>
|
||||
<div class="content">
|
||||
<div class="case-studies">
|
||||
<div class="case-study">
|
||||
<img src="/images/case_studies/pearson.png" alt="Pearson">
|
||||
<p class="quote">"We chose Kubernetes because of its flexibility, ease of management and the way it improves our engineers' productivity."</p>
|
||||
<!--<p class="attrib">— Chris Jackson, Director for Cloud Product Engineering, Pearson</p>-->
|
||||
<a href="./pearson/">Read about Pearson</a>
|
||||
</div>
|
||||
<div class="case-study">
|
||||
<img src="/images/case_studies/wikimedia.png" alt="Wikimedia">
|
||||
<p class="quote">"With Kubernetes, we're simplifying our environment and making it easier for developers to build the tools that make wikis run better."</p>
|
||||
<!--<p class="attrib">— Yuvi Panda, Operations Engineer, Wikimedia Foundation</p>-->
|
||||
<a href="./wikimedia/">Read about Wikimedia</a>
|
||||
</div>
|
||||
<div class="case-study">
|
||||
<img src="/images/case_studies/ebay.png" alt="eBay">
|
||||
<p class="quote">Inside eBay's shift to Kubernetes and containers atop OpenStack</p>
|
||||
<a href="http://www.nextplatform.com/2015/11/12/inside-ebays-shift-to-kubernetes-and-containers-atop-openstack/">Read about eBay</a>
|
||||
</div>
|
||||
<div class="case-study">
|
||||
<img src="/images/case_studies/box.png" alt="box">
|
||||
<p class="quote">Kubernetes at Box: Microservices at Maximum Velocity</p>
|
||||
<a href="https://blog.box.com/blog/kubernetes-box-microservices-maximum-velocity/">Read about Box</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<main>
|
||||
<div class="content">
|
||||
<div class="case-studies">
|
||||
<div class="case-study">
|
||||
<img src="/images/case_studies/pearson.png" alt="Pearson">
|
||||
<p class="quote">"We chose Kubernetes because of its flexibility, ease of management and the way it improves our engineers' productivity."</p>
|
||||
<!--<p class="attrib">— Chris Jackson, Director for Cloud Product Engineering, Pearson</p>-->
|
||||
<a href="./pearson/">Read about Pearson</a>
|
||||
</div>
|
||||
<div class="case-study">
|
||||
<img src="/images/case_studies/wikimedia.png" alt="Wikimedia">
|
||||
<p class="quote">"With Kubernetes, we're simplifying our environment and making it easier for developers to build the tools that make wikis run better."</p>
|
||||
<!--<p class="attrib">— Yuvi Panda, Operations Engineer, Wikimedia Foundation</p>-->
|
||||
<a href="./wikimedia/">Read about Wikimedia</a>
|
||||
</div>
|
||||
<div class="case-study">
|
||||
<img src="/images/case_studies/ebay.png" alt="eBay">
|
||||
<p class="quote">Inside eBay's shift to Kubernetes and containers atop OpenStack</p>
|
||||
<a href="http://www.nextplatform.com/2015/11/12/inside-ebays-shift-to-kubernetes-and-containers-atop-openstack/">Read about eBay</a>
|
||||
</div>
|
||||
<div class="case-study">
|
||||
<img src="/images/case_studies/box.png" alt="box">
|
||||
<p class="quote">Kubernetes at Box: Microservices at Maximum Velocity</p>
|
||||
<a href="https://blog.box.com/blog/kubernetes-box-microservices-maximum-velocity/">Read about Box</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<section id="video">
|
||||
<main>
|
||||
<!--<div>-->
|
||||
<!--<h3>"I don't want to deploy software the old way ever again"</h3>-->
|
||||
<!--<p class="attrib">— Dylan Carney, Lead Software Engineer, Zulily</p>-->
|
||||
<!--<img src="/images/case_studies/zulily.png" id="zulilyLogo" alt="zulily">-->
|
||||
<!--</div>-->
|
||||
<!--<div><button onclick="kub.showVideo()"><img src="/images/case_studies/video_thumb.jpg" alt="Zulily video"><h6>Kubernetes at zulily</h6></button></div>-->
|
||||
<div>
|
||||
<!--<h3>SAP</h3>-->
|
||||
<h3>SAP's OpenStack, running on Kubernetes in production</h3>
|
||||
<img src="/images/case_studies/sap_small.png" id="zulilyLogo" alt="SAP">
|
||||
</div>
|
||||
<div><button onclick="kub.showVideo()"><img src="/images/case_studies/video_thumb1.png" alt="SAP video"><h6>Kubernetes at SAP</h6></button></div>
|
||||
</main>
|
||||
<main>
|
||||
<!--<div>-->
|
||||
<!--<h3>"I don't want to deploy software the old way ever again"</h3>-->
|
||||
<!--<p class="attrib">— Dylan Carney, Lead Software Engineer, Zulily</p>-->
|
||||
<!--<img src="/images/case_studies/zulily.png" id="zulilyLogo" alt="zulily">-->
|
||||
<!--</div>-->
|
||||
<!--<div><button onclick="kub.showVideo()"><img src="/images/case_studies/video_thumb.jpg" alt="Zulily video"><h6>Kubernetes at zulily</h6></button></div>-->
|
||||
<div>
|
||||
<!--<h3>SAP</h3>-->
|
||||
<h3>SAP's OpenStack, running on Kubernetes in production</h3>
|
||||
<img src="/images/case_studies/sap_small.png" id="zulilyLogo" alt="SAP">
|
||||
</div>
|
||||
<div><button onclick="kub.showVideo()"><img src="/images/case_studies/video_thumb1.png" alt="SAP video"><h6>Kubernetes at SAP</h6></button></div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<section id="users">
|
||||
<main>
|
||||
<h3>Kubernetes Users</h3>
|
||||
<div id="usersGrid">
|
||||
<a target="_blank" href="https://www.youtube.com/watch?v=P5qfyv_zGcU"><img src="/images/case_studies/nyt.png" alt="New York Times"></a>
|
||||
<a target="_blank" href="https://openai.com/blog/infrastructure-for-deep-learning"><img src="/images/case_studies/openai.png" alt="OpenAI"></a>
|
||||
<a target="_blank" href="http://blogs.wsj.com/cio/2016/02/24/big-changes-in-goldmans-software-emerge-from-small-containers/"><img src="/images/case_studies/gs.png" alt="Goldman Sachs"></a>
|
||||
<a target="_blank" href="https://youtu.be/4gyeixJLabo"><img src="/images/case_studies/sap.png" alt="SAP"></a>
|
||||
<a target="_blank" href="http://www.nextplatform.com/2016/05/24/samsung-experts-put-kubernetes-paces/"><img src="/images/case_studies/sds.png" alt="Samsung SDS"></a>
|
||||
<a target="_blank" href="http://thenewstack.io/wepay-kubernetes-changed-business/"><img src="/images/case_studies/wepay.png" alt="WePay"></a>
|
||||
<a target="_blank" href="https://www.youtube.com/watch?v=5378N5iLb2Q"><img src="/images/case_studies/soundcloud.png" alt="SoundCloud"></a>
|
||||
<a target="_blank" href="https://www.youtube.com/watch?v=F3iMkz_NSvU"><img src="/images/case_studies/homeoffice.png" alt="UK Home Office"></a>
|
||||
<a target="_blank" href="http://searchitoperations.techtarget.com/news/450297178/Tech-firms-roll-out-Kubernetes-in-production"><img src="/images/case_studies/concur.png" alt="Concur"></a>
|
||||
<a target="_blank" href="http://www.nextplatform.com/2015/08/04/amadeus-takes-off-with-containers-and-clouds/"><img src="/images/case_studies/amadeus.png" alt="Amadeus"></a>
|
||||
<a target="_blank" href="http://superuser.openstack.org/articles/how-ancestry-com-s-open-source-strategy-combines-kubernetes-and-openstack"><img src="/images/case_studies/ancestry.png" alt="Ancestry.com"></a>
|
||||
<a target="_blank" href="https://cloud.google.com/customers/ccp-games/"><img src="/images/case_studies/ccp.png" alt="CCP Games"></a>
|
||||
<a target="_blank" href="https://www.openstack.org/videos/video/running-kubernetes-on-openstack-at-liveperson"><img src="/images/case_studies/liveperson.png" alt="LivePerson"></a>
|
||||
<a target="_blank" href="https://youtu.be/YkOY7DgXKyw"><img src="/images/case_studies/monzo_logo.png" alt="monzo"></a>
|
||||
<a target="_blank" href="https://blog.box.com/blog/kubernetes-box-microservices-maximum-velocity/"><img src="/images/case_studies/box_logo.png" alt="Box"></a>
|
||||
<a target="_blank" href="https://cloudplatform.googleblog.com/2016/09/bringing-Pokemon-GO-to-life-on-Google-Cloud.html"><img src="/images/case_studies/pokemon_go_logo.png" alt="Pokemon GO"></a>
|
||||
<a target="_blank" href="http://blog.kubernetes.io/2016/10/kubernetes-and-openstack-at-yahoo-japan.html"><img src="/images/case_studies/yahooJapan_logo.png" alt="Yahoo! Japan"></a>
|
||||
<a target="_blank" href="https://cloud.google.com/customers/philips/"><img src="/images/case_studies/philips_logo.png" alt="Philips"></a>
|
||||
<a target="_blank" href="https://youtu.be/EC_ZRLsw58M"><img src="/images/case_studies/buffer_logo.png" alt="buffer"></a>
|
||||
<a target="_blank" href="https://youtu.be/lmeFkH-rHII"><img src="/images/case_studies/comcast_logo.png" alt="Comcast"></a>
|
||||
<a href="./wikimedia/"><img src="/images/case_studies/wikimedia_logo.png" alt="Wikimedia"></a>
|
||||
<a href="./pearson/"><img src="/images/case_studies/pearson_logo.png" alt="Pearson"></a>
|
||||
<a target="_blank" href="#" onclick="event.preventDefault(); kub.showVideo()"><img src="/images/case_studies/zulily_logo.png" alt="zulily"></a>
|
||||
<a target="_blank" href="http://www.nextplatform.com/2015/11/12/inside-ebays-shift-to-kubernetes-and-containers-atop-openstack/"><img src="/images/case_studies/ebay_logo.png" alt="Ebay"></a>
|
||||
<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/e/1FAIpQLScuI7Ye3VQHQTwBASrgkjQDSS5TP0g3AXfFhwSM9YpHgxRKFA/viewform" class="tell-your-story"><img src="/images/case_studies/story.png" alt="Tell your story"></a>
|
||||
</div>
|
||||
</main>
|
||||
<main>
|
||||
<h3>Kubernetes Users</h3>
|
||||
<div id="usersGrid">
|
||||
<a target="_blank" href="https://www.youtube.com/watch?v=P5qfyv_zGcU"><img src="/images/case_studies/nyt.png" alt="New York Times"></a>
|
||||
<a target="_blank" href="https://openai.com/blog/infrastructure-for-deep-learning"><img src="/images/case_studies/openai.png" alt="OpenAI"></a>
|
||||
<a target="_blank" href="http://blogs.wsj.com/cio/2016/02/24/big-changes-in-goldmans-software-emerge-from-small-containers/"><img src="/images/case_studies/gs.png" alt="Goldman Sachs"></a>
|
||||
<a target="_blank" href="https://youtu.be/4gyeixJLabo"><img src="/images/case_studies/sap.png" alt="SAP"></a>
|
||||
<a target="_blank" href="http://www.nextplatform.com/2016/05/24/samsung-experts-put-kubernetes-paces/"><img src="/images/case_studies/sds.png" alt="Samsung SDS"></a>
|
||||
<a target="_blank" href="http://thenewstack.io/wepay-kubernetes-changed-business/"><img src="/images/case_studies/wepay.png" alt="WePay"></a>
|
||||
<a target="_blank" href="https://www.youtube.com/watch?v=5378N5iLb2Q"><img src="/images/case_studies/soundcloud.png" alt="SoundCloud"></a>
|
||||
<a target="_blank" href="https://www.youtube.com/watch?v=F3iMkz_NSvU"><img src="/images/case_studies/homeoffice.png" alt="UK Home Office"></a>
|
||||
<a target="_blank" href="http://searchitoperations.techtarget.com/news/450297178/Tech-firms-roll-out-Kubernetes-in-production"><img src="/images/case_studies/concur.png" alt="Concur"></a>
|
||||
<a target="_blank" href="http://www.nextplatform.com/2015/08/04/amadeus-takes-off-with-containers-and-clouds/"><img src="/images/case_studies/amadeus.png" alt="Amadeus"></a>
|
||||
<a target="_blank" href="http://superuser.openstack.org/articles/how-ancestry-com-s-open-source-strategy-combines-kubernetes-and-openstack"><img src="/images/case_studies/ancestry.png" alt="Ancestry.com"></a>
|
||||
<a target="_blank" href="https://cloud.google.com/customers/ccp-games/"><img src="/images/case_studies/ccp.png" alt="CCP Games"></a>
|
||||
<a target="_blank" href="https://www.openstack.org/videos/video/running-kubernetes-on-openstack-at-liveperson"><img src="/images/case_studies/liveperson.png" alt="LivePerson"></a>
|
||||
<a target="_blank" href="https://youtu.be/YkOY7DgXKyw"><img src="/images/case_studies/monzo_logo.png" alt="monzo"></a>
|
||||
<a target="_blank" href="https://blog.box.com/blog/kubernetes-box-microservices-maximum-velocity/"><img src="/images/case_studies/box_logo.png" alt="Box"></a>
|
||||
<a target="_blank" href="https://cloudplatform.googleblog.com/2016/09/bringing-Pokemon-GO-to-life-on-Google-Cloud.html"><img src="/images/case_studies/pokemon_go_logo.png" alt="Pokemon GO"></a>
|
||||
<a target="_blank" href="http://blog.kubernetes.io/2016/10/kubernetes-and-openstack-at-yahoo-japan.html"><img src="/images/case_studies/yahooJapan_logo.png" alt="Yahoo! Japan"></a>
|
||||
<a target="_blank" href="https://cloud.google.com/customers/philips/"><img src="/images/case_studies/philips_logo.png" alt="Philips"></a>
|
||||
<a target="_blank" href="https://youtu.be/EC_ZRLsw58M"><img src="/images/case_studies/buffer_logo.png" alt="buffer"></a>
|
||||
<a target="_blank" href="https://youtu.be/lmeFkH-rHII"><img src="/images/case_studies/comcast_logo.png" alt="Comcast"></a>
|
||||
<a href="./wikimedia/"><img src="/images/case_studies/wikimedia_logo.png" alt="Wikimedia"></a>
|
||||
<a href="./pearson/"><img src="/images/case_studies/pearson_logo.png" alt="Pearson"></a>
|
||||
<a target="_blank" href="#" onclick="event.preventDefault(); kub.showVideo()"><img src="/images/case_studies/zulily_logo.png" alt="zulily"></a>
|
||||
<a target="_blank" href="http://www.nextplatform.com/2015/11/12/inside-ebays-shift-to-kubernetes-and-containers-atop-openstack/"><img src="/images/case_studies/ebay_logo.png" alt="Ebay"></a>
|
||||
<a target="_blank" href="https://docs.google.com/a/google.com/forms/d/e/1FAIpQLScuI7Ye3VQHQTwBASrgkjQDSS5TP0g3AXfFhwSM9YpHgxRKFA/viewform" class="tell-your-story"><img src="/images/case_studies/story.png" alt="Tell your story"></a>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
|
||||
<div id="videoPlayer">
|
||||
<!--<iframe data-url="https://www.youtube.com/watch?v=B0_5Nms8sD0" frameborder="0" allowfullscreen></iframe>-->
|
||||
<iframe data-url="https://www.youtube.com/embed/4gyeixJLabo?autoplay=1" frameborder="0" allowfullscreen></iframe>
|
||||
<button id="closeButton"></button>
|
||||
<!--<iframe data-url="https://www.youtube.com/watch?v=B0_5Nms8sD0" frameborder="0" allowfullscreen></iframe>-->
|
||||
<iframe data-url="https://www.youtube.com/embed/4gyeixJLabo?autoplay=1" frameborder="0" allowfullscreen="true"></iframe>
|
||||
<button id="closeButton"></button>
|
||||
</div>
|
||||
|
||||
+60
-60
@@ -6,76 +6,76 @@ cid: caseStudies
|
||||
---
|
||||
|
||||
<section id="hero" class="light-text">
|
||||
<h1> Pearson Case Study</h1>
|
||||
<h1> Pearson Case Study</h1>
|
||||
</section>
|
||||
|
||||
<section id="mainContent">
|
||||
<main>
|
||||
<div class="content">
|
||||
<h3 id="caseStudyTitle">Using Kubernetes to reinvent the world's largest educational company</h3>
|
||||
<p>
|
||||
Pearson, the world's education company, serving 75 million learners worldwide, set a goal to more than double that number to 200 million by 2025. A key part of this growth is in digital learning experiences, and that requires an infrastructure platform that is able to scale quickly and deliver products to market faster. So Pearson's Cloud Technology team chose Kubernetes to help build a platform to meet the business requirements. </p>
|
||||
<div class="feature">
|
||||
<img src="/images/case_studies/pearson.png" alt="Pearson">
|
||||
<p class="quote">
|
||||
"To transform our infrastructure, we had to think beyond simply enabling automated provisioning, we realized we had to build a platform that would allow Pearson developers to build manage and deploy applications in a completely different way. We chose Kubernetes because of its flexibility, ease of management and the way it would improve our engineers' productivity." </p>
|
||||
<p class="attrib">— Chris Jackson, Director for Cloud Product Engineering, Pearson</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<main>
|
||||
<div class="content">
|
||||
<h3 id="caseStudyTitle">Using Kubernetes to reinvent the world's largest educational company</h3>
|
||||
<p>
|
||||
Pearson, the world's education company, serving 75 million learners worldwide, set a goal to more than double that number to 200 million by 2025. A key part of this growth is in digital learning experiences, and that requires an infrastructure platform that is able to scale quickly and deliver products to market faster. So Pearson's Cloud Technology team chose Kubernetes to help build a platform to meet the business requirements. </p>
|
||||
<div class="feature">
|
||||
<img src="/images/case_studies/pearson.png" alt="Pearson">
|
||||
<p class="quote">
|
||||
"To transform our infrastructure, we had to think beyond simply enabling automated provisioning, we realized we had to build a platform that would allow Pearson developers to build manage and deploy applications in a completely different way. We chose Kubernetes because of its flexibility, ease of management and the way it would improve our engineers' productivity." </p>
|
||||
<p class="attrib">— Chris Jackson, Director for Cloud Product Engineering, Pearson</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<section class="bullets">
|
||||
<main>
|
||||
<div class="content">
|
||||
<div class="bullet">
|
||||
<h4>Challenges:</h4>
|
||||
<ul>
|
||||
<li>Pearson had difficulty in scaling and adapting to the growing online audience. They wanted to build and deliver content primarily over the web.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bullet">
|
||||
<h4>Why Kubernetes:</h4>
|
||||
<ul>
|
||||
<li>Kubernetes will allow Pearson's teams to develop their apps in a consistent manner, saving time and minimizing complexity.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bullet">
|
||||
<h4>Approach:</h4>
|
||||
<ul>
|
||||
<li>Build a centralized platform for use across the entire enterprise</li>
|
||||
<li>Use container technology as the core of the platform</li>
|
||||
<li>Deploy Kubernetes to manage the platform</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bullet">
|
||||
<h4>Results:</h4>
|
||||
<ul>
|
||||
<li>Pearson is building an enterprise-wide platform for delivering innovative, web-based educational content. They expect engineers' productivity to increase by up to 20 percent.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<main>
|
||||
<div class="content">
|
||||
<div class="bullet">
|
||||
<h4>Challenges:</h4>
|
||||
<ul>
|
||||
<li>Pearson had difficulty in scaling and adapting to the growing online audience. They wanted to build and deliver content primarily over the web.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bullet">
|
||||
<h4>Why Kubernetes:</h4>
|
||||
<ul>
|
||||
<li>Kubernetes will allow Pearson's teams to develop their apps in a consistent manner, saving time and minimizing complexity.</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bullet">
|
||||
<h4>Approach:</h4>
|
||||
<ul>
|
||||
<li>Build a centralized platform for use across the entire enterprise</li>
|
||||
<li>Use container technology as the core of the platform</li>
|
||||
<li>Deploy Kubernetes to manage the platform</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bullet">
|
||||
<h4>Results:</h4>
|
||||
<ul>
|
||||
<li>Pearson is building an enterprise-wide platform for delivering innovative, web-based educational content. They expect engineers' productivity to increase by up to 20 percent.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<section class="details">
|
||||
<main>
|
||||
<div class="content">
|
||||
<h4>Kubernetes powers a comprehensive developer experience</h4>
|
||||
<p>Pearson wanted to use as much open source technology as possible for the platform given that it provides both technical and commercial benefits over the duration of the project. Jackson says, "Building an infrastructure platform based on open source technology in Pearson was a no-brainer, the sharing of technical challenges and advanced use cases in a community of people with talent far beyond what we could hire independently allows us to innovate at a level we could not reach on our own. Our engineers enjoy returning code to the community and participating in talks, blogs and meetings, it's a great way for us to allow our team to express themselves and share the pride they have in their work."</p>
|
||||
<p>It also wanted to use a container-focused platform. Pearson has 400 development groups and diverse brands with varying business and technical needs. With containers, each brand could experiment with building new types of content using their preferred technologies, and then deliver it using containers. Pearson chose Kubernetes because it believes that is the best technology for managing containers, has the widest community support and offers the most flexible and powerful tools."</p>
|
||||
<p>Kubernetes is at the core of the platform we've built for developers. After we get our big spike in back-to-school in traffic, much of Pearson's traffic will interact with Kubernetes. It is proving to be as effective as we had hoped," Jackson says.</p>
|
||||
</div>
|
||||
</main>
|
||||
<main>
|
||||
<div class="content">
|
||||
<h4>Kubernetes powers a comprehensive developer experience</h4>
|
||||
<p>Pearson wanted to use as much open source technology as possible for the platform given that it provides both technical and commercial benefits over the duration of the project. Jackson says, "Building an infrastructure platform based on open source technology in Pearson was a no-brainer, the sharing of technical challenges and advanced use cases in a community of people with talent far beyond what we could hire independently allows us to innovate at a level we could not reach on our own. Our engineers enjoy returning code to the community and participating in talks, blogs and meetings, it's a great way for us to allow our team to express themselves and share the pride they have in their work."</p>
|
||||
<p>It also wanted to use a container-focused platform. Pearson has 400 development groups and diverse brands with varying business and technical needs. With containers, each brand could experiment with building new types of content using their preferred technologies, and then deliver it using containers. Pearson chose Kubernetes because it believes that is the best technology for managing containers, has the widest community support and offers the most flexible and powerful tools."</p>
|
||||
<p>Kubernetes is at the core of the platform we've built for developers. After we get our big spike in back-to-school in traffic, much of Pearson's traffic will interact with Kubernetes. It is proving to be as effective as we had hoped," Jackson says.</p>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<section class="details">
|
||||
<main>
|
||||
<div class="content">
|
||||
<h4>Encouraging experimentation, saving engineers time</h4>
|
||||
<p>With the new platform, Pearson will increase stability and performance, and to bring products to market more quickly. The company says its engineers will also get a productivity boost because they won't spend time managing infrastructure. Jackson estimates 15 to 20 percent in productivity savings.</p>
|
||||
<p>Beyond that, Pearson says the platform will encourage innovation because of the ease with which new applications can be developed, and because applications will be deployed far more quickly than in the past. It expects that will help the company meet its goal of reaching 200 million learners within the next 10 years.</p>
|
||||
<p>"We're already seeing tremendous benefits with Kubernetes — improved engineering productivity, faster delivery of applications and a simplified infrastructure. But this is just the beginning. Kubernetes will help transform the way that educational content is delivered online," says Jackson.</p>
|
||||
</div>
|
||||
</main>
|
||||
<main>
|
||||
<div class="content">
|
||||
<h4>Encouraging experimentation, saving engineers time</h4>
|
||||
<p>With the new platform, Pearson will increase stability and performance, and to bring products to market more quickly. The company says its engineers will also get a productivity boost because they won't spend time managing infrastructure. Jackson estimates 15 to 20 percent in productivity savings.</p>
|
||||
<p>Beyond that, Pearson says the platform will encourage innovation because of the ease with which new applications can be developed, and because applications will be deployed far more quickly than in the past. It expects that will help the company meet its goal of reaching 200 million learners within the next 10 years.</p>
|
||||
<p>"We're already seeing tremendous benefits with Kubernetes — improved engineering productivity, faster delivery of applications and a simplified infrastructure. But this is just the beginning. Kubernetes will help transform the way that educational content is delivered online," says Jackson.</p>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
+75
-75
@@ -6,91 +6,91 @@ cid: caseStudies
|
||||
---
|
||||
|
||||
<section id="hero" class="light-text">
|
||||
<h1> Wikimedia Case Study</h1>
|
||||
<h1> Wikimedia Case Study</h1>
|
||||
</section>
|
||||
|
||||
<section id="mainContent">
|
||||
<main>
|
||||
<div class="content">
|
||||
<h3 id="caseStudyTitle">Using Kubernetes to Build Tools to Improve the World's Wikis</h3>
|
||||
<p>
|
||||
The non-profit Wikimedia Foundation operates some of the largest collaboratively edited reference projects in the world, including Wikipedia. To help users maintain and use wikis, it runs Wikimedia Tool Labs, a hosting environment for community developers working on tools and bots to help editors and other volunteers do their work, including reducing vandalism. The community around Wikimedia Tool Labs began forming nearly 10 years ago.
|
||||
</p>
|
||||
<div class="feature">
|
||||
<img src="/images/case_studies/wikimedia.png" alt="Wikimedia">
|
||||
<p class="quote">
|
||||
"Wikimedia Tool Labs is vital for making sure wikis all around the world work as well as they possibly can. Because it's grown organically for almost 10 years, it has become an extremely challenging environment and difficult to maintain. It's like a big ball of mud — you really can't see through it. With Kubernetes, we're simplifying the environment and making it easier for developers to build the tools that make wikis run better."
|
||||
</p>
|
||||
<p class="attrib">— Yuvi Panda, operations engineer at Wikimedia Foundation and Wikimedia Tool Labs</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<main>
|
||||
<div class="content">
|
||||
<h3 id="caseStudyTitle">Using Kubernetes to Build Tools to Improve the World's Wikis</h3>
|
||||
<p>
|
||||
The non-profit Wikimedia Foundation operates some of the largest collaboratively edited reference projects in the world, including Wikipedia. To help users maintain and use wikis, it runs Wikimedia Tool Labs, a hosting environment for community developers working on tools and bots to help editors and other volunteers do their work, including reducing vandalism. The community around Wikimedia Tool Labs began forming nearly 10 years ago.
|
||||
</p>
|
||||
<div class="feature">
|
||||
<img src="/images/case_studies/wikimedia.png" alt="Wikimedia">
|
||||
<p class="quote">
|
||||
"Wikimedia Tool Labs is vital for making sure wikis all around the world work as well as they possibly can. Because it's grown organically for almost 10 years, it has become an extremely challenging environment and difficult to maintain. It's like a big ball of mud — you really can't see through it. With Kubernetes, we're simplifying the environment and making it easier for developers to build the tools that make wikis run better."
|
||||
</p>
|
||||
<p class="attrib">— Yuvi Panda, operations engineer at Wikimedia Foundation and Wikimedia Tool Labs</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<section class="bullets">
|
||||
<main>
|
||||
<div class="content">
|
||||
<div class="bullet">
|
||||
<h4>Challenges:</h4>
|
||||
<ul>
|
||||
<li>Simplify a complex, difficult-to-manage infrastructure</li>
|
||||
<li>Allow developers to continue writing tools and bots using existing techniques</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bullet">
|
||||
<h4>Why Kubernetes:</h4>
|
||||
<ul>
|
||||
<li>Wikimedia Tool Labs chose Kubernetes because it can mimic existing workflows, while reducing complexity</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bullet">
|
||||
<h4>Approach:</h4>
|
||||
<ul>
|
||||
<li>Migrate old systems and a complex infrastructure to Kubernetes</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bullet">
|
||||
<h4>Results:</h4>
|
||||
<ul>
|
||||
<li>20 percent of web tools that account for more than 40 percent of web traffic now run on Kubernetes</li>
|
||||
<li>A 25-node cluster that keeps up with each new Kubernetes release</li>
|
||||
<li>Thousands of lines of old code have been deleted, thanks to Kubernetes</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<main>
|
||||
<div class="content">
|
||||
<div class="bullet">
|
||||
<h4>Challenges:</h4>
|
||||
<ul>
|
||||
<li>Simplify a complex, difficult-to-manage infrastructure</li>
|
||||
<li>Allow developers to continue writing tools and bots using existing techniques</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bullet">
|
||||
<h4>Why Kubernetes:</h4>
|
||||
<ul>
|
||||
<li>Wikimedia Tool Labs chose Kubernetes because it can mimic existing workflows, while reducing complexity</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bullet">
|
||||
<h4>Approach:</h4>
|
||||
<ul>
|
||||
<li>Migrate old systems and a complex infrastructure to Kubernetes</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bullet">
|
||||
<h4>Results:</h4>
|
||||
<ul>
|
||||
<li>20 percent of web tools that account for more than 40 percent of web traffic now run on Kubernetes</li>
|
||||
<li>A 25-node cluster that keeps up with each new Kubernetes release</li>
|
||||
<li>Thousands of lines of old code have been deleted, thanks to Kubernetes</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<section class="details">
|
||||
<main>
|
||||
<div class="content">
|
||||
<h4>Using Kubernetes to provide tools for maintaining wikis</h4>
|
||||
<p>
|
||||
Wikimedia Tool Labs is run by a staff of four-and-a-half paid employees and two volunteers. The infrastructure didn't make it easy or intuitive for developers to build bots and other tools to make wikis work more easily. Yuvi says, "It's incredibly chaotic. We have lots of Perl and Bash duct tape on top of it. Everything is super fragile."
|
||||
</p>
|
||||
<p>
|
||||
To solve the problem, Wikimedia Tool Labs migrated parts of its infrastructure to Kubernetes, in preparation for eventually moving its entire system. Yuvi said Kubernetes greatly simplifies maintenance. The goal is to allow developers creating bots and other tools to use whatever development methods they want, but make it easier for the Wikimedia Tool Labs to maintain the required infrastructure for hosting and sharing them.
|
||||
</p>
|
||||
<p>
|
||||
"With Kubernetes, I've been able to remove a lot of our custom-made code, which makes everything easier to maintain. Our users' code also runs in a more stable way than previously," says Yuvi.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<main>
|
||||
<div class="content">
|
||||
<h4>Using Kubernetes to provide tools for maintaining wikis</h4>
|
||||
<p>
|
||||
Wikimedia Tool Labs is run by a staff of four-and-a-half paid employees and two volunteers. The infrastructure didn't make it easy or intuitive for developers to build bots and other tools to make wikis work more easily. Yuvi says, "It's incredibly chaotic. We have lots of Perl and Bash duct tape on top of it. Everything is super fragile."
|
||||
</p>
|
||||
<p>
|
||||
To solve the problem, Wikimedia Tool Labs migrated parts of its infrastructure to Kubernetes, in preparation for eventually moving its entire system. Yuvi said Kubernetes greatly simplifies maintenance. The goal is to allow developers creating bots and other tools to use whatever development methods they want, but make it easier for the Wikimedia Tool Labs to maintain the required infrastructure for hosting and sharing them.
|
||||
</p>
|
||||
<p>
|
||||
"With Kubernetes, I've been able to remove a lot of our custom-made code, which makes everything easier to maintain. Our users' code also runs in a more stable way than previously," says Yuvi.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<section class="details">
|
||||
<main>
|
||||
<div class="content">
|
||||
<h4>Simplifying infrastructure and keeping wikis running better</h4>
|
||||
<p>
|
||||
Wikimedia Tool Labs has seen great success with the initial Kubernetes deployment. Old code is being simplified and eliminated, contributing developers don't have to change the way they write their tools and bots, and those tools and bots run in a more stable fashion than they have in the past. The paid staff and volunteers are able to better keep up with fixing issues.
|
||||
</p>
|
||||
<p>
|
||||
In the future, with a more complete migration to Kubernetes, Wikimedia Tool Labs expects to make it even easier to host and maintain the bots and tools that help run wikis across the world. The tool labs already host approximately 1,300 tools and bots from 800 volunteers, with many more being submitted every day. Twenty percent of the tool labs' web tools that account for more than 60 percent of web traffic now run on Kubernetes. The tool labs has a 25-node cluster that keeps up with each new Kubernetes release. Many existing web tools are migrating to Kubernetes.
|
||||
</p>
|
||||
<p>
|
||||
"Our goal is to make sure that people all over the world can share knowledge as easily as possible. Kubernetes helps with that, by making it easier for wikis everywhere to have the tools they need to thrive," says Yuvi.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
<main>
|
||||
<div class="content">
|
||||
<h4>Simplifying infrastructure and keeping wikis running better</h4>
|
||||
<p>
|
||||
Wikimedia Tool Labs has seen great success with the initial Kubernetes deployment. Old code is being simplified and eliminated, contributing developers don't have to change the way they write their tools and bots, and those tools and bots run in a more stable fashion than they have in the past. The paid staff and volunteers are able to better keep up with fixing issues.
|
||||
</p>
|
||||
<p>
|
||||
In the future, with a more complete migration to Kubernetes, Wikimedia Tool Labs expects to make it even easier to host and maintain the bots and tools that help run wikis across the world. The tool labs already host approximately 1,300 tools and bots from 800 volunteers, with many more being submitted every day. Twenty percent of the tool labs' web tools that account for more than 60 percent of web traffic now run on Kubernetes. The tool labs has a 25-node cluster that keeps up with each new Kubernetes release. Many existing web tools are migrating to Kubernetes.
|
||||
</p>
|
||||
<p>
|
||||
"Our goal is to make sure that people all over the world can share knowledge as easily as possible. Kubernetes helps with that, by making it easier for wikis everywhere to have the tools they need to thrive," says Yuvi.
|
||||
</p>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
+56
-49
@@ -9,56 +9,63 @@ cid: community
|
||||
</section>
|
||||
|
||||
<section id="mainContent">
|
||||
<main>
|
||||
<div class="content">
|
||||
<h3>Ensuring Kubernetes works well everywhere and for everyone.</h3>
|
||||
<p>Connect with the Kubernetes community on our <a href="http://slack.k8s.io/">Slack channel</a> or join the
|
||||
<a href="https://groups.google.com/forum/#!forum/kubernetes-dev">Kubernetes-dev Google group</a>. A weekly
|
||||
community meeting takes place via video conference to discuss the state of affairs,
|
||||
<a href="https://groups.google.com/forum/#!forum/kubernetes-community-video-chat">get a calendar invite</a>
|
||||
to participate.</p>
|
||||
<p>You can also join Kubernauts all around the world through our
|
||||
<a href="https://www.meetup.com/topics/kubernetes/">Kubernetes Meetup Community</a> and the
|
||||
<a href="https://www.meetup.com/Kubernetes-Cloud-Native-Online-Meetup/">Kubernetes Cloud Native Meetup Community</a>.</p>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h3>Special Interest Groups (SIGs)</h3>
|
||||
<p>Have a special interest in how Kubernetes works with another technology? See our ever growing
|
||||
<a href="https://github.com/kubernetes/kubernetes/wiki/Special-Interest-Groups-(SIGs)">lists of SIGs</a>,
|
||||
from AWS and Openstack to Big Data and Scalability, there's a place for you to contribute and instructions
|
||||
for forming a new SIG if your special interest isn't covered (yet).</p>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h3>Events</h3>
|
||||
<div id="calendarWrapper">
|
||||
<iframe src="https://calendar.google.com/calendar/embed?src=nt2tcnbtbied3l6gi2h29slvc0%40group.calendar.google.com&ctz=America/Los_Angeles"
|
||||
frameborder="0" scrolling="no"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<main>
|
||||
<div class="content">
|
||||
<h3>Ensuring Kubernetes works well everywhere and for everyone.</h3>
|
||||
<p>Connect with the Kubernetes community on our <a href="http://slack.k8s.io/">Slack channel</a> or join the
|
||||
<a href="https://groups.google.com/forum/#!forum/kubernetes-dev">Kubernetes-dev Google group</a>. A weekly
|
||||
community meeting takes place via video conference to discuss the state of affairs,
|
||||
<a href="https://groups.google.com/forum/#!forum/kubernetes-community-video-chat">get a calendar invite</a>
|
||||
to participate.</p>
|
||||
<p>You can also join Kubernauts all around the world through our
|
||||
<a href="https://www.meetup.com/topics/kubernetes/">Kubernetes Meetup Community</a> and the
|
||||
<a href="https://www.meetup.com/Kubernetes-Cloud-Native-Online-Meetup/">Kubernetes Cloud Native Meetup Community</a>.</p>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h3>Special Interest Groups (SIGs)</h3>
|
||||
<p>Have a special interest in how Kubernetes works with another technology? See our ever growing
|
||||
<a href="https://github.com/kubernetes/kubernetes/wiki/Special-Interest-Groups-(SIGs)">lists of SIGs</a>,
|
||||
from AWS and Openstack to Big Data and Scalability, there's a place for you to contribute and instructions
|
||||
for forming a new SIG if your special interest isn't covered (yet).</p>
|
||||
|
||||
<p>As a member of the Kubernetes community, you are welcome to join any of the SIG meetings
|
||||
you are interested in. No registration required.</p>
|
||||
<div id="calendarMeetings">
|
||||
<iframe src="https://calendar.google.com/calendar/embed?src=cgnt364vd8s86hr2phapfjc6uk%40group.calendar.google.com&ctz=America/Los_Angeles"
|
||||
frameborder="0" scrolling="no"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h3>Events</h3>
|
||||
<div id="calendarEvents">
|
||||
<iframe src="https://calendar.google.com/calendar/embed?src=nt2tcnbtbied3l6gi2h29slvc0%40group.calendar.google.com&ctz=America/Los_Angeles"
|
||||
frameborder="0" scrolling="no"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
<section id="talkToUs">
|
||||
<main>
|
||||
<h3>Talk to Us!</h3>
|
||||
<h4>We would love to hear from you, how you are using Kubernetes,<br> and what we can do to make it better.</h4>
|
||||
<div id="bigSocial">
|
||||
<div>
|
||||
<a href="https://twitter.com/kubernetesio">@kubernetesio</a>
|
||||
<p>Get the latest news and updates.</p>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://github.com/kubernetes/kubernetes">Github Project</a>
|
||||
<p>Check out the project and consider contributing.</p>
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://slack.k8s.io/">#kubernetes-users</a>
|
||||
<p>Our Slack channel is the best way to contact our engineers and share your ideas with them.</p>
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://stackoverflow.com/questions/tagged/kubernetes">Stack Overflow</a>
|
||||
<p>Our user forum is a great place to go for community support.</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
<main>
|
||||
<h3>Talk to Us!</h3>
|
||||
<h4>We would love to hear from you, how you are using Kubernetes,<br> and what we can do to make it better.</h4>
|
||||
<div id="bigSocial">
|
||||
<div>
|
||||
<a href="https://twitter.com/kubernetesio">@kubernetesio</a>
|
||||
<p>Get the latest news and updates.</p>
|
||||
</div>
|
||||
<div>
|
||||
<a href="https://github.com/kubernetes/kubernetes">Github Project</a>
|
||||
<p>Check out the project and consider contributing.</p>
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://slack.k8s.io/">#kubernetes-users</a>
|
||||
<p>Our Slack channel is the best way to contact our engineers and share your ideas with them.</p>
|
||||
</div>
|
||||
<div>
|
||||
<a href="http://stackoverflow.com/questions/tagged/kubernetes">Stack Overflow</a>
|
||||
<p>Our user forum is a great place to go for community support.</p>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</section>
|
||||
|
||||
@@ -63,7 +63,7 @@ users in its object store.
|
||||
|
||||
Once the request is authenticated as coming from a specific user,
|
||||
it moves to a generic authorization step. This is shown as step **2** in the
|
||||
diagram.
|
||||
diagram.
|
||||
|
||||
The input to the Authorization step are attributes of the REST request, including:
|
||||
- the username determined by the Authentication step.
|
||||
@@ -80,7 +80,7 @@ then the request can proceed. If all deny the request, then the request is deni
|
||||
code 403).
|
||||
|
||||
The [Authorization Modules](/docs/admin/authorization) page describes what authorization modules
|
||||
are available and how to configure them.
|
||||
are available and how to configure them.
|
||||
|
||||
For version 1.2, clusters created by `kube-up.sh` are configured so that no authorization is
|
||||
required for any request.
|
||||
@@ -108,7 +108,7 @@ They act on objects being created, deleted, updated or connected (proxy), but no
|
||||
|
||||
Multiple admission controllers can be configured. Each is called in order.
|
||||
|
||||
This is shown as step **3** in the diagram.
|
||||
This is shown as step **3** in the diagram.
|
||||
|
||||
Unlike Authentication and Authorization Modules, if any admission controller module
|
||||
rejects, then the request is immediately rejected.
|
||||
@@ -122,7 +122,7 @@ Once a request passes all admission controllers, it is validated using the valid
|
||||
for the corresponding API object, and then written to the object store (shown as step **4**).
|
||||
|
||||
|
||||
## API Server Ports and IPs
|
||||
## API Server Ports and IPs
|
||||
|
||||
The previous discussion applies to requests sent to the secure port of the API server
|
||||
(the typical case). The API server can actually serve on 2 ports:
|
||||
@@ -132,7 +132,7 @@ By default the Kubernetes API server serves HTTP on 2 ports:
|
||||
1. `Localhost Port`:
|
||||
|
||||
- is intended for testing and bootstrap, and for other components of the master node
|
||||
(scheduler, controller-manager) to talk to the API
|
||||
(scheduler, controller-manager) to talk to the API
|
||||
- no TLS
|
||||
- default is port 8080, change with `--insecure-port` flag.
|
||||
- defaults IP is localhost, change with `--insecure-bind-address` flag.
|
||||
@@ -141,7 +141,7 @@ By default the Kubernetes API server serves HTTP on 2 ports:
|
||||
- protected by need to have host access
|
||||
|
||||
2. `Secure Port`:
|
||||
|
||||
|
||||
- use whenever possible
|
||||
- uses TLS. Set cert with `--tls-cert-file` and key with `--tls-private-key-file` flag.
|
||||
- default is port 6443, change with `--secure-port` flag.
|
||||
|
||||
@@ -14,6 +14,7 @@ Add-ons in each section are sorted alphabetically - the ordering does not imply
|
||||
|
||||
* [Calico](http://docs.projectcalico.org/v2.0/getting-started/kubernetes/installation/hosted/) is a secure L3 networking and network policy provider.
|
||||
* [Canal](https://github.com/tigera/canal/tree/master/k8s-install/kubeadm) unites Flannel and Calico, providing networking and network policy.
|
||||
* [Contiv](http://contiv.github.io) provides configurable networking (native L3 using BGP, overlay using vxlan, classic L2, and Cisco-SDN/ACI) for various use cases and a rich policy framework. Contiv project is fully [open sourced](http://github.com/contiv). The [installer](http://github.com/contiv/install) provides both kubeadm and non-kubeadm based installation options.
|
||||
* [Flannel](https://github.com/coreos/flannel/blob/master/Documentation/kube-flannel.yml) is an overlay network provider that can be used with Kubernetes.
|
||||
* [Romana](http://romana.io) is a Layer 3 networking solution for pod networks that also supports the [NetworkPolicy API](/docs/user-guide/networkpolicies/). Kubeadm add-on installation details available [here](https://github.com/romana/romana/tree/master/containerize).
|
||||
* [Weave Net](https://www.weave.works/docs/net/latest/kube-addon/) provides networking and network policy, will carry on working on both sides of a network partition, and does not require an external database.
|
||||
|
||||
@@ -87,7 +87,7 @@ The ImagePolicyWebhook plug-in allows a backend webhook to make admission decisi
|
||||
```
|
||||
|
||||
#### Configuration File Format
|
||||
ImagePolicyWebhook uses the admission controller config file (`--admission-controller-config-file`) to set configuration options for the behavior of the backend. This file may be json or yaml and has the following format:
|
||||
ImagePolicyWebhook uses the admission config file `--admission-controller-config-file` to set configuration options for the behavior of the backend. This file may be json or yaml and has the following format:
|
||||
|
||||
```javascript
|
||||
{
|
||||
@@ -101,7 +101,7 @@ ImagePolicyWebhook uses the admission controller config file (`--admission-contr
|
||||
}
|
||||
```
|
||||
|
||||
The config file must reference a [kubeconfig](/docs/user-guide/kubeconfig-file/) formatted file which sets up the connection to the backend. It is required that the backend communicate over TLS.
|
||||
The config file must reference a [kubeconfig](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/) formatted file which sets up the connection to the backend. It is required that the backend communicate over TLS.
|
||||
|
||||
The kubeconfig file's cluster field must point to the remote service, and the user field must contain the returned authorizer.
|
||||
|
||||
@@ -120,7 +120,7 @@ users:
|
||||
client-certificate: /path/to/cert.pem # cert for the webhook plugin to use
|
||||
client-key: /path/to/key.pem # key matching the cert
|
||||
```
|
||||
For additional HTTP configuration, refer to the [kubeconfig](/docs/user-guide/kubeconfig-file/) documentation.
|
||||
For additional HTTP configuration, refer to the [kubeconfig](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/) documentation.
|
||||
|
||||
#### Request Payloads
|
||||
|
||||
@@ -252,6 +252,11 @@ This plugin ignores any `PersistentVolumeClaim` updates, it acts only on creatio
|
||||
See [persistent volume](/docs/user-guide/persistent-volumes) documentation about persistent volume claims and
|
||||
storage classes and how to mark a storage class as default.
|
||||
|
||||
### DefaultTolerationSeconds
|
||||
|
||||
This plug-in sets the default forgiveness toleration for pods, which have no forgiveness tolerations, to tolerate
|
||||
the taints `notready:NoExecute` and `unreachable:NoExecute` for 5 minutes.
|
||||
|
||||
## Is there a recommended set of plug-ins to use?
|
||||
|
||||
Yes.
|
||||
|
||||
@@ -4,389 +4,6 @@ assignees:
|
||||
title: AppArmor
|
||||
---
|
||||
|
||||
AppArmor is a Linux kernel enhancement that can reduce the potential attack surface of an
|
||||
application and provide greater defense in depth for Applications. Beta support for AppArmor was
|
||||
added in Kubernetes v1.4.
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
## What is AppArmor
|
||||
|
||||
AppArmor is a Linux kernel security module that supplements the standard Linux user and group based
|
||||
permissions to confine programs to a limited set of resources. AppArmor can be configured for any
|
||||
application to reduce its potential attack surface and provide greater defense in depth. It is
|
||||
configured through profiles tuned to whitelist the access needed by a specific program or container,
|
||||
such as Linux capabilities, network access, file permissions, etc. Each profile can be run in either
|
||||
enforcing mode, which blocks access to disallowed resources, or complain mode, which only reports
|
||||
violations.
|
||||
|
||||
AppArmor can help you to run a more secure deployment by restricting what containers are allowed to
|
||||
do, and /or providing better auditing through system logs. However, it is important to keep in mind
|
||||
that AppArmor is not a silver bullet, and can only do so much to protect against exploits in your
|
||||
application code. It is important to provide good, restrictive profiles, and harden your
|
||||
applications and cluster from other angles as well.
|
||||
|
||||
AppArmor support in Kubernetes is currently in beta.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
1. **Kubernetes version is at least v1.4**. Kubernetes support for AppArmor was added in
|
||||
v1.4. Kubernetes components older than v1.4 are not aware of the new AppArmor annotations, and
|
||||
will **silently ignore** any AppArmor settings that are provided. To ensure that your Pods are
|
||||
receiving the expected protections, it is important to verify the Kubelet version of your nodes:
|
||||
|
||||
$ kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {@.status.nodeInfo.kubeletVersion}\n{end}'
|
||||
gke-test-default-pool-239f5d02-gyn2: v1.4.0
|
||||
gke-test-default-pool-239f5d02-x1kf: v1.4.0
|
||||
gke-test-default-pool-239f5d02-xwux: v1.4.0
|
||||
|
||||
2. **AppArmor kernel module is enabled**. For the Linux kernel to enforce an AppArmor profile, the
|
||||
AppArmor kernel module must be installed and enabled. Several distributions enable the module by
|
||||
default, such as Ubuntu and SUSE, and many others provide optional support. To check whether the
|
||||
module is enabled, check the `/sys/module/apparmor/parameters/enabled` file:
|
||||
|
||||
$ cat /sys/module/apparmor/parameters/enabled
|
||||
Y
|
||||
|
||||
If the Kubelet contains AppArmor support (>= v1.4), it will refuse to run a Pod with AppArmor
|
||||
options if the kernel module is not enabled.
|
||||
|
||||
*Note: Ubuntu carries many AppArmor patches that have not been merged into the upstream Linux
|
||||
kernel, including patches that add additional hooks and features. Kubernetes has only been
|
||||
tested with the upstream version, and does not promise support for other features.*
|
||||
|
||||
3. **Container runtime is Docker**. Currently the only Kubernetes-supported container runtime that
|
||||
also supports AppArmor is Docker. As more runtimes add AppArmor support, the options will be
|
||||
expanded. You can verify that your nodes are running docker with:
|
||||
|
||||
$ kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {@.status.nodeInfo.containerRuntimeVersion}\n{end}'
|
||||
gke-test-default-pool-239f5d02-gyn2: docker://1.11.2
|
||||
gke-test-default-pool-239f5d02-x1kf: docker://1.11.2
|
||||
gke-test-default-pool-239f5d02-xwux: docker://1.11.2
|
||||
|
||||
If the Kubelet contains AppArmor support (>= v1.4), it will refuse to run a Pod with AppArmor
|
||||
options if the runtime is not Docker.
|
||||
|
||||
4. **Profile is loaded**. AppArmor is applied to a Pod by specifying an AppArmor profile that each
|
||||
container should be run with. If any of the specified profiles is not already loaded in the
|
||||
kernel, the Kubelet (>= v1.4) will reject the Pod. You can view which profiles are loaded on a
|
||||
node by checking the `/sys/kernel/security/apparmor/profiles` file. For example:
|
||||
|
||||
$ ssh gke-test-default-pool-239f5d02-gyn2 "sudo cat /sys/kernel/security/apparmor/profiles | sort"
|
||||
apparmor-test-deny-write (enforce)
|
||||
apparmor-test-audit-write (enforce)
|
||||
docker-default (enforce)
|
||||
k8s-nginx (enforce)
|
||||
|
||||
For more details on loading profiles on nodes, see
|
||||
[Setting up nodes with profiles](#setting-up-nodes-with-profiles).
|
||||
|
||||
As long as the Kubelet version includes AppArmor support (>= v1.4), the Kubelet will reject a Pod
|
||||
with AppArmor options if any of the prerequisites are not met. You can also verify AppArmor support
|
||||
on nodes by checking the node ready condition message (though this is likely to be removed in a
|
||||
later release):
|
||||
|
||||
$ kubectl get nodes -o=jsonpath=$'{range .items[*]}{@.metadata.name}: {.status.conditions[?(@.reason=="KubeletReady")].message}\n{end}'
|
||||
gke-test-default-pool-239f5d02-gyn2: kubelet is posting ready status. AppArmor enabled
|
||||
gke-test-default-pool-239f5d02-x1kf: kubelet is posting ready status. AppArmor enabled
|
||||
gke-test-default-pool-239f5d02-xwux: kubelet is posting ready status. AppArmor enabled
|
||||
|
||||
## Securing a Pod
|
||||
|
||||
*Note: AppArmor is currently in beta, so options are specified as annotations. Once support graduates to
|
||||
general availability, the annotations will be replaced with first-class fields (more details in
|
||||
[Upgrade path to GA](#upgrade-path-to-general-availability)).*
|
||||
|
||||
AppArmor profiles are specified *per-container*. To specify the AppArmor profile to run a Pod
|
||||
container with, add an annotation to the Pod's metadata:
|
||||
|
||||
container.apparmor.security.beta.kubernetes.io/<container_name>: <profile_ref>
|
||||
|
||||
Where `<container_name>` is the name of the container to apply the profile to, and `<profile_ref>`
|
||||
specifies the profile to apply. The `profile_ref` can be one of:
|
||||
|
||||
- `runtime/default` to apply the runtime's default profile.
|
||||
- `localhost/<profile_name>` to apply the profile loaded on the host with the name `<profile_name>`
|
||||
|
||||
See the [API Reference](#api-reference) for the full details on the annotation and profile name formats.
|
||||
|
||||
The Kubernetes AppArmor enforcement works by first checking that all the prerequisites have been
|
||||
met, and then forwarding the profile selection to the container runtime for enforcement. If the
|
||||
prerequisites have not been met, the Pod will be rejected, and will not run.
|
||||
|
||||
To verify that the profile was applied, you can expect to see the AppArmor security option listed in the container created event:
|
||||
|
||||
$ kubectl get events | grep Created
|
||||
22s 22s 1 hello-apparmor Pod spec.containers{hello} Normal Created {kubelet e2e-test-stclair-minion-group-31nt} Created container with docker id 269a53b202d3; Security:[seccomp=unconfined apparmor=k8s-apparmor-example-deny-write]
|
||||
|
||||
You can also verify directly that the container's root process is running with the correct profile by checking its proc attr:
|
||||
|
||||
$ kubectl exec <pod_name> cat /proc/1/attr/current
|
||||
k8s-apparmor-example-deny-write (enforce)
|
||||
|
||||
## Example
|
||||
|
||||
In this example you'll see:
|
||||
|
||||
- One way to load a profile on a node
|
||||
- How to enforce the profile on a Pod
|
||||
- How to check that the profile is loaded
|
||||
- What happens when a profile is violated
|
||||
- What happens when a profile cannot be loaded
|
||||
|
||||
*This example assumes you have already set up a cluster with AppArmor support.*
|
||||
|
||||
First, we need to load the profile we want to use onto our nodes. The profile we'll use simply
|
||||
denies all file writes:
|
||||
|
||||
{% include code.html language="text" file="deny-write.profile" ghlink="/docs/admin/apparmor/deny-write.profile" %}
|
||||
|
||||
Since we don't know where the Pod will be scheduled, we'll need to load the profile on all our
|
||||
nodes. For this example we'll just use SSH to install the profiles, but other approaches are
|
||||
discussed in [Setting up nodes with profiles](#setting-up-nodes-with-profiles).
|
||||
|
||||
$ NODES=(
|
||||
# The SSH-accessible domain names of your nodes
|
||||
gke-test-default-pool-239f5d02-gyn2.us-central1-a.my-k8s
|
||||
gke-test-default-pool-239f5d02-x1kf.us-central1-a.my-k8s
|
||||
gke-test-default-pool-239f5d02-xwux.us-central1-a.my-k8s)
|
||||
$ for NODE in ${NODES[*]}; do ssh $NODE 'sudo apparmor_parser -q <<EOF
|
||||
#include <tunables/global>
|
||||
|
||||
profile k8s-apparmor-example-deny-write flags=(attach_disconnected) {
|
||||
#include <abstractions/base>
|
||||
|
||||
file,
|
||||
|
||||
# Deny all file writes.
|
||||
deny /** w,
|
||||
}
|
||||
EOF'
|
||||
done
|
||||
|
||||
Next, we'll run a simple "Hello AppArmor" pod with the deny-write profile:
|
||||
|
||||
{% include code.html language="yaml" file="hello-apparmor-pod.yaml" ghlink="/docs/admin/apparmor/hello-apparmor-pod.yaml" %}
|
||||
|
||||
$ kubectl create -f /dev/stdin <<EOF
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: hello-apparmor
|
||||
annotations:
|
||||
container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-apparmor-example-deny-write
|
||||
spec:
|
||||
containers:
|
||||
- name: hello
|
||||
image: busybox
|
||||
command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
|
||||
EOF
|
||||
pod "hello-apparmor" created
|
||||
|
||||
If we look at the pod events, we can see that the Pod container was created with the AppArmor
|
||||
profile "k8s-apparmor-example-deny-write":
|
||||
|
||||
$ kubectl get events | grep hello-apparmor
|
||||
14s 14s 1 hello-apparmor Pod Normal Scheduled {default-scheduler } Successfully assigned hello-apparmor to gke-test-default-pool-239f5d02-gyn2
|
||||
14s 14s 1 hello-apparmor Pod spec.containers{hello} Normal Pulling {kubelet gke-test-default-pool-239f5d02-gyn2} pulling image "busybox"
|
||||
13s 13s 1 hello-apparmor Pod spec.containers{hello} Normal Pulled {kubelet gke-test-default-pool-239f5d02-gyn2} Successfully pulled image "busybox"
|
||||
13s 13s 1 hello-apparmor Pod spec.containers{hello} Normal Created {kubelet gke-test-default-pool-239f5d02-gyn2} Created container with docker id 06b6cd1c0989; Security:[seccomp=unconfined apparmor=k8s-apparmor-example-deny-write]
|
||||
13s 13s 1 hello-apparmor Pod spec.containers{hello} Normal Started {kubelet gke-test-default-pool-239f5d02-gyn2} Started container with docker id 06b6cd1c0989
|
||||
|
||||
We can verify that the container is actually running with that profile by checking its proc attr:
|
||||
|
||||
$ kubectl exec hello-apparmor cat /proc/1/attr/current
|
||||
k8s-apparmor-example-deny-write (enforce)
|
||||
|
||||
Finally, we can see what happens if we try to violate the profile by writing to a file:
|
||||
|
||||
$ kubectl exec hello-apparmor touch /tmp/test
|
||||
touch: /tmp/test: Permission denied
|
||||
error: error executing remote command: command terminated with non-zero exit code: Error executing in Docker Container: 1
|
||||
|
||||
To wrap up, let's look at what happens if we try to specify a profile that hasn't been loaded:
|
||||
|
||||
$ kubectl create -f /dev/stdin <<EOF
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: hello-apparmor-2
|
||||
annotations:
|
||||
container.apparmor.security.beta.kubernetes.io/hello: localhost/k8s-apparmor-example-allow-write
|
||||
spec:
|
||||
containers:
|
||||
- name: hello
|
||||
image: busybox
|
||||
command: [ "sh", "-c", "echo 'Hello AppArmor!' && sleep 1h" ]
|
||||
EOF
|
||||
pod "hello-apparmor-2" created
|
||||
|
||||
$ kubectl describe pod hello-apparmor-2
|
||||
Name: hello-apparmor-2
|
||||
Namespace: default
|
||||
Node: gke-test-default-pool-239f5d02-x1kf/
|
||||
Start Time: Tue, 30 Aug 2016 17:58:56 -0700
|
||||
Labels: <none>
|
||||
Status: Failed
|
||||
Reason: AppArmor
|
||||
Message: Pod Cannot enforce AppArmor: profile "k8s-apparmor-example-allow-write" is not loaded
|
||||
IP:
|
||||
Controllers: <none>
|
||||
Containers:
|
||||
hello:
|
||||
Image: busybox
|
||||
Port:
|
||||
Command:
|
||||
sh
|
||||
-c
|
||||
echo 'Hello AppArmor!' && sleep 1h
|
||||
Requests:
|
||||
cpu: 100m
|
||||
Environment Variables: <none>
|
||||
Volumes:
|
||||
default-token-dnz7v:
|
||||
Type: Secret (a volume populated by a Secret)
|
||||
SecretName: default-token-dnz7v
|
||||
QoS Tier: Burstable
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||
23s 23s 1 {default-scheduler } Normal Scheduled Successfully assigned hello-apparmor-2 to e2e-test-stclair-minion-group-t1f5
|
||||
23s 23s 1 {kubelet e2e-test-stclair-minion-group-t1f5} Warning AppArmor Cannot enforce AppArmor: profile "k8s-apparmor-example-allow-write" is not loaded
|
||||
|
||||
Note the pod status is Failed, with a helpful error message: `Pod Cannot enforce AppArmor: profile
|
||||
"k8s-apparmor-example-allow-write" is not loaded`. An event was also recorded with the same message.
|
||||
|
||||
## Administration
|
||||
|
||||
### Setting up nodes with profiles
|
||||
|
||||
Kubernetes does not currently provide any native mechanisms for loading AppArmor profiles onto
|
||||
nodes. There are lots of ways to setup the profiles though, such as:
|
||||
|
||||
- Through a [DaemonSet](../daemons/) that runs a Pod on each node to
|
||||
ensure the correct profiles are loaded. An example implementation can be found
|
||||
[here](https://github.com/kubernetes/contrib/tree/master/apparmor/loader).
|
||||
- At node initialization time, using your node initialization scripts (e.g. Salt, Ansible, etc.) or
|
||||
image.
|
||||
- By copying the profiles to each node and loading them through SSH, as demonstrated in the
|
||||
[Example](#example).
|
||||
|
||||
The scheduler is not aware of which profiles are loaded onto which node, so the full set of profiles
|
||||
must be loaded onto every node. An alternative approach is to add a node label for each profile (or
|
||||
class of profiles) on the node, and use a
|
||||
[node selector](../../user-guide/node-selection/) to ensure the Pod is run on a
|
||||
node with the required profile.
|
||||
|
||||
### Restricting profiles with the PodSecurityPolicy
|
||||
|
||||
If the PodSecurityPolicy extension is enabled, cluster-wide AppArmor restrictions can be applied. To
|
||||
enable the PodSecurityPolicy, two flags must be set on the `apiserver`:
|
||||
|
||||
--admission-control=PodSecurityPolicy[,others...]
|
||||
--runtime-config=extensions/v1beta1/podsecuritypolicy[,others...]
|
||||
|
||||
With the extension enabled, the AppArmor options can be specified as annotations on the PodSecurityPolicy:
|
||||
|
||||
apparmor.security.beta.kubernetes.io/defaultProfileName: <profile_ref>
|
||||
apparmor.security.beta.kubernetes.io/allowedProfileNames: <profile_ref>[,others...]
|
||||
|
||||
The default profile name option specifies the profile to apply to containers by default when none is
|
||||
specified. The allowed profile names option specifies a list of profiles that Pod containers are
|
||||
allowed to be run with. If both options are provided, the default must be allowed. The profiles are
|
||||
specified in the same format as on containers. See the [API Reference](#api-reference) for the full
|
||||
specification.
|
||||
|
||||
### Disabling AppArmor
|
||||
|
||||
If you do not want AppArmor to be available on your cluster, it can be disabled by a command-line flag:
|
||||
|
||||
--feature-gates=AppArmor=false
|
||||
|
||||
When disabled, any Pod that includes an AppArmor profile will fail validation with a "Forbidden"
|
||||
error. Note that by default docker always enables the "docker-default" profile on non-privileged
|
||||
pods (if the AppArmor kernel module is enabled), and will continue to do so even if the feature-gate
|
||||
is disabled. The option to disable AppArmor will be removed when AppArmor graduates to general
|
||||
availability (GA).
|
||||
|
||||
### Upgrading to Kubernetes v1.4 with AppArmor
|
||||
|
||||
No action is required with respect to AppArmor to upgrade your cluster to v1.4. However, if any
|
||||
existing pods had an AppArmor annotation, they will not go through validation (or PodSecurityPolicy
|
||||
admission). If permissive profiles are loaded on the nodes, a malicious user could pre-apply a
|
||||
permissive profile to escalate the pod privileges above the docker-default. If this is a concern, it
|
||||
is recommended to scrub the cluster of any pods containing an annotation with
|
||||
`apparmor.security.beta.kubernetes.io`.
|
||||
|
||||
### Upgrade path to General Availability
|
||||
|
||||
When AppArmor is ready to be graduated to general availability (GA), the options currently specified
|
||||
through annotations will be converted to fields. Supporting all the upgrade and downgrade paths
|
||||
through the transition is very nuanced, and will be explained in detail when the transition
|
||||
occurs. We will commit to supporting both fields and annotations for at least 2 releases, and will
|
||||
explicitly reject the annotations for at least 2 releases after that.
|
||||
|
||||
## Authoring Profiles
|
||||
|
||||
Getting AppArmor profiles specified correctly can be a tricky business. Fortunately there are some
|
||||
tools to help with that:
|
||||
|
||||
- `aa-genprof` and `aa-logprof` generate profile rules by monitoring an application's activity and
|
||||
logs, and admitting the actions it takes. Further instructions are provided by the
|
||||
[AppArmor documentation](http://wiki.apparmor.net/index.php/Profiling_with_tools).
|
||||
- [bane](https://github.com/jfrazelle/bane) is an AppArmor profile generator for Docker that uses a
|
||||
simplified profile language.
|
||||
|
||||
It is recommended to run your application through Docker on a development workstation to generate
|
||||
the profiles, but there is nothing preventing running the tools on the Kubernetes node where your
|
||||
Pod is running.
|
||||
|
||||
To debug problems with AppArmor, you can check the system logs to see what, specifically, was
|
||||
denied. AppArmor logs verbose messages to `dmesg`, and errors can usually be found in the system
|
||||
logs or through `journalctl`. More information is provided in
|
||||
[AppArmor failures](http://wiki.apparmor.net/index.php/AppArmor_Failures).
|
||||
|
||||
Additional resources:
|
||||
|
||||
- [Quick guide to the AppArmor profile language](http://wiki.apparmor.net/index.php/QuickProfileLanguage)
|
||||
- [AppArmor core policy reference](http://wiki.apparmor.net/index.php/ProfileLanguage)
|
||||
|
||||
## API Reference
|
||||
|
||||
**Pod Annotation**:
|
||||
|
||||
Specifying the profile a container will run with:
|
||||
|
||||
- **key**: `container.apparmor.security.beta.kubernetes.io/<container_name>`
|
||||
Where `<container_name>` matches the name of a container in the Pod.
|
||||
A separate profile can be specified for each container in the Pod.
|
||||
- **value**: a profile reference, described below
|
||||
|
||||
**Profile Reference**:
|
||||
|
||||
- `runtime/default`: Refers to the default runtime profile.
|
||||
- Equivalent to not specifying a profile (without a PodSecurityPolicy default), except it still
|
||||
requires AppArmor to be enabled.
|
||||
- For Docker, this resolves to the
|
||||
[`docker-default`](https://docs.docker.com/engine/security/apparmor/) profile for non-privileged
|
||||
containers, and unconfined (no profile) for privileged containers.
|
||||
- `localhost/<profile_name>`: Refers to a profile loaded on the node (localhost) by name.
|
||||
- The possible profile names are detailed in the
|
||||
[core policy reference](http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference#Profile_names_and_attachment_specifications)
|
||||
|
||||
Any other profile reference format is invalid.
|
||||
|
||||
**PodSecurityPolicy Annotations**
|
||||
|
||||
Specifying the default profile to apply to containers when none is provided:
|
||||
|
||||
- **key**: `apparmor.security.beta.kubernetes.io/defaultProfileName`
|
||||
- **value**: a profile reference, described above
|
||||
|
||||
Specifying the list of profiles Pod containers is allowed to specify:
|
||||
|
||||
- **key**: `apparmor.security.beta.kubernetes.io/allowedProfileNames`
|
||||
- **value**: a comma-separated list of profile references (described above)
|
||||
- Although an escaped comma is a legal character in a profile name, it cannot be explicitly
|
||||
allowed here
|
||||
[AppArmor](/docs/tutorials/clusters/apparmor/)
|
||||
|
||||
+2
-59
@@ -5,63 +5,6 @@ assignees:
|
||||
title: Audit in Kubernetes
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
Kubernetes Audit provides a security-relevant chronological set of records documenting
|
||||
the sequence of activities that have affected system by individual users, administrators
|
||||
or other components of the system. It allows cluster administrator to
|
||||
answer the following questions:
|
||||
- what happened?
|
||||
- when did it happen?
|
||||
- who initiated it?
|
||||
- on what did it happen?
|
||||
- where was it observed?
|
||||
- from where was it initiated?
|
||||
- to where was it going?
|
||||
|
||||
NOTE: Currently, Kubernetes provides only basic audit capabilities, there is still a lot
|
||||
of work going on to provide fully featured auditing capabilities (see [this issue](https://github.com/kubernetes/features/issues/22)).
|
||||
|
||||
Kubernetes audit is part of [kube-apiserver](/docs/admin/kube-apiserver) logging all requests
|
||||
coming to the server. Each audit log contains two entries:
|
||||
|
||||
1. The request line containing:
|
||||
- unique id allowing to match the response line (see 2)
|
||||
- source ip of the request
|
||||
- HTTP method being invoked
|
||||
- original user invoking the operation
|
||||
- impersonated user for the operation
|
||||
- namespace of the request or <none>
|
||||
- URI as requested
|
||||
2. The response line containing:
|
||||
- the unique id from 1
|
||||
- response code
|
||||
|
||||
Example output for user `admin` asking for a list of pods:
|
||||
|
||||
```
|
||||
2016-09-07T13:03:57.400333046Z AUDIT: id="5c3b8227-4af9-4322-8a71-542231c3887b" ip="127.0.0.1" method="GET" user="admin" as="<self>" namespace="default" uri="/api/v1/namespaces/default/pods"
|
||||
2016-09-07T13:03:57.400710987Z AUDIT: id="5c3b8227-4af9-4322-8a71-542231c3887b" response="200"
|
||||
```
|
||||
|
||||
NOTE: The audit capabilities are available *only* for the secured endpoint of the API server.
|
||||
|
||||
## Configuration
|
||||
|
||||
[Kube-apiserver](/docs/admin/kube-apiserver) provides following options which are responsible
|
||||
for configuring where and how audit logs are handled:
|
||||
|
||||
- `audit-log-path` - enables the audit log pointing to a file where the requests are being logged to.
|
||||
- `audit-log-maxage` - specifies maximum number of days to retain old audit log files based on the timestamp encoded in their filename.
|
||||
- `audit-log-maxbackup` - specifies maximum number of old audit log files to retain.
|
||||
- `audit-log-maxsize` - specifies maximum size in megabytes of the audit log file before it gets rotated. Defaults to 100MB
|
||||
|
||||
If an audit log file already exists, Kubernetes appends new audit logs to that file.
|
||||
Otherwise, Kubernetes creates an audit log file at the location you specified in
|
||||
`audit-log-path`. If the audit log file exceeds the size you specify in `audit-log-maxsize`,
|
||||
Kubernetes will rename the current log file by appending the current timestamp on
|
||||
the file name (before the file extension) and create a new audit log file.
|
||||
Kubernetes may delete old log files when creating a new log file; you can configure
|
||||
how many files are retained and how old they can be by specifying the `audit-log-maxbackup`
|
||||
and `audit-log-maxage` options.
|
||||
[Auditing](/docs/concepts/cluster-administration/audit/)
|
||||
|
||||
@@ -85,9 +85,9 @@ See [APPENDIX](#appendix) for how to generate a client cert.
|
||||
The API server reads bearer tokens from a file when given the `--token-auth-file=SOMEFILE` option on the command line. Currently, tokens last indefinitely, and the token list cannot be
|
||||
changed without restarting API server.
|
||||
|
||||
The token file format is implemented in `plugin/pkg/auth/authenticator/token/tokenfile/...`
|
||||
and is a csv file with a minimum of 3 columns: token, user name, user uid, followed by
|
||||
optional group names. Note, if you have more than one group the column must be double quoted e.g.
|
||||
The token file is a csv file with a minimum of 3 columns: token, user name, user uid,
|
||||
followed by optional group names. Note, if you have more than one group the column must be
|
||||
double quoted e.g.
|
||||
|
||||
```conf
|
||||
token,user,uid,"group1,group2,group3"
|
||||
@@ -115,9 +115,9 @@ and the password cannot be changed without restarting API server. Note that basi
|
||||
authentication is currently supported for convenience while we finish making the
|
||||
more secure modes described above easier to use.
|
||||
|
||||
The basic auth file format is implemented in `plugin/pkg/auth/authenticator/password/passwordfile/...`
|
||||
and is a csv file with a minimum of 3 columns: password, user name, user id, followed by
|
||||
optional group names. Note, if you have more than one group the column must be double quoted e.g.
|
||||
The basic auth file is a csv file with a minimum of 3 columns: password,
|
||||
user name, user id, followed by optional group names. Note, if you have more than
|
||||
one group the column must be double quoted e.g.
|
||||
|
||||
```conf
|
||||
password,user,uid,"group1,group2,group3"
|
||||
@@ -250,11 +250,21 @@ To enable the plugin, configure the following flags on the API server:
|
||||
|
||||
| Parameter | Description | Example | Required |
|
||||
| --------- | ----------- | ------- | ------- |
|
||||
| --oidc-issuer-url | URL of the provider which allows the API server to discover public signing keys. Only URLs which use the `https://` scheme are accepted. This is typically the provider's discovery URL without a path, for example "https://accounts.google.com" or "https://login.salesforce.com". This URL should point to the level below .well-known/openid-configuration | If the discovery URL is https://accounts.google.com/.well-known/openid-configuration the value should be https://accounts.google.com | Yes |
|
||||
| --oidc-client-id | A client id that all tokens must be issued for. | kubernetes | Yes |
|
||||
| --oidc-username-claim | JWT claim to use as the user name. By default `sub`, which is expected to be a unique identifier of the end user. Admins can choose other claims, such as `email`, depending on their provider. | sub | No |
|
||||
| --oidc-groups-claim | JWT claim to use as the user's group. If the claim is present it must be an array of strings. | groups | No |
|
||||
| --oidc-ca-file | The path to the certificate for the CA that signed your identity provider's web certificate. Defaults to the host's root CAs. | `/etc/kubernetes/ssl/kc-ca.pem` | No |
|
||||
| `--oidc-issuer-url` | URL of the provider which allows the API server to discover public signing keys. Only URLs which use the `https://` scheme are accepted. This is typically the provider's discovery URL without a path, for example "https://accounts.google.com" or "https://login.salesforce.com". This URL should point to the level below .well-known/openid-configuration | If the discovery URL is https://accounts.google.com/.well-known/openid-configuration the value should be https://accounts.google.com | Yes |
|
||||
| `--oidc-client-id` | A client id that all tokens must be issued for. | kubernetes | Yes |
|
||||
| `--oidc-username-claim` | JWT claim to use as the user name. By default `sub`, which is expected to be a unique identifier of the end user. Admins can choose other claims, such as `email` or `name`, depending on their provider. However, claims other than `email` will be prefixed with the issuer URL to prevent naming clashes with other plugins. | sub | No |
|
||||
| `--oidc-groups-claim` | JWT claim to use as the user's group. If the claim is present it must be an array of strings. | groups | No |
|
||||
| `--oidc-ca-file` | The path to the certificate for the CA that signed your identity provider's web certificate. Defaults to the host's root CAs. | `/etc/kubernetes/ssl/kc-ca.pem` | No |
|
||||
|
||||
If a claim other than `email` is chosen for `--oidc-username-claim`, the value
|
||||
will be prefixed with the `--oidc-issuer-url` to prevent clashes with existing
|
||||
Kubernetes names (such as the `system:` users). For example, if the provider
|
||||
URL is `https://accounts.google.com` and the username claim maps to `jane`, the
|
||||
plugin will authenticate the user as:
|
||||
|
||||
```
|
||||
https://accounts.google.com#jane
|
||||
```
|
||||
|
||||
Importantly, the API server is not an OAuth2 client, rather it can only be
|
||||
configured to trust a single issuer. This allows the use of public providers,
|
||||
@@ -289,13 +299,14 @@ The first option is to use the `oidc` authenticator. This authenticator takes y
|
||||
|
||||
```bash
|
||||
kubectl config set-credentials USER_NAME \
|
||||
--auth-provider=oidc
|
||||
--auth-provider=oidc \
|
||||
--auth-provider-arg=idp-issuer-url=( issuer url ) \
|
||||
--auth-provider-arg=client-id=( your client id ) \
|
||||
--auth-provider-arg=client-secret=( your client secret ) \
|
||||
--auth-provider-arg=refresh-token=( your refresh token ) \
|
||||
--auth-provider-arg=idp-certificate-authority=( path to your ca certificate ) \
|
||||
--auth-provider-arg=id-token=( your id_token )
|
||||
--auth-provider-arg=id-token=( your id_token ) \
|
||||
--auth-provider-arg=extra-scopes=( comma separated list of scopes to add to "openid email profile", optional )
|
||||
```
|
||||
|
||||
As an example, running the below command after authenticating to your identity provider:
|
||||
@@ -308,6 +319,7 @@ kubectl config set-credentials mmosley \
|
||||
--auth-provider-arg=client-secret=1db158f6-177d-4d9c-8a8b-d36869918ec5 \
|
||||
--auth-provider-arg=refresh-token=q1bKLFOyUiosTfawzA93TzZIDzH2TNa2SMm0zEiPKTUwME6BkEo6Sql5yUWVBSWpKUGphaWpxSVAfekBOZbBhaEW+VlFUeVRGcluyVF5JT4+haZmPsluFoFu5XkpXk5BXqHega4GAXlF+ma+vmYpFcHe5eZR+slBFpZKtQA= \
|
||||
--auth-provider-arg=idp-certificate-authority=/root/ca.pem \
|
||||
--auth-provider-arg=extra-scopes=groups \
|
||||
--auth-provider-arg=id-token=eyJraWQiOiJDTj1vaWRjaWRwLnRyZW1vbG8ubGFuLCBPVT1EZW1vLCBPPVRybWVvbG8gU2VjdXJpdHksIEw9QXJsaW5ndG9uLCBTVD1WaXJnaW5pYSwgQz1VUy1DTj1rdWJlLWNhLTEyMDIxNDc5MjEwMzYwNzMyMTUyIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL29pZGNpZHAudHJlbW9sby5sYW46ODQ0My9hdXRoL2lkcC9PaWRjSWRQIiwiYXVkIjoia3ViZXJuZXRlcyIsImV4cCI6MTQ4MzU0OTUxMSwianRpIjoiMm96US15TXdFcHV4WDlHZUhQdy1hZyIsImlhdCI6MTQ4MzU0OTQ1MSwibmJmIjoxNDgzNTQ5MzMxLCJzdWIiOiI0YWViMzdiYS1iNjQ1LTQ4ZmQtYWIzMC0xYTAxZWU0MWUyMTgifQ.w6p4J_6qQ1HzTG9nrEOrubxIMb9K5hzcMPxc9IxPx2K4xO9l-oFiUw93daH3m5pluP6K7eOE6txBuRVfEcpJSwlelsOsW8gb8VJcnzMS9EnZpeA0tW_p-mnkFc3VcfyXuhe5R3G7aa5d8uHv70yJ9Y3-UhjiN9EhpMdfPAoEB9fYKKkJRzF7utTTIPGrSaSU6d2pcpfYKaxIwePzEkT4DfcQthoZdy9ucNvvLoi1DIC-UocFD8HLs8LYKEqSxQvOcvnThbObJ9af71EwmuE21fO5KzMW20KtAeget1gnldOosPtz1G5EwvaQ401-RPQzPGMVBld0_zMCAwZttJ4knw
|
||||
```
|
||||
|
||||
@@ -321,6 +333,7 @@ users:
|
||||
config:
|
||||
client-id: kubernetes
|
||||
client-secret: 1db158f6-177d-4d9c-8a8b-d36869918ec5
|
||||
extra-scopes: groups
|
||||
id-token: eyJraWQiOiJDTj1vaWRjaWRwLnRyZW1vbG8ubGFuLCBPVT1EZW1vLCBPPVRybWVvbG8gU2VjdXJpdHksIEw9QXJsaW5ndG9uLCBTVD1WaXJnaW5pYSwgQz1VUy1DTj1rdWJlLWNhLTEyMDIxNDc5MjEwMzYwNzMyMTUyIiwiYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL29pZGNpZHAudHJlbW9sby5sYW46ODQ0My9hdXRoL2lkcC9PaWRjSWRQIiwiYXVkIjoia3ViZXJuZXRlcyIsImV4cCI6MTQ4MzU0OTUxMSwianRpIjoiMm96US15TXdFcHV4WDlHZUhQdy1hZyIsImlhdCI6MTQ4MzU0OTQ1MSwibmJmIjoxNDgzNTQ5MzMxLCJzdWIiOiI0YWViMzdiYS1iNjQ1LTQ4ZmQtYWIzMC0xYTAxZWU0MWUyMTgifQ.w6p4J_6qQ1HzTG9nrEOrubxIMb9K5hzcMPxc9IxPx2K4xO9l-oFiUw93daH3m5pluP6K7eOE6txBuRVfEcpJSwlelsOsW8gb8VJcnzMS9EnZpeA0tW_p-mnkFc3VcfyXuhe5R3G7aa5d8uHv70yJ9Y3-UhjiN9EhpMdfPAoEB9fYKKkJRzF7utTTIPGrSaSU6d2pcpfYKaxIwePzEkT4DfcQthoZdy9ucNvvLoi1DIC-UocFD8HLs8LYKEqSxQvOcvnThbObJ9af71EwmuE21fO5KzMW20KtAeget1gnldOosPtz1G5EwvaQ401-RPQzPGMVBld0_zMCAwZttJ4knw
|
||||
idp-certificate-authority: /root/ca.pem
|
||||
idp-issuer-url: https://oidcidp.tremolo.lan:8443/auth/idp/OidcIdP
|
||||
@@ -346,7 +359,7 @@ Webhook authentication is a hook for verifying bearer tokens.
|
||||
* `--authentication-token-webhook-config-file` a kubeconfig file describing how to access the remote webhook service.
|
||||
* `--authentication-token-webhook-cache-ttl` how long to cache authentication decisions. Defaults to two minutes.
|
||||
|
||||
The configuration file uses the [kubeconfig](/docs/user-guide/kubeconfig-file/)
|
||||
The configuration file uses the [kubeconfig](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/)
|
||||
file format. Within the file "users" refers to the API server webhook and
|
||||
"clusters" refers to the remote service. An example would be:
|
||||
|
||||
@@ -541,8 +554,8 @@ Finally, add the following parameters into API server start parameters:
|
||||
1. Generate server certificate and key.
|
||||
(build-server-full [filename]: Generate a keypair and sign locally for a client or server)
|
||||
|
||||
./easyrsa --subject-alt-name="IP:${MASTER_IP}" build-server-full kubernetes-master nopass
|
||||
1. Copy `pki/ca.crt`, `pki/issued/kubernetes-master.crt`, and `pki/private/kubernetes-master.key` to your directory.
|
||||
./easyrsa --subject-alt-name="IP:${MASTER_IP}" build-server-full server nopass
|
||||
1. Copy `pki/ca.crt`, `pki/issued/server.crt`, and `pki/private/server.key` to your directory.
|
||||
1. Fill in and add the following parameters into the API server start parameters:
|
||||
|
||||
--client-ca-file=/yourdirectory/ca.crt
|
||||
|
||||
+31
-19
@@ -24,10 +24,9 @@ The following implementations are available, and are selected by flag:
|
||||
need authorization.
|
||||
- `--authorization-mode=ABAC` allows for a simple local-file-based user-configured
|
||||
authorization policy. ABAC stands for Attribute-Based Access Control.
|
||||
authorization policy.
|
||||
- `--authorization-mode=RBAC` is an experimental implementation which allows
|
||||
for authorization to be driven by the Kubernetes API.
|
||||
RBAC stands for Roles-Based Access Control.
|
||||
RBAC stands for Role-Based Access Control.
|
||||
- `--authorization-mode=Webhook` allows for authorization to be driven by a
|
||||
remote service using REST.
|
||||
|
||||
@@ -87,15 +86,25 @@ properties:
|
||||
- Subject-matching properties:
|
||||
- `user`, type string; the user-string from `--token-auth-file`. If you specify `user`, it must match the username of the authenticated user.
|
||||
- `group`, type string; if you specify `group`, it must match one of the groups of the authenticated user. `system:authenticated` matches all authenticated requests. `system:unauthenticated` matches all unauthenticated requests.
|
||||
- `readonly`, type boolean, when true, means that the policy only applies to get, list, and watch operations.
|
||||
- Resource-matching properties:
|
||||
- `apiGroup`, type string; an API group, such as `extensions`. `*` matches all API groups.
|
||||
- `namespace`, type string; a namespace string. `*` matches all resource requests.
|
||||
- `resource`, type string; a resource, such as `pods`. `*` matches all resource requests.
|
||||
- `apiGroup`, type string; an API group.
|
||||
- Ex: `extensions`
|
||||
- Wildcard: `*` matches all API groups.
|
||||
- `namespace`, type string; a namespace.
|
||||
- Ex: `kube-system`
|
||||
- Wildcard: `*` matches all resource requests.
|
||||
- `resource`, type string; a resource type
|
||||
- Ex: `pods`
|
||||
- Wildcard: `*` matches all resource requests.
|
||||
- Non-resource-matching properties:
|
||||
- `nonResourcePath`, type string; matches the non-resource request paths (like `/version` and `/apis`). `*` matches all non-resource requests. `/foo/*` matches `/foo/` and all of its subpaths.
|
||||
- `nonResourcePath`, type string; non-resource request paths.
|
||||
- Ex: `/version` or `/apis`
|
||||
- Wildcard:
|
||||
- `*` matches all non-resource requests.
|
||||
- `/foo/*` matches `/foo/` and all of its subpaths.
|
||||
- `readonly`, type boolean, when true, means that the policy only applies to get, list, and watch operations.
|
||||
|
||||
An unset property is the same as a property set to the zero value for its type
|
||||
**NOTES:** An unset property is the same as a property set to the zero value for its type
|
||||
(e.g. empty string, 0, false). However, unset should be preferred for
|
||||
readability.
|
||||
|
||||
@@ -221,20 +230,20 @@ don't already have even when the RBAC authorizer it disabled__. If "user-1"
|
||||
does not have the ability to read secrets in "namespace-a", they cannot create
|
||||
a binding that would grant that permission to themselves or any other user.
|
||||
|
||||
For bootstrapping the first roles, it becomes necessary for someone to get
|
||||
around these limitations. For the alpha release of RBAC, an API Server flag was
|
||||
added to allow one user to step around all RBAC authorization and privilege
|
||||
escalation checks. NOTE: _This is subject to change with future releases._
|
||||
When bootstrapping, superuser credentials should include the `system:masters`
|
||||
group, for example by creating a client cert with `/O=system:masters`. This
|
||||
gives those credentials full access to the API and allows an admin to then set
|
||||
up bindings for other users.
|
||||
|
||||
In Kubernetes versions 1.4 and 1.5, there was a similar flag that gave a user
|
||||
full access:
|
||||
|
||||
```
|
||||
--authorization-rbac-super-user=admin
|
||||
```
|
||||
|
||||
Once set the specified super user, in this case "admin", can be used to create
|
||||
the roles and role bindings to initialize the system.
|
||||
|
||||
This flag is optional and once the initial bootstrapping is performed can be
|
||||
unset.
|
||||
__This flag will be removed in 1.6__. Admins should prefer the `system:masters`
|
||||
group when setting up clusters.
|
||||
|
||||
### Roles, RolesBindings, ClusterRoles, and ClusterRoleBindings
|
||||
|
||||
@@ -445,6 +454,7 @@ subjects:
|
||||
```
|
||||
|
||||
For all authenticated users:
|
||||
|
||||
```yaml
|
||||
subjects:
|
||||
- kind: Group
|
||||
@@ -452,6 +462,7 @@ subjects:
|
||||
```
|
||||
|
||||
For all unauthenticated users:
|
||||
|
||||
```yaml
|
||||
subjects:
|
||||
- kind: Group
|
||||
@@ -459,6 +470,7 @@ subjects:
|
||||
```
|
||||
|
||||
For all users:
|
||||
|
||||
```yaml
|
||||
subjects:
|
||||
- kind: Group
|
||||
@@ -477,7 +489,7 @@ service when determining user privileges.
|
||||
Mode `Webhook` requires a file for HTTP configuration, specify by the
|
||||
`--authorization-webhook-config-file=SOME_FILENAME` flag.
|
||||
|
||||
The configuration file uses the [kubeconfig](/docs/user-guide/kubeconfig-file/)
|
||||
The configuration file uses the [kubeconfig](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/)
|
||||
file format. Within the file "users" refers to the API Server webhook and
|
||||
"clusters" refers to the remote service.
|
||||
|
||||
@@ -503,7 +515,7 @@ current-context: webhook
|
||||
contexts:
|
||||
- context:
|
||||
cluster: name-of-remote-authz-service
|
||||
user: name-of-api-sever
|
||||
user: name-of-api-server
|
||||
name: webhook
|
||||
```
|
||||
|
||||
|
||||
@@ -4,133 +4,6 @@ assignees:
|
||||
title: Kubernetes Components
|
||||
---
|
||||
|
||||
This document outlines the various binary components that need to run to
|
||||
deliver a functioning Kubernetes cluster.
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
## Master Components
|
||||
|
||||
Master components are those that provide the cluster's control plane. For
|
||||
example, master components are responsible for making global decisions about the
|
||||
cluster (e.g., scheduling), and detecting and responding to cluster events
|
||||
(e.g., starting up a new pod when a replication controller's 'replicas' field is
|
||||
unsatisfied).
|
||||
|
||||
Master components could in theory be run on any node in the cluster. However,
|
||||
for simplicity, current set up scripts typically start all master components on
|
||||
the same VM, and does not run user containers on this VM. See
|
||||
[high-availability.md](/docs/admin/high-availability) for an example multi-master-VM setup.
|
||||
|
||||
Even in the future, when Kubernetes is fully self-hosting, it will probably be
|
||||
wise to only allow master components to schedule on a subset of nodes, to limit
|
||||
co-running with user-run pods, reducing the possible scope of a
|
||||
node-compromising security exploit.
|
||||
|
||||
### kube-apiserver
|
||||
|
||||
[kube-apiserver](/docs/admin/kube-apiserver) exposes the Kubernetes API; it is the front-end for the
|
||||
Kubernetes control plane. It is designed to scale horizontally (i.e., one scales
|
||||
it by running more of them-- [high-availability.md](/docs/admin/high-availability)).
|
||||
|
||||
### etcd
|
||||
|
||||
[etcd](/docs/admin/etcd) is used as Kubernetes' backing store. All cluster data is stored here.
|
||||
Proper administration of a Kubernetes cluster includes a backup plan for etcd's
|
||||
data.
|
||||
|
||||
### kube-controller-manager
|
||||
|
||||
[kube-controller-manager](/docs/admin/kube-controller-manager) is a binary that runs controllers, which are the
|
||||
background threads that handle routine tasks in the cluster. Logically, each
|
||||
controller is a separate process, but to reduce the number of moving pieces in
|
||||
the system, they are all compiled into a single binary and run in a single
|
||||
process.
|
||||
|
||||
These controllers include:
|
||||
|
||||
* Node Controller: Responsible for noticing & responding when nodes go down.
|
||||
* Replication Controller: Responsible for maintaining the correct number of pods for every replication
|
||||
controller object in the system.
|
||||
* Endpoints Controller: Populates the Endpoints object (i.e., join Services & Pods).
|
||||
* Service Account & Token Controllers: Create default accounts and API access tokens for new namespaces.
|
||||
* ... and others.
|
||||
|
||||
### kube-scheduler
|
||||
|
||||
[kube-scheduler](/docs/admin/kube-scheduler) watches newly created pods that have no node assigned, and
|
||||
selects a node for them to run on.
|
||||
|
||||
### addons
|
||||
|
||||
Addons are pods and services that implement cluster features. The pods may be managed
|
||||
by Deployments, ReplicationContollers, etc. Namespaced addon objects are created in
|
||||
the "kube-system" namespace.
|
||||
|
||||
Addon manager takes the responsibility for creating and maintaining addon resources.
|
||||
See [here](http://releases.k8s.io/HEAD/cluster/addons) for more details.
|
||||
|
||||
#### DNS
|
||||
|
||||
While the other addons are not strictly required, all Kubernetes
|
||||
clusters should have [cluster DNS](/docs/admin/dns/), as many examples rely on it.
|
||||
|
||||
Cluster DNS is a DNS server, in addition to the other DNS server(s) in your
|
||||
environment, which serves DNS records for Kubernetes services.
|
||||
|
||||
Containers started by Kubernetes automatically include this DNS server
|
||||
in their DNS searches.
|
||||
|
||||
#### User interface
|
||||
|
||||
The kube-ui provides a read-only overview of the cluster state. Access
|
||||
[the UI using kubectl proxy](/docs/user-guide/connecting-to-applications-proxy/#connecting-to-the-kube-ui-service-from-your-local-workstation)
|
||||
|
||||
#### Container Resource Monitoring
|
||||
|
||||
[Container Resource Monitoring](/docs/user-guide/monitoring) records generic time-series metrics
|
||||
about containers in a central database, and provides a UI for browsing that data.
|
||||
|
||||
#### Cluster-level Logging
|
||||
|
||||
A [Cluster-level logging](/docs/user-guide/logging/overview) mechanism is responsible for
|
||||
saving container logs to a central log store with search/browsing interface.
|
||||
|
||||
## Node components
|
||||
|
||||
Node components run on every node, maintaining running pods and providing them
|
||||
the Kubernetes runtime environment.
|
||||
|
||||
### kubelet
|
||||
|
||||
[kubelet](/docs/admin/kubelet) is the primary node agent. It:
|
||||
|
||||
* Watches for pods that have been assigned to its node (either by apiserver
|
||||
or via local configuration file) and:
|
||||
* Mounts the pod's required volumes
|
||||
* Downloads the pod's secrets
|
||||
* Runs the pod's containers via docker (or, experimentally, rkt).
|
||||
* Periodically executes any requested container liveness probes.
|
||||
* Reports the status of the pod back to the rest of the system, by creating a
|
||||
"mirror pod" if necessary.
|
||||
* Reports the status of the node back to the rest of the system.
|
||||
|
||||
### kube-proxy
|
||||
|
||||
[kube-proxy](/docs/admin/kube-proxy) enables the Kubernetes service abstraction by maintaining
|
||||
network rules on the host and performing connection forwarding.
|
||||
|
||||
### docker
|
||||
|
||||
`docker` is of course used for actually running containers.
|
||||
|
||||
### rkt
|
||||
|
||||
`rkt` is supported experimentally as an alternative to docker.
|
||||
|
||||
### supervisord
|
||||
|
||||
`supervisord` is a lightweight process babysitting system for keeping kubelet and docker
|
||||
running.
|
||||
|
||||
### fluentd
|
||||
|
||||
`fluentd` is a daemon which helps provide [cluster-level logging](#cluster-level-logging).
|
||||
[Kubernetes Components](/docs/concepts/overview/components/)
|
||||
|
||||
@@ -19,7 +19,9 @@ To install Kubernetes on a set of machines, consult one of the existing [Getting
|
||||
|
||||
## Upgrading a cluster
|
||||
|
||||
The current state of cluster upgrades is provider dependent.
|
||||
The current state of cluster upgrades is provider dependent, and some releases may require special care when upgrading. It is recommended that administrators consult both the [release notes](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md), as well as the version specific upgrade notes prior to upgrading their clusters.
|
||||
|
||||
* [Upgrading to 1.6](/docs/admin/upgrade-1-6)
|
||||
|
||||
### Upgrading Google Compute Engine clusters
|
||||
|
||||
@@ -56,8 +58,12 @@ The node upgrade process is user-initiated and is described in the [GKE document
|
||||
|
||||
### Upgrading clusters on other platforms
|
||||
|
||||
The `cluster/kube-push.sh` script will do a rudimentary update. This process is still quite experimental, we
|
||||
recommend testing the upgrade on an experimental cluster before performing the update on a production cluster.
|
||||
Different providers, and tools, will manage upgrades differently. It is recommended that you consult their main documentation regarding upgrades.
|
||||
|
||||
* [kops](https://github.com/kubernetes/kops)
|
||||
* [kargo](https://github.com/kubernetes-incubator/kargo)
|
||||
* [CoreOS Tectonic](https://coreos.com/tectonic/docs/latest/admin/upgrade.html)
|
||||
* ...
|
||||
|
||||
## Resizing a cluster
|
||||
|
||||
@@ -72,7 +78,6 @@ Instance Group will take care of putting appropriate image on new machines and s
|
||||
|
||||
In other environments you may need to configure the machine yourself and tell the Kubelet on which machine API server is running.
|
||||
|
||||
|
||||
### Cluster autoscaling
|
||||
|
||||
If you are using GCE or GKE, you can configure your cluster so that it is automatically rescaled based on
|
||||
@@ -91,8 +96,8 @@ an extended period of time (10min but it may change in the future).
|
||||
|
||||
Cluster autoscaler is configured per instance group (GCE) or node pool (GKE).
|
||||
|
||||
If you are using GCE then you can either enable it while creating a cluster with kube-up.sh script.
|
||||
To configure cluster autoscaler you have to set 3 environment variables:
|
||||
If you are using GCE then you can either enable it while creating a cluster with kube-up.sh script.
|
||||
To configure cluster autoscaler you have to set three environment variables:
|
||||
|
||||
* `KUBE_ENABLE_CLUSTER_AUTOSCALER` - it enables cluster autoscaler if set to true.
|
||||
* `KUBE_AUTOSCALER_MIN_NODES` - minimum number of nodes in the cluster.
|
||||
@@ -190,7 +195,7 @@ for changes to this variable to take effect.
|
||||
You can use `kubectl convert` command to convert config files between different API versions.
|
||||
|
||||
```shell
|
||||
$ kubectl convert -f pod.yaml --output-version v1
|
||||
kubectl convert -f pod.yaml --output-version v1
|
||||
```
|
||||
|
||||
For more options, please refer to the usage of [kubectl convert](/docs/user-guide/kubectl/kubectl_convert/) command.
|
||||
|
||||
@@ -21,8 +21,8 @@ Some typical uses of a DaemonSet are:
|
||||
https://github.com/prometheus/node_exporter), `collectd`, New Relic agent, or Ganglia `gmond`.
|
||||
|
||||
In a simple case, one DaemonSet, covering all nodes, would be used for each type of daemon.
|
||||
A more complex setup might use multiple DaemonSets would be used for a single type of daemon,
|
||||
but with different flags and/or different memory and cpu requests for different hardware types.
|
||||
A more complex setup might use multiple DaemonSets for a single type of daemon, but with
|
||||
different flags and/or different memory and cpu requests for different hardware types.
|
||||
|
||||
## Writing a DaemonSet Spec
|
||||
|
||||
@@ -51,7 +51,7 @@ A pod template in a DaemonSet must have a [`RestartPolicy`](/docs/user-guide/pod
|
||||
### Pod Selector
|
||||
|
||||
The `.spec.selector` field is a pod selector. It works the same as the `.spec.selector` of
|
||||
a [Job](/docs/user-guide/jobs/) or other new resources.
|
||||
a [Job](/docs/concepts/jobs/run-to-completion-finite-workloads/) or other new resources.
|
||||
|
||||
The `spec.selector` is an object consisting of two fields:
|
||||
|
||||
|
||||
@@ -3,93 +3,7 @@ assignees:
|
||||
- davidopp
|
||||
title: Pod Disruption Budget
|
||||
---
|
||||
This guide is for anyone wishing to specify safety constraints on pods or anyone
|
||||
wishing to write software (typically automation software) that respects those
|
||||
constraints.
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
## Rationale
|
||||
|
||||
Various cluster management operations may voluntarily evict pods. "Voluntary"
|
||||
means an eviction can be safely delayed for a reasonable period of time. The
|
||||
principal examples today are draining a node for maintenance or upgrade
|
||||
(`kubectl drain`), and cluster autoscaling down. In the future the
|
||||
[rescheduler](https://github.com/kubernetes/kubernetes/blob/master/docs/proposals/rescheduling.md)
|
||||
may also perform voluntary evictions. By contrast, something like evicting pods
|
||||
because a node has become unreachable or reports `NotReady`, is not "voluntary."
|
||||
|
||||
For voluntary evictions, it can be useful for applications to be able to limit
|
||||
the number of pods that are down simultaneously. For example, a quorum-based application would
|
||||
like to ensure that the number of replicas running is never brought below the
|
||||
number needed for a quorum, even temporarily. Or a web front end might want to
|
||||
ensure that the number of replicas serving load never falls below a certain
|
||||
percentage of the total, even briefly. `PodDisruptionBudget` is an API object
|
||||
that specifies the minimum number or percentage of replicas of a collection that
|
||||
must be up at a time. Components that wish to evict a pod subject to disruption
|
||||
budget use the `/eviction` subresource; unlike a regular pod deletion, this
|
||||
operation may be rejected by the API server if the eviction would cause a
|
||||
disruption budget to be violated.
|
||||
|
||||
## Specifying a PodDisruptionBudget
|
||||
|
||||
A `PodDisruptionBudget` has two components: a label selector `selector` to specify the set of
|
||||
pods to which it applies, and `minAvailable` which is a description of the number of pods from that
|
||||
set that must still be available after the eviction, i.e. even in the absence
|
||||
of the evicted pod. `minAvailable` can be either an absolute number or a percentage.
|
||||
So for example, 100% means no voluntary evictions from the set are permitted. In
|
||||
typical usage, a single budget would be used for a collection of pods managed by
|
||||
a controller—for example, the pods in a single ReplicaSet.
|
||||
|
||||
Note that a disruption budget does not truly guarantee that the specified
|
||||
number/percentage of pods will always be up. For example, a node that hosts a
|
||||
pod from the collection may fail when the collection is at the minimum size
|
||||
specified in the budget, thus bringing the number of available pods from the
|
||||
collection below the specified size. The budget can only protect against
|
||||
voluntary evictions, not all causes of unavailability.
|
||||
|
||||
## Requesting an eviction
|
||||
|
||||
If you are writing infrastructure software that wants to produce these voluntary
|
||||
evictions, you will need to use the eviction API. The eviction subresource of a
|
||||
pod can be thought of as a kind of policy-controlled DELETE operation on the pod
|
||||
itself. To attempt an eviction (perhaps more REST-precisely, to attempt to
|
||||
*create* an eviction), you POST an attempted operation. Here's an example:
|
||||
|
||||
```json
|
||||
{
|
||||
"apiVersion": "policy/v1beta1",
|
||||
"kind": "Eviction",
|
||||
"metadata": {
|
||||
"name": "quux",
|
||||
"namespace": "default"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
You can attempt an eviction using `curl`:
|
||||
|
||||
```bash
|
||||
$ curl -v -H 'Content-type: application/json' http://127.0.0.1:8080/api/v1/namespaces/default/pods/quux/eviction -d @eviction.json
|
||||
```
|
||||
|
||||
The API can respond in one of three ways.
|
||||
|
||||
1. If the eviction is granted, then the pod is deleted just as if you had sent
|
||||
a `DELETE` request to the pod's URL and you get back `200 OK`.
|
||||
2. If the current state of affairs wouldn't allow an eviction by the rules set
|
||||
forth in the budget, you get back `429 Too Many Requests`. This is
|
||||
typically used for generic rate limiting of *any* requests, but here we mean
|
||||
that this request isn't allowed *right now* but it may be allowed later.
|
||||
Currently, callers do not get any `Retry-After` advice, but they may in
|
||||
future versions.
|
||||
3. If there is some kind of misconfiguration, like multiple budgets pointing at
|
||||
the same pod, you will get `500 Internal Server Error`.
|
||||
|
||||
For a given eviction request, there are two cases.
|
||||
|
||||
1. There is no budget that matches this pod. In this case, the server always
|
||||
returns `200 OK`.
|
||||
2. There is at least one budget. In this case, any of the three above responses may
|
||||
apply.
|
||||
[Configuring a Pod Disruption Budget](/docs/tasks/configure-pod-container/configure-pod-disruption-budget/)
|
||||
|
||||
+2
-381
@@ -5,385 +5,6 @@ assignees:
|
||||
title: Using DNS Pods and Services
|
||||
---
|
||||
|
||||
## Introduction
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
As of Kubernetes 1.3, DNS is a built-in service launched automatically using the addon manager [cluster add-on](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/README.md).
|
||||
|
||||
Kubernetes DNS schedules a DNS Pod and Service on the cluster, and configures
|
||||
the kubelets to tell individual containers to use the DNS Service's IP to
|
||||
resolve DNS names.
|
||||
|
||||
## What things get DNS names?
|
||||
|
||||
Every Service defined in the cluster (including the DNS server itself) is
|
||||
assigned a DNS name. By default, a client Pod's DNS search list will
|
||||
include the Pod's own namespace and the cluster's default domain. This is best
|
||||
illustrated by example:
|
||||
|
||||
Assume a Service named `foo` in the Kubernetes namespace `bar`. A Pod running
|
||||
in namespace `bar` can look up this service by simply doing a DNS query for
|
||||
`foo`. A Pod running in namespace `quux` can look up this service by doing a
|
||||
DNS query for `foo.bar`.
|
||||
|
||||
## Supported DNS schema
|
||||
|
||||
The following sections detail the supported record types and layout that is
|
||||
supported. Any other layout or names or queries that happen to work are
|
||||
considered implementation details and are subject to change without warning.
|
||||
|
||||
### Services
|
||||
|
||||
#### A records
|
||||
|
||||
"Normal" (not headless) Services are assigned a DNS A record for a name of the
|
||||
form `my-svc.my-namespace.svc.cluster.local`. This resolves to the cluster IP
|
||||
of the Service.
|
||||
|
||||
"Headless" (without a cluster IP) Services are also assigned a DNS A record for
|
||||
a name of the form `my-svc.my-namespace.svc.cluster.local`. Unlike normal
|
||||
Services, this resolves to the set of IPs of the pods selected by the Service.
|
||||
Clients are expected to consume the set or else use standard round-robin
|
||||
selection from the set.
|
||||
|
||||
### SRV records
|
||||
|
||||
SRV Records are created for named ports that are part of normal or [Headless
|
||||
Services](http://releases.k8s.io/docs/user-guide/services/#headless-services).
|
||||
For each named port, the SRV record would have the form
|
||||
`_my-port-name._my-port-protocol.my-svc.my-namespace.svc.cluster.local`.
|
||||
For a regular service, this resolves to the port number and the CNAME:
|
||||
`my-svc.my-namespace.svc.cluster.local`.
|
||||
For a headless service, this resolves to multiple answers, one for each pod
|
||||
that is backing the service, and contains the port number and a CNAME of the pod
|
||||
of the form `auto-generated-name.my-svc.my-namespace.svc.cluster.local`.
|
||||
|
||||
### Backwards compatibility
|
||||
|
||||
Previous versions of kube-dns made names of the form
|
||||
`my-svc.my-namespace.cluster.local` (the 'svc' level was added later). This
|
||||
is no longer supported.
|
||||
|
||||
### Pods
|
||||
|
||||
#### A Records
|
||||
|
||||
When enabled, pods are assigned a DNS A record in the form of `pod-ip-address.my-namespace.pod.cluster.local`.
|
||||
|
||||
For example, a pod with IP `1.2.3.4` in the namespace `default` with a DNS name of `cluster.local` would have an entry: `1-2-3-4.default.pod.cluster.local`.
|
||||
|
||||
#### A Records and hostname based on Pod's hostname and subdomain fields
|
||||
|
||||
Currently when a pod is created, its hostname is the Pod's `metadata.name` value.
|
||||
|
||||
With v1.2, users can specify a Pod annotation, `pod.beta.kubernetes.io/hostname`, to specify what the Pod's hostname should be.
|
||||
The Pod annotation, if specified, takes precedence over the Pod's name, to be the hostname of the pod.
|
||||
For example, given a Pod with annotation `pod.beta.kubernetes.io/hostname: my-pod-name`, the Pod will have its hostname set to "my-pod-name".
|
||||
|
||||
With v1.3, the PodSpec has a `hostname` field, which can be used to specify the Pod's hostname. This field value takes precedence over the
|
||||
`pod.beta.kubernetes.io/hostname` annotation value.
|
||||
|
||||
v1.2 introduces a beta feature where the user can specify a Pod annotation, `pod.beta.kubernetes.io/subdomain`, to specify the Pod's subdomain.
|
||||
The final domain will be "<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>".
|
||||
For example, a Pod with the hostname annotation set to "foo", and the subdomain annotation set to "bar", in namespace "my-namespace", will have the FQDN "foo.bar.my-namespace.svc.cluster.local"
|
||||
|
||||
With v1.3, the PodSpec has a `subdomain` field, which can be used to specify the Pod's subdomain. This field value takes precedence over the
|
||||
`pod.beta.kubernetes.io/subdomain` annotation value.
|
||||
|
||||
Example:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: default-subdomain
|
||||
spec:
|
||||
selector:
|
||||
name: busybox
|
||||
clusterIP: None
|
||||
ports:
|
||||
- name: foo # Actually, no port is needed.
|
||||
port: 1234
|
||||
targetPort: 1234
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: busybox1
|
||||
labels:
|
||||
name: busybox
|
||||
spec:
|
||||
hostname: busybox-1
|
||||
subdomain: default-subdomain
|
||||
containers:
|
||||
- image: busybox
|
||||
command:
|
||||
- sleep
|
||||
- "3600"
|
||||
name: busybox
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: busybox2
|
||||
labels:
|
||||
name: busybox
|
||||
spec:
|
||||
hostname: busybox-2
|
||||
subdomain: default-subdomain
|
||||
containers:
|
||||
- image: busybox
|
||||
command:
|
||||
- sleep
|
||||
- "3600"
|
||||
name: busybox
|
||||
```
|
||||
|
||||
If there exists a headless service in the same namespace as the pod and with the same name as the subdomain, the cluster's KubeDNS Server also returns an A record for the Pod's fully qualified hostname.
|
||||
Given a Pod with the hostname set to "busybox-1" and the subdomain set to "default-subdomain", and a headless Service named "default-subdomain" in the same namespace, the pod will see it's own FQDN as "busybox-1.default-subdomain.my-namespace.svc.cluster.local". DNS serves an A record at that name, pointing to the Pod's IP. Both pods "busybox1" and "busybox2" can have their distinct A records.
|
||||
|
||||
As of Kubernetes v1.2, the Endpoints object also has the annotation `endpoints.beta.kubernetes.io/hostnames-map`. Its value is the json representation of map[string(IP)][endpoints.HostRecord], for example: '{"10.245.1.6":{HostName: "my-webserver"}}'.
|
||||
If the Endpoints are for a headless service, an A record is created with the format <hostname>.<service name>.<pod namespace>.svc.<cluster domain>
|
||||
For the example json, if endpoints are for a headless service named "bar", and one of the endpoints has IP "10.245.1.6", an A record is created with the name "my-webserver.bar.my-namespace.svc.cluster.local" and the A record lookup would return "10.245.1.6".
|
||||
This endpoints annotation generally does not need to be specified by end-users, but can used by the internal service controller to deliver the aforementioned feature.
|
||||
|
||||
With v1.3, The Endpoints object can specify the `hostname` for any endpoint, along with its IP. The hostname field takes precedence over the hostname value
|
||||
that might have been specified via the `endpoints.beta.kubernetes.io/hostnames-map` annotation.
|
||||
|
||||
With v1.3, the following annotations are deprecated: `pod.beta.kubernetes.io/hostname`, `pod.beta.kubernetes.io/subdomain`, `endpoints.beta.kubernetes.io/hostnames-map`
|
||||
|
||||
## How do I test if it is working?
|
||||
|
||||
### Create a simple Pod to use as a test environment
|
||||
|
||||
Create a file named busybox.yaml with the
|
||||
following contents:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: busybox
|
||||
namespace: default
|
||||
spec:
|
||||
containers:
|
||||
- image: busybox
|
||||
command:
|
||||
- sleep
|
||||
- "3600"
|
||||
imagePullPolicy: IfNotPresent
|
||||
name: busybox
|
||||
restartPolicy: Always
|
||||
```
|
||||
|
||||
Then create a pod using this file:
|
||||
|
||||
```
|
||||
kubectl create -f busybox.yaml
|
||||
```
|
||||
|
||||
### Wait for this pod to go into the running state
|
||||
|
||||
You can get its status with:
|
||||
```
|
||||
kubectl get pods busybox
|
||||
```
|
||||
|
||||
You should see:
|
||||
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
busybox 1/1 Running 0 <some-time>
|
||||
```
|
||||
|
||||
### Validate that DNS is working
|
||||
|
||||
Once that pod is running, you can exec nslookup in that environment:
|
||||
|
||||
```
|
||||
kubectl exec -ti busybox -- nslookup kubernetes.default
|
||||
```
|
||||
|
||||
You should see something like:
|
||||
|
||||
```
|
||||
Server: 10.0.0.10
|
||||
Address 1: 10.0.0.10
|
||||
|
||||
Name: kubernetes.default
|
||||
Address 1: 10.0.0.1
|
||||
```
|
||||
|
||||
If you see that, DNS is working correctly.
|
||||
|
||||
### Troubleshooting Tips
|
||||
|
||||
If the nslookup command fails, check the following:
|
||||
|
||||
#### Check the local DNS configuration first
|
||||
Take a look inside the resolv.conf file. (See "Inheriting DNS from the node" and "Known issues" below for more information)
|
||||
|
||||
```
|
||||
kubectl exec busybox cat /etc/resolv.conf
|
||||
```
|
||||
|
||||
Verify that the search path and name server are set up like the following (note that search path may vary for different cloud providers):
|
||||
|
||||
```
|
||||
search default.svc.cluster.local svc.cluster.local cluster.local google.internal c.gce_project_id.internal
|
||||
nameserver 10.0.0.10
|
||||
options ndots:5
|
||||
```
|
||||
|
||||
#### Quick diagnosis
|
||||
|
||||
Errors such as the following indicate a problem with the kube-dns add-on or associated Services:
|
||||
|
||||
```
|
||||
$ kubectl exec -ti busybox -- nslookup kubernetes.default
|
||||
Server: 10.0.0.10
|
||||
Address 1: 10.0.0.10
|
||||
|
||||
nslookup: can't resolve 'kubernetes.default'
|
||||
```
|
||||
|
||||
or
|
||||
|
||||
```
|
||||
$ kubectl exec -ti busybox -- nslookup kubernetes.default
|
||||
Server: 10.0.0.10
|
||||
Address 1: 10.0.0.10 kube-dns.kube-system.svc.cluster.local
|
||||
|
||||
nslookup: can't resolve 'kubernetes.default'
|
||||
```
|
||||
|
||||
#### Check if the DNS pod is running
|
||||
|
||||
Use the kubectl get pods command to verify that the DNS pod is running.
|
||||
|
||||
```
|
||||
kubectl get pods --namespace=kube-system -l k8s-app=kube-dns
|
||||
```
|
||||
|
||||
You should see something like:
|
||||
|
||||
```
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
...
|
||||
kube-dns-v19-ezo1y 3/3 Running 0 1h
|
||||
...
|
||||
```
|
||||
|
||||
If you see that no pod is running or that the pod has failed/completed, the DNS add-on may not be deployed by default in your current environment and you will have to deploy it manually.
|
||||
|
||||
#### Check for Errors in the DNS pod
|
||||
|
||||
Use `kubectl logs` command to see logs for the DNS daemons.
|
||||
|
||||
```
|
||||
kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c kubedns
|
||||
kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c dnsmasq
|
||||
kubectl logs --namespace=kube-system $(kubectl get pods --namespace=kube-system -l k8s-app=kube-dns -o name) -c healthz
|
||||
```
|
||||
|
||||
See if there is any suspicious log. W, E, F letter at the beginning represent Warning, Error and Failure. Please search for entries that have these as the logging level and use [kubernetes issues](https://github.com/kubernetes/kubernetes/issues) to report unexpected errors.
|
||||
|
||||
#### Is DNS service up?
|
||||
|
||||
Verify that the DNS service is up by using the `kubectl get service` command.
|
||||
|
||||
```
|
||||
kubectl get svc --namespace=kube-system
|
||||
```
|
||||
|
||||
You should see:
|
||||
|
||||
```
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
...
|
||||
kube-dns 10.0.0.10 <none> 53/UDP,53/TCP 1h
|
||||
...
|
||||
```
|
||||
|
||||
If you have created the service or in the case it should be created by default but it does not appear, see this [debugging services page](http://kubernetes.io/docs/user-guide/debugging-services/) for more information.
|
||||
|
||||
#### Are DNS endpoints exposed?
|
||||
|
||||
You can verify that DNS endpoints are exposed by using the `kubectl get endpoints` command.
|
||||
|
||||
```
|
||||
kubectl get ep kube-dns --namespace=kube-system
|
||||
```
|
||||
|
||||
You should see something like:
|
||||
```
|
||||
NAME ENDPOINTS AGE
|
||||
kube-dns 10.180.3.17:53,10.180.3.17:53 1h
|
||||
```
|
||||
|
||||
If you do not see the endpoints, see endpoints section in the [debugging services documentation](http://kubernetes.io/docs/user-guide/debugging-services/).
|
||||
|
||||
For additional Kubernetes DNS examples, see the [cluster-dns examples](https://github.com/kubernetes/kubernetes/tree/master/examples/cluster-dns) in the Kubernetes GitHub repository.
|
||||
|
||||
## Kubernetes Federation (Multiple Zone support)
|
||||
|
||||
Release 1.3 introduced Cluster Federation support for multi-site
|
||||
Kubernetes installations. This required some minor
|
||||
(backward-compatible) changes to the way
|
||||
the Kubernetes cluster DNS server processes DNS queries, to facilitate
|
||||
the lookup of federated services (which span multiple Kubernetes clusters).
|
||||
See the [Cluster Federation Administrators' Guide](/docs/admin/federation) for more
|
||||
details on Cluster Federation and multi-site support.
|
||||
|
||||
## How it Works
|
||||
|
||||
The running Kubernetes DNS pod holds 3 containers - kubedns, dnsmasq and a health check called healthz.
|
||||
The kubedns process watches the Kubernetes master for changes in Services and Endpoints, and maintains
|
||||
in-memory lookup structures to service DNS requests. The dnsmasq container adds DNS caching to improve
|
||||
performance. The healthz container provides a single health check endpoint while performing dual healthchecks
|
||||
(for dnsmasq and kubedns).
|
||||
|
||||
The DNS pod is exposed as a Kubernetes Service with a static IP. Once assigned the
|
||||
kubelet passes DNS configured using the `--cluster-dns=10.0.0.10` flag to each
|
||||
container.
|
||||
|
||||
DNS names also need domains. The local domain is configurable, in the kubelet using
|
||||
the flag `--cluster-domain=<default local domain>`
|
||||
|
||||
The Kubernetes cluster DNS server (based off the [SkyDNS](https://github.com/skynetservices/skydns) library)
|
||||
supports forward lookups (A records), service lookups (SRV records) and reverse IP address lookups (PTR records).
|
||||
|
||||
## Inheriting DNS from the node
|
||||
When running a pod, kubelet will prepend the cluster DNS server and search
|
||||
paths to the node's own DNS settings. If the node is able to resolve DNS names
|
||||
specific to the larger environment, pods should be able to, also. See "Known
|
||||
issues" below for a caveat.
|
||||
|
||||
If you don't want this, or if you want a different DNS config for pods, you can
|
||||
use the kubelet's `--resolv-conf` flag. Setting it to "" means that pods will
|
||||
not inherit DNS. Setting it to a valid file path means that kubelet will use
|
||||
this file instead of `/etc/resolv.conf` for DNS inheritance.
|
||||
|
||||
## Known issues
|
||||
Kubernetes installs do not configure the nodes' resolv.conf files to use the
|
||||
cluster DNS by default, because that process is inherently distro-specific.
|
||||
This should probably be implemented eventually.
|
||||
|
||||
Linux's libc is impossibly stuck ([see this bug from
|
||||
2005](https://bugzilla.redhat.com/show_bug.cgi?id=168253)) with limits of just
|
||||
3 DNS `nameserver` records and 6 DNS `search` records. Kubernetes needs to
|
||||
consume 1 `nameserver` record and 3 `search` records. This means that if a
|
||||
local installation already uses 3 `nameserver`s or uses more than 3 `search`es,
|
||||
some of those settings will be lost. As a partial workaround, the node can run
|
||||
`dnsmasq` which will provide more `nameserver` entries, but not more `search`
|
||||
entries. You can also use kubelet's `--resolv-conf` flag.
|
||||
|
||||
If you are using Alpine version 3.3 or earlier as your base image, DNS may not
|
||||
work properly owing to a known issue with Alpine. Check [here](https://github.com/kubernetes/kubernetes/issues/30215)
|
||||
for more information.
|
||||
|
||||
## References
|
||||
|
||||
- [Docs for the DNS cluster addon](http://releases.k8s.io/{{page.githubbranch}}/cluster/addons/dns/README.md)
|
||||
|
||||
## What's next
|
||||
- [Autoscaling the DNS Service in a Cluster](/docs/tasks/administer-cluster/dns-horizontal-autoscaling/).
|
||||
[DNS Pods and Services](/docs/concepts/services-networking/dns-pod-service/)
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ Data Reliability: for reasonable safety, either etcd needs to be run as a
|
||||
etcd) or etcd's data directory should be located on durable storage (e.g., GCE's
|
||||
persistent disk). In either case, if high availability is required--as it might
|
||||
be in a production cluster--the data directory ought to be [backed up
|
||||
periodically](https://coreos.com/etcd/docs/2.2.1/admin_guide.html#disaster-recovery),
|
||||
periodically](https://coreos.com/etcd/docs/latest/op-guide/recovery.html),
|
||||
to reduce downtime in case of corruption.
|
||||
|
||||
## Default configuration
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
title: federation-controller-mananger
|
||||
title: federation-controller-manager
|
||||
notitle: true
|
||||
---
|
||||
|
||||
|
||||
@@ -245,7 +245,7 @@ federation, and
|
||||
in your federation DNS.
|
||||
|
||||
You can find more details about config maps in general at
|
||||
http://kubernetes.io/docs/user-guide/configmap/.
|
||||
[config map](http://kubernetes.io/docs/user-guide/configmap/).
|
||||
|
||||
### Kubernetes 1.4 and earlier: Setting federations flag on kube-dns-rc
|
||||
|
||||
|
||||
@@ -4,205 +4,6 @@ assignees:
|
||||
title: Setting up Cluster Federation with Kubefed
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
Kubernetes version 1.5 includes a new command line tool called
|
||||
`kubefed` to help you administrate your federated clusters.
|
||||
`kubefed` helps you to deploy a new Kubernetes cluster federation
|
||||
control plane, and to add clusters to or remove clusters from an
|
||||
existing federation control plane.
|
||||
|
||||
This guide explains how to administer a Kubernetes Cluster Federation
|
||||
using `kubefed`.
|
||||
|
||||
> Note: `kubefed` is an alpha feature in Kubernetes 1.5.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This guide assumes that you have a running Kubernetes cluster. Please
|
||||
see one of the [getting started](/docs/getting-started-guides/) guides
|
||||
for installation instructions for your platform.
|
||||
|
||||
|
||||
## Getting `kubefed`
|
||||
|
||||
Download the client tarball corresponding to Kubernetes version 1.5
|
||||
or later
|
||||
[from the release page](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md),
|
||||
extract the binaries in the tarball to one of the directories
|
||||
in your `$PATH` and set the executable permission on those binaries.
|
||||
|
||||
Note: The URL in the curl command below downloads the binaries for
|
||||
Linux amd64. If you are on a different platform, please use the URL
|
||||
for the binaries appropriate for your platform. You can find the list
|
||||
of available binaries on the [release page](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG.md#client-binaries-3)
|
||||
|
||||
|
||||
```shell
|
||||
curl -O https://storage.googleapis.com/kubernetes-release/release/v1.5.0/kubernetes-client-linux-amd64.tar.gz
|
||||
tar -xzvf kubernetes-client-linux-amd64.tar.gz
|
||||
sudo cp kubernetes/client/bin/kubefed /usr/local/bin
|
||||
sudo chmod +x /usr/local/bin/kubefed
|
||||
sudo cp kubernetes/client/bin/kubectl /usr/local/bin
|
||||
sudo chmod +x /usr/local/bin/kubectl
|
||||
```
|
||||
|
||||
|
||||
## Choosing a host cluster.
|
||||
|
||||
You'll need to choose one of your Kubernetes clusters to be the
|
||||
*host cluster*. The host cluster hosts the components that make up
|
||||
your federation control plane. Ensure that you have a `kubeconfig`
|
||||
entry in your local `kubeconfig` that corresponds to the host cluster.
|
||||
You can verify that you have the required `kubeconfig` entry by
|
||||
running:
|
||||
|
||||
```shell
|
||||
kubectl config get-contexts
|
||||
```
|
||||
|
||||
The output should contain an entry corresponding to your host cluster,
|
||||
similar to the following:
|
||||
|
||||
```
|
||||
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
|
||||
gke_myproject_asia-east1-b_gce-asia-east1 gke_myproject_asia-east1-b_gce-asia-east1 gke_myproject_asia-east1-b_gce-asia-east1
|
||||
```
|
||||
|
||||
|
||||
You'll need to provide the `kubeconfig` context (called name in the
|
||||
entry above) for your host cluster when you deploy your federation
|
||||
control plane.
|
||||
|
||||
|
||||
## Deploying a federation control plane.
|
||||
|
||||
"To deploy a federation control plane on your host cluster, run
|
||||
`kubefed init` command. When you use `kubefed init`, you must provide
|
||||
the following:
|
||||
|
||||
* Federation name
|
||||
* `--host-cluster-context`, the `kubeconfig` context for the host cluster
|
||||
* `--dns-zone-name`, a domain name suffix for your federated services
|
||||
|
||||
The following example command deploys a federation control plane with
|
||||
the name `fellowship`, a host cluster context `rivendell`, and the
|
||||
domain suffix `example.com`:
|
||||
|
||||
```shell
|
||||
kubefed init fellowship --host-cluster-context=rivendell --dns-zone-name="example.com"
|
||||
```
|
||||
|
||||
The domain suffix you specify in `--dns-zone-name` must be an existing
|
||||
domain that you control, and that is programmable by your DNS provider.
|
||||
|
||||
`kubefed init` sets up the federation control plane in the host
|
||||
cluster and also adds an entry for the federation API server in your
|
||||
local kubeconfig. Note that in the alpha release in Kubernetes 1.5,
|
||||
`kubefed init` does not automatically set the current context to the
|
||||
newly deployed federation. You can set the current context manually by
|
||||
running:
|
||||
|
||||
```shell
|
||||
kubectl config use-context fellowship
|
||||
```
|
||||
|
||||
where `fellowship` is the name of your federation.
|
||||
|
||||
|
||||
## Adding a cluster to a federation
|
||||
|
||||
Once you've deployed a federation control plane, you'll need to make
|
||||
that control plane aware of the clusters it should manage. You can add
|
||||
a cluster to your federation by using the `kubefed join` command.
|
||||
|
||||
To use `kubefed join`, you'll need to provide the name of the cluster
|
||||
you want to add to the federation, and the `--host-cluster-context`
|
||||
for the federation control plane's host cluster.
|
||||
|
||||
The following example command adds the cluster `gondor` to the
|
||||
federation with host cluster `rivendell`:
|
||||
|
||||
```
|
||||
kubefed join gondor --host-cluster-context=rivendell
|
||||
```
|
||||
|
||||
> Note: Kubernetes requires that you manually join clusters to a
|
||||
federation because the federation control plane manages only those
|
||||
clusters that it is responsible for managing. Adding a cluster tells
|
||||
the federation control plane that it is responsible for managing that
|
||||
cluster.
|
||||
|
||||
### Naming rules and customization
|
||||
|
||||
The cluster name you supply to `kubefed join` must be a valid RFC 1035
|
||||
label.
|
||||
|
||||
Furthermore, federation control plane requires credentials of the
|
||||
joined clusters to operate on them. These credentials are obtained
|
||||
from the local kubeconfig. `kubefed join` uses the cluster name
|
||||
specified as the argument to look for the cluster's context in the
|
||||
local kubeconfig. If it fails to find a matching context, it exits
|
||||
with an error.
|
||||
|
||||
This might cause issues in cases where context names for each cluster
|
||||
in the federation don't follow
|
||||
[RFC 1035](https://www.ietf.org/rfc/rfc1035.txt) label naming rules.
|
||||
In such cases, you can specify a cluster name that conforms to the
|
||||
[RFC 1035](https://www.ietf.org/rfc/rfc1035.txt) label naming rules
|
||||
and specify the cluster context using the `--cluster-context` flag.
|
||||
For example, if context of the cluster your are joining is
|
||||
`gondor_needs-no_king`, then you can join the cluster by running:
|
||||
|
||||
```shell
|
||||
kubefed join gondor --host-cluster-context=rivendell --cluster-context=gondor_needs-no_king
|
||||
```
|
||||
|
||||
#### Secret name
|
||||
|
||||
Cluster credentials required by the federation control plane as
|
||||
described above are stored as a secret in the host cluster. The name
|
||||
of the secret is also derived from the cluster name.
|
||||
|
||||
However, the name of a secret object in Kubernetes should conform
|
||||
to the DNS subdomain name specification described in
|
||||
[RFC 1123](https://tools.ietf.org/html/rfc1123). If this isn't the
|
||||
case, you can pass the secret name to `kubefed join` using the
|
||||
`--secret-name` flag. For example, if the cluster name is `noldor` and
|
||||
the secret name is `11kingdom`, you can join the cluster by
|
||||
running:
|
||||
|
||||
```shell
|
||||
kubefed join noldor --host-cluster-context=rivendell --secret-name=11kingdom
|
||||
```
|
||||
|
||||
Note: If your cluster name does not conform to the DNS subdomain name
|
||||
specification, all you need to do is supply the secret name via the
|
||||
`--secret-name` flag. `kubefed join` automatically creates the secret
|
||||
for you.
|
||||
|
||||
|
||||
## Removing a cluster from a federation
|
||||
|
||||
To remove a cluster from a federation, run the `kubefed unjoin`
|
||||
command with the cluster name and the federation's
|
||||
`--host-cluster-context`:
|
||||
|
||||
```
|
||||
kubefed unjoin gondor --host-cluster-context=rivendell
|
||||
```
|
||||
|
||||
|
||||
## Turning down the federation control plane:
|
||||
|
||||
Proper cleanup of federation control plane is not fully implemented in
|
||||
this alpha release of `kubefed`. However, for the time being, deleting
|
||||
the federation system namespace should remove all the resources except
|
||||
the persistent storage volume dynamically provisioned for the
|
||||
federation control plane's etcd. You can delete the federation
|
||||
namespace by running the following command:
|
||||
|
||||
```
|
||||
$ kubectl delete ns federation-system
|
||||
```
|
||||
[Setting up Cluster Federation with kubefed](/docs/tutorials/federation/set-up-cluster-federation-kubefed/)
|
||||
|
||||
@@ -23,10 +23,10 @@ threshold has been met.
|
||||
|
||||
### Container Collection
|
||||
|
||||
The policy for garbage collecting containers considers three user-defined variables. `MinAge` is the minimum age at which a container can be garbage collected. `MaxPerPodContainer` is the maximum number of dead containers any single
|
||||
pod (UID, container name) pair is allowed to have. `MaxContainers` is the maximum number of total dead containers. These variables can be individually disabled by setting 'MinAge' to zero and setting 'MaxPerPodContainer' and 'MaxContainers' respectively to less than zero.
|
||||
The policy for garbage collecting containers considers three user-defined variables. `MinAge` is the minimum age at which a container can be garbage collected. `MaxPerPodContainer` is the maximum number of dead containers every single
|
||||
pod (UID, container name) pair is allowed to have. `MaxContainers` is the maximum number of total dead containers. These variables can be individually disabled by setting `MinAge` to zero and setting `MaxPerPodContainer` and `MaxContainers` respectively to less than zero.
|
||||
|
||||
Kubelet will act on containers that are unidentified, deleted, or outside of the boundaries set by the previously mentioned flags. The oldest containers will generally be removed first. 'MaxPerPodContainer' and 'MaxContainer' may potentially conflict with each other in situations where retaining the maximum number of containers per pod ('MaxPerPodContainer') would go outside the allowable range of global dead containers ('MaxContainers'). 'MaxPerPodContainer' would be adjusted in this situation: A worst case scenario would be to downgrade 'MaxPerPodContainer' to 1 and evict the oldest containers. Additionally, containers owned by pods that have been deleted are removed once they are older than `MinAge`.
|
||||
Kubelet will act on containers that are unidentified, deleted, or outside of the boundaries set by the previously mentioned flags. The oldest containers will generally be removed first. `MaxPerPodContainer` and `MaxContainer` may potentially conflict with each other in situations where retaining the maximum number of containers per pod (`MaxPerPodContainer`) would go outside the allowable range of global dead containers (`MaxContainers`). `MaxPerPodContainer` would be adjusted in this situation: A worst case scenario would be to downgrade `MaxPerPodContainer` to 1 and evict the oldest containers. Additionally, containers owned by pods that have been deleted are removed once they are older than `MinAge`.
|
||||
|
||||
Containers that are not managed by kubelet are not subject to container garbage collection.
|
||||
|
||||
@@ -42,15 +42,34 @@ to free. Default is 80%.
|
||||
We also allow users to customize garbage collection policy through the following kubelet flags:
|
||||
|
||||
1. `minimum-container-ttl-duration`, minimum age for a finished container before it is
|
||||
garbage collected. Default is 1 minute.
|
||||
2. `maximum-dead-containers-per-container`, maximum number of old instances to retain
|
||||
per container. Default is 2.
|
||||
garbage collected. Default is 0 minute, which means every finished container will be garbaged collected.
|
||||
2. `maximum-dead-containers-per-container`, maximum number of old instances to be retained
|
||||
per container. Default is 1.
|
||||
3. `maximum-dead-containers`, maximum number of old instances of containers to retain globally.
|
||||
Default is 100.
|
||||
Default is -1, which means there is no global limit.
|
||||
|
||||
Containers can potentially be garbage collected before their usefulness has expired. These containers
|
||||
can contain logs and other data that can be useful for troubleshooting. A sufficiently large value for
|
||||
`maximum-dead-containers-per-container` is highly recommended to allow at least 2 dead containers to be
|
||||
retained per expected container. A higher value for `maximum-dead-containers` is also recommended for a
|
||||
`maximum-dead-containers-per-container` is highly recommended to allow at least 1 dead container to be
|
||||
retained per expected container. A larger value for `maximum-dead-containers` is also recommended for a
|
||||
similar reason.
|
||||
See [this issue](https://github.com/kubernetes/kubernetes/issues/13287) for more details.
|
||||
|
||||
|
||||
### Deprecation
|
||||
|
||||
Some kubelet Garbage Collection features in this doc will be replaced by kubelet eviction in the future.
|
||||
|
||||
Including:
|
||||
|
||||
| Existing Flag | New Flag | Rationale |
|
||||
| ------------- | -------- | --------- |
|
||||
| `--image-gc-high-threshold` | `--eviction-hard` or `--eviction-soft` | existing eviction signals can trigger image garbage collection |
|
||||
| `--image-gc-low-threshold` | `--eviction-minimum-reclaim` | eviction reclaims achieve the same behavior |
|
||||
| `--maximum-dead-containers` | | deprecated once old logs are stored outside of container's context |
|
||||
| `--maximum-dead-containers-per-container` | | deprecated once old logs are stored outside of container's context |
|
||||
| `--minimum-container-ttl-duration` | | deprecated once old logs are stored outside of container's context |
|
||||
| `--low-diskspace-threshold-mb` | `--eviction-hard` or `eviction-soft` | eviction generalizes disk thresholds to other resources |
|
||||
| `--outofdisk-transition-frequency` | `--eviction-pressure-transition-period` | eviction generalizes disk pressure transition to other resources |
|
||||
|
||||
See [Configuring Out Of Resource Handling](/docs/admin/out-of-resource/) for more details.
|
||||
|
||||
@@ -107,7 +107,7 @@ This operation may be sped up by migrating etcd data directory, as described [he
|
||||
|
||||
## Implementation notes
|
||||
|
||||

|
||||

|
||||
|
||||
### Overview
|
||||
|
||||
|
||||
+2
-87
@@ -1,92 +1,7 @@
|
||||
---
|
||||
assignees:
|
||||
- davidopp
|
||||
- lavalamp
|
||||
title: Admin Guide
|
||||
---
|
||||
|
||||
The cluster admin guide is for anyone creating or administering a Kubernetes cluster.
|
||||
It assumes some familiarity with concepts in the [User Guide](/docs/user-guide/).
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
## Planning a cluster
|
||||
|
||||
There are many different examples of how to setup a Kubernetes cluster. Many of them are listed in this
|
||||
[matrix](/docs/getting-started-guides/). We call each of the combinations in this matrix a *distro*.
|
||||
|
||||
Before choosing a particular guide, here are some things to consider:
|
||||
|
||||
- Are you just looking to try out Kubernetes on your laptop, or build a high-availability many-node cluster? Both
|
||||
models are supported, but some distros are better for one case or the other.
|
||||
- Will you be using a hosted Kubernetes cluster, such as [GKE](https://cloud.google.com/container-engine), or setting
|
||||
one up yourself?
|
||||
- Will your cluster be on-premises, or in the cloud (IaaS)? Kubernetes does not directly support hybrid clusters. We
|
||||
recommend setting up multiple clusters rather than spanning distant locations.
|
||||
- Will you be running Kubernetes on "bare metal" or virtual machines? Kubernetes supports both, via different distros.
|
||||
- Do you just want to run a cluster, or do you expect to do active development of Kubernetes project code? If the
|
||||
latter, it is better to pick a distro actively used by other developers. Some distros only use binary releases, but
|
||||
offer is a greater variety of choices.
|
||||
- Not all distros are maintained as actively. Prefer ones which are listed as tested on a more recent version of
|
||||
Kubernetes.
|
||||
- If you are configuring Kubernetes on-premises, you will need to consider what [networking
|
||||
model](/docs/admin/networking) fits best.
|
||||
- If you are designing for very high-availability, you may want [clusters in multiple zones](/docs/admin/multi-cluster).
|
||||
- You may want to familiarize yourself with the various
|
||||
[components](/docs/admin/cluster-components) needed to run a cluster.
|
||||
|
||||
## Setting up a cluster
|
||||
|
||||
Pick one of the Getting Started Guides from the [matrix](/docs/getting-started-guides/) and follow it.
|
||||
If none of the Getting Started Guides fits, you may want to pull ideas from several of the guides.
|
||||
|
||||
One option for custom networking is *OpenVSwitch GRE/VxLAN networking* ([ovs-networking.md](/docs/admin/ovs-networking)), which
|
||||
uses OpenVSwitch to set up networking between pods across
|
||||
Kubernetes nodes.
|
||||
|
||||
If you are modifying an existing guide which uses Salt, this document explains [how Salt is used in the Kubernetes
|
||||
project](/docs/admin/salt).
|
||||
|
||||
## Managing a cluster, including upgrades
|
||||
|
||||
[Managing a cluster](/docs/admin/cluster-management).
|
||||
|
||||
## Managing nodes
|
||||
|
||||
[Managing nodes](/docs/admin/node).
|
||||
|
||||
## Optional Cluster Services
|
||||
|
||||
* **DNS Integration with SkyDNS** ([dns.md](/docs/admin/dns)):
|
||||
Resolving a DNS name directly to a Kubernetes service.
|
||||
|
||||
* [**Cluster-level logging**](/docs/user-guide/logging/overview):
|
||||
Saving container logs to a central log store with search/browsing interface.
|
||||
|
||||
## Multi-tenant support
|
||||
|
||||
* **Resource Quota** ([resourcequota/](/docs/admin/resourcequota/))
|
||||
|
||||
## Security
|
||||
|
||||
* **Kubernetes Container Environment** ([docs/user-guide/container-environment.md](/docs/user-guide/container-environment)):
|
||||
Describes the environment for Kubelet managed containers on a Kubernetes
|
||||
node.
|
||||
|
||||
* **Securing access to the API Server** [accessing the api](/docs/admin/accessing-the-api)
|
||||
|
||||
* **Authentication** [authentication](/docs/admin/authentication)
|
||||
|
||||
* **Authorization** [authorization](/docs/admin/authorization)
|
||||
|
||||
* **Admission Controllers** [admission controllers](/docs/admin/admission-controllers)
|
||||
|
||||
* **Sysctls** [sysctls](/docs/admin/sysctls.md)
|
||||
|
||||
* **Audit** [audit](/docs/admin/audit)
|
||||
|
||||
* **Securing the kubelet**
|
||||
* [Master-Node communication](/docs/admin/master-node-communication/)
|
||||
* [TLS bootstrapping](/docs/admin/kubelet-tls-bootstrapping/)
|
||||
* [Kubelet authentication/authorization](/docs/admin/kubelet-authentication-authorization/)
|
||||
[Cluster Administration Overview](/docs/tasks/administer-cluster/overview/)
|
||||
|
||||
@@ -71,10 +71,17 @@ DynamicKubeletConfig=true|false (ALPHA - default=false)
|
||||
DynamicVolumeProvisioning=true|false (ALPHA - default=true)
|
||||
ExperimentalHostUserNamespaceDefaulting=true|false (ALPHA - default=false)
|
||||
StreamingProxyRedirects=true|false (ALPHA - default=false)
|
||||
--google-json-key string The Google Cloud Platform Service Account JSON Key to use for authentication.
|
||||
--insecure-allow-any-token username/group1,group2 If set, your server will be INSECURE. Any token will be allowed and user information will be parsed from the token as username/group1,group2
|
||||
--insecure-bind-address ip The IP address on which to serve the --insecure-port (set to 0.0.0.0 for all interfaces). Defaults to localhost. (default 127.0.0.1)
|
||||
--insecure-port int The port on which to serve unsecured, unauthenticated access. Default 8080. It is assumed that firewall rules are set up such that this port is not reachable from outside of the cluster and that port 443 on the cluster's public address is proxied to this port. This is performed by nginx in the default setup. (default 8080)
|
||||
--ir-data-source string Data source used by InitialResources. Supported options: influxdb, gcm. (default "influxdb")
|
||||
--ir-dbname string InfluxDB database name which contains metrics required by InitialResources. (default "k8s")
|
||||
--ir-hawkular string Hawkular configuration URL.
|
||||
--ir-influxdb-host string Address of InfluxDB which contains metrics required by InitialResources. (default "localhost:8080/api/v1/proxy/namespaces/kube-system/services/monitoring-influxdb:api")
|
||||
--ir-namespace-only Whether the estimation should be made only based on data from the same namespace.
|
||||
--ir-password string Password used for connecting to InfluxDB. (default "root")
|
||||
--ir-percentile int Which percentile of samples should InitialResources use when estimating resources. For experiment purposes. (default 90)
|
||||
--ir-user string User used for connecting to InfluxDB. (default "root")
|
||||
--kubelet-certificate-authority string Path to a cert file for the certificate authority.
|
||||
--kubelet-client-certificate string Path to a client cert file for TLS.
|
||||
--kubelet-client-key string Path to a client key file for TLS.
|
||||
|
||||
@@ -28,6 +28,7 @@ kube-controller-manager
|
||||
```
|
||||
--address ip The IP address to serve on (set to 0.0.0.0 for all interfaces) (default 0.0.0.0)
|
||||
--allocate-node-cidrs Should CIDRs for Pods be allocated and set on the cloud provider.
|
||||
--allow-verification-with-non-compliant-keys Allow a SignatureVerifier to use keys which are technically non-compliant with RFC6962.
|
||||
--cloud-config string The path to the cloud provider configuration file. Empty string for no configuration file.
|
||||
--cloud-provider string The provider for cloud services. Empty string for no provider.
|
||||
--cluster-cidr string CIDR Range for Pods in cluster.
|
||||
@@ -59,7 +60,6 @@ DynamicVolumeProvisioning=true|false (ALPHA - default=true)
|
||||
ExperimentalHostUserNamespaceDefaulting=true|false (ALPHA - default=false)
|
||||
StreamingProxyRedirects=true|false (ALPHA - default=false)
|
||||
--flex-volume-plugin-dir string Full path of the directory in which the flex volume plugin should search for additional third party volume plugins. (default "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/")
|
||||
--google-json-key string The Google Cloud Platform Service Account JSON Key to use for authentication.
|
||||
--horizontal-pod-autoscaler-sync-period duration The period for syncing the number of pods in horizontal pod autoscaler. (default 30s)
|
||||
--insecure-experimental-approve-all-kubelet-csrs-for-group string The group for which the controller-manager will auto approve all CSRs for kubelet client certificates.
|
||||
--kube-api-burst int32 Burst to use while talking with Kubernetes apiserver (default 30)
|
||||
|
||||
@@ -41,7 +41,6 @@ DynamicKubeletConfig=true|false (ALPHA - default=false)
|
||||
DynamicVolumeProvisioning=true|false (ALPHA - default=true)
|
||||
ExperimentalHostUserNamespaceDefaulting=true|false (ALPHA - default=false)
|
||||
StreamingProxyRedirects=true|false (ALPHA - default=false)
|
||||
--google-json-key string The Google Cloud Platform Service Account JSON Key to use for authentication.
|
||||
--healthz-bind-address ip The IP address for the health check server to serve on, defaulting to 127.0.0.1 (set to 0.0.0.0 for all interfaces) (default 127.0.0.1)
|
||||
--healthz-port int32 The port to bind the health check server. Use 0 to disable. (default 10249)
|
||||
--hostname-override string If non-empty, will use this string as identification instead of the actual hostname.
|
||||
|
||||
@@ -36,7 +36,6 @@ DynamicKubeletConfig=true|false (ALPHA - default=false)
|
||||
DynamicVolumeProvisioning=true|false (ALPHA - default=true)
|
||||
ExperimentalHostUserNamespaceDefaulting=true|false (ALPHA - default=false)
|
||||
StreamingProxyRedirects=true|false (ALPHA - default=false)
|
||||
--google-json-key string The Google Cloud Platform Service Account JSON Key to use for authentication.
|
||||
--hard-pod-affinity-symmetric-weight int RequiredDuringScheduling affinity is not symmetric, but there is an implicit PreferredDuringScheduling affinity rule corresponding to every RequiredDuringScheduling affinity rule. --hard-pod-affinity-symmetric-weight represents the weight of implicit PreferredDuringScheduling affinity rule. (default 1)
|
||||
--kube-api-burst int32 Burst to use while talking with Kubernetes apiserver (default 100)
|
||||
--kube-api-content-type string Content type of requests sent to apiserver. (default "application/vnd.kubernetes.protobuf")
|
||||
|
||||
+60
-41
@@ -31,10 +31,10 @@ server, as well as an additional kubeconfig file for administration.
|
||||
controller manager and scheduler, and placing them in
|
||||
`/etc/kubernetes/manifests`. The kubelet watches this directory for static
|
||||
resources to create on startup. These are the core components of Kubernetes, and
|
||||
once they are up and running we can use `kubectl` to set up/manage any
|
||||
once they are up and running we can use `kubectl` to set up or manage any
|
||||
additional components.
|
||||
|
||||
1. kubeadm installs any add-on components, such as DNS or discovery, via the API
|
||||
1. kubeadm installs some add-on components, such as DNS or discovery, via the API
|
||||
server.
|
||||
|
||||
Running `kubeadm join` on each node in the cluster consists of the following steps:
|
||||
@@ -180,48 +180,49 @@ available as configuration file options.
|
||||
|
||||
### Sample Master Configuration
|
||||
|
||||
```yaml
|
||||
apiVersion: kubeadm.k8s.io/v1alpha1
|
||||
kind: MasterConfiguration
|
||||
api:
|
||||
advertiseAddresses:
|
||||
- <address1|string>
|
||||
- <address2|string>
|
||||
bindPort: <int>
|
||||
externalDNSNames:
|
||||
- <dnsname1|string>
|
||||
- <dnsname2|string>
|
||||
cloudProvider: <string>
|
||||
discovery:
|
||||
bindPort: <int>
|
||||
etcd:
|
||||
endpoints:
|
||||
- <endpoint1|string>
|
||||
- <endpoint2|string>
|
||||
caFile: <path|string>
|
||||
certFile: <path|string>
|
||||
keyFile: <path|string>
|
||||
kubernetesVersion: <string>
|
||||
networking:
|
||||
dnsDomain: <string>
|
||||
serviceSubnet: <cidr>
|
||||
podSubnet: <cidr>
|
||||
secrets:
|
||||
givenToken: <token|string>
|
||||
```
|
||||
```yaml
|
||||
apiVersion: kubeadm.k8s.io/v1alpha1
|
||||
kind: MasterConfiguration
|
||||
api:
|
||||
advertiseAddresses:
|
||||
- <address1|string>
|
||||
- <address2|string>
|
||||
bindPort: <int>
|
||||
externalDNSNames:
|
||||
- <dnsname1|string>
|
||||
- <dnsname2|string>
|
||||
authorizationMode: <string>
|
||||
cloudProvider: <string>
|
||||
discovery:
|
||||
bindPort: <int>
|
||||
etcd:
|
||||
endpoints:
|
||||
- <endpoint1|string>
|
||||
- <endpoint2|string>
|
||||
caFile: <path|string>
|
||||
certFile: <path|string>
|
||||
keyFile: <path|string>
|
||||
kubernetesVersion: <string>
|
||||
networking:
|
||||
dnsDomain: <string>
|
||||
serviceSubnet: <cidr>
|
||||
podSubnet: <cidr>
|
||||
secrets:
|
||||
givenToken: <token|string>
|
||||
```
|
||||
|
||||
### Sample Node Configuration
|
||||
|
||||
```yaml
|
||||
apiVersion: kubeadm.k8s.io/v1alpha1
|
||||
kind: NodeConfiguration
|
||||
apiPort: <int>
|
||||
discoveryPort: <int>
|
||||
masterAddresses:
|
||||
- <master1>
|
||||
secrets:
|
||||
givenToken: <token|string>
|
||||
```
|
||||
```yaml
|
||||
apiVersion: kubeadm.k8s.io/v1alpha1
|
||||
kind: NodeConfiguration
|
||||
apiPort: <int>
|
||||
discoveryPort: <int>
|
||||
masterAddresses:
|
||||
- <master1>
|
||||
secrets:
|
||||
givenToken: <token|string>
|
||||
```
|
||||
|
||||
## Automating kubeadm
|
||||
|
||||
@@ -257,6 +258,24 @@ These environment variables are a short-term solution, eventually they will be i
|
||||
| `KUBE_ETCD_IMAGE` | `gcr.io/google_containers/etcd-<arch>:2.2.5` | The etcd container image to use. |
|
||||
| `KUBE_REPO_PREFIX` | `gcr.io/google_containers` | The image prefix for all images that are used. |
|
||||
|
||||
If you want to use kubeadm with an http proxy, you may need to configure it to support http_proxy, https_proxy, or no_proxy.
|
||||
|
||||
For example, if your kube master node IP address is 10.18.17.16 and you have proxy support both http/https on 10.18.17.16 port 8080, you can use the following command:
|
||||
|
||||
You can using following command
|
||||
|
||||
```bash
|
||||
export PROXY_PORT=8080
|
||||
export PROXY_IP=10.18.17.16
|
||||
export http_proxy=http://$PROXY_IP:$PROXY_PORT
|
||||
export HTTP_PROXY=$http_proxy
|
||||
export https_proxy=$http_proxy
|
||||
export HTTPS_PROXY=$http_proxy
|
||||
export no_proxy="localhost,127.0.0.1,localaddress,.localdomain.com,example.com,10.18.17.16"
|
||||
```
|
||||
|
||||
Remember to change ```proxy_ip``` and add a kube master node IP address to ```no_proxy```.
|
||||
|
||||
## Releases and release notes
|
||||
|
||||
If you already have kubeadm installed and want to upgrade, run `apt-get update && apt-get upgrade` or `yum update` to get the latest version of kubeadm.
|
||||
|
||||
@@ -17,8 +17,8 @@ various mechanisms (primarily through the apiserver) and ensures that the contai
|
||||
described in those PodSpecs are running and healthy. The kubelet doesn't manage
|
||||
containers which were not created by Kubernetes.
|
||||
|
||||
Other than from a PodSpec from the apiserver, there are three ways that a container
|
||||
manifest can be provided to the Kubelet.
|
||||
Other than from a PodSpec, there are three ways that a container
|
||||
manifest can be provided to the Kubelet from the apiserver.
|
||||
|
||||
File: Path passed as a flag on the command line. This file is rechecked every 20
|
||||
seconds (configurable with a flag).
|
||||
@@ -96,7 +96,7 @@ StreamingProxyRedirects=true|false (ALPHA - default=false)
|
||||
--google-json-key string The Google Cloud Platform Service Account JSON Key to use for authentication.
|
||||
--hairpin-mode string How should the kubelet setup hairpin NAT. This allows endpoints of a Service to loadbalance back to themselves if they should try to access their own Service. Valid values are "promiscuous-bridge", "hairpin-veth" and "none". (default "promiscuous-bridge")
|
||||
--healthz-bind-address ip The IP address for the healthz server to serve on, defaulting to 127.0.0.1 (set to 0.0.0.0 for all interfaces) (default 127.0.0.1)
|
||||
--healthz-port int32 The port of the localhost healthz endpoint (default 10248)
|
||||
--healthz-port int32 (Deprecated) The port of the localhost healthz endpoint (default 10248)
|
||||
--host-ipc-sources stringSlice Comma-separated list of sources from which the Kubelet allows pods to use the host ipc namespace. [default="*"] (default [*])
|
||||
--host-network-sources stringSlice Comma-separated list of sources from which the Kubelet allows pods to use of host network. [default="*"] (default [*])
|
||||
--host-pid-sources stringSlice Comma-separated list of sources from which the Kubelet allows pods to use the host pid namespace. [default="*"] (default [*])
|
||||
@@ -137,7 +137,7 @@ StreamingProxyRedirects=true|false (ALPHA - default=false)
|
||||
--pods-per-core int32 Number of Pods per core that can run on this Kubelet. The total number of Pods on this Kubelet cannot exceed max-pods, so max-pods will be used if this calculation results in a larger number of Pods allowed on the Kubelet. A value of 0 disables this limit.
|
||||
--port int32 The port for the Kubelet to serve on. (default 10250)
|
||||
--protect-kernel-defaults Default kubelet behaviour for kernel tuning. If set, kubelet errors if any of kernel tunables is different than kubelet defaults.
|
||||
--read-only-port int32 The read-only port for the Kubelet to serve on with no authentication/authorization (set to 0 to disable) (default 10255)
|
||||
--read-only-port int32 The read-only port for the Kubelet to serve on with no authentication/authorization, and for localhost healthz endpoint (set to 0 to disable) (default 10255)
|
||||
--really-crash-for-testing If true, when panics occur crash. Intended for testing.
|
||||
--register-node Register the node with the apiserver (defaults to true if --api-servers is set) (default true)
|
||||
--register-schedulable Register the node as schedulable. Won't have any effect if register-node is false. [default=true] (default true)
|
||||
|
||||
@@ -5,210 +5,6 @@ assignees:
|
||||
title: Setting Pod CPU and Memory Limits
|
||||
---
|
||||
|
||||
By default, pods run with unbounded CPU and memory limits. This means that any pod in the
|
||||
system will be able to consume as much CPU and memory on the node that executes the pod.
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
Users may want to impose restrictions on the amount of resources a single pod in the system may consume
|
||||
for a variety of reasons.
|
||||
|
||||
For example:
|
||||
|
||||
1. Each node in the cluster has 2GB of memory. The cluster operator does not want to accept pods
|
||||
that require more than 2GB of memory since no node in the cluster can support the requirement. To prevent a
|
||||
pod from being permanently unscheduled to a node, the operator instead chooses to reject pods that exceed 2GB
|
||||
of memory as part of admission control.
|
||||
2. A cluster is shared by two communities in an organization that runs production and development workloads
|
||||
respectively. Production workloads may consume up to 8GB of memory, but development workloads may consume up
|
||||
to 512MB of memory. The cluster operator creates a separate namespace for each workload, and applies limits to
|
||||
each namespace.
|
||||
3. Users may create a pod which consumes resources just below the capacity of a machine. The left over space
|
||||
may be too small to be useful, but big enough for the waste to be costly over the entire cluster. As a result,
|
||||
the cluster operator may want to set limits that a pod must consume at least 20% of the memory and CPU of their
|
||||
average node size in order to provide for more uniform scheduling and to limit waste.
|
||||
|
||||
This example demonstrates how limits can be applied to a Kubernetes [namespace](/docs/admin/namespaces/walkthrough/) to control
|
||||
min/max resource limits per pod. In addition, this example demonstrates how you can
|
||||
apply default resource limits to pods in the absence of an end-user specified value.
|
||||
|
||||
See [LimitRange design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/admission_control_limit_range.md) for more information. For a detailed description of the Kubernetes resource model, see [Resources](/docs/user-guide/compute-resources/)
|
||||
|
||||
## Step 0: Prerequisites
|
||||
|
||||
This example requires a running Kubernetes cluster. See the [Getting Started guides](/docs/getting-started-guides/) for how to get started.
|
||||
|
||||
Change to the `<kubernetes>` directory if you're not already there.
|
||||
|
||||
## Step 1: Create a namespace
|
||||
|
||||
This example will work in a custom namespace to demonstrate the concepts involved.
|
||||
|
||||
Let's create a new namespace called limit-example:
|
||||
|
||||
```shell
|
||||
$ kubectl create namespace limit-example
|
||||
namespace "limit-example" created
|
||||
```
|
||||
|
||||
Note that `kubectl` commands will print the type and name of the resource created or mutated, which can then be used in subsequent commands:
|
||||
|
||||
```shell
|
||||
$ kubectl get namespaces
|
||||
NAME STATUS AGE
|
||||
default Active 51s
|
||||
limit-example Active 45s
|
||||
```
|
||||
|
||||
## Step 2: Apply a limit to the namespace
|
||||
|
||||
Let's create a simple limit in our namespace.
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/limitrange/limits.yaml --namespace=limit-example
|
||||
limitrange "mylimits" created
|
||||
```
|
||||
|
||||
Let's describe the limits that we have imposed in our namespace.
|
||||
|
||||
```shell
|
||||
$ kubectl describe limits mylimits --namespace=limit-example
|
||||
Name: mylimits
|
||||
Namespace: limit-example
|
||||
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
|
||||
---- -------- --- --- --------------- ------------- -----------------------
|
||||
Pod cpu 200m 2 - - -
|
||||
Pod memory 6Mi 1Gi - - -
|
||||
Container cpu 100m 2 200m 300m -
|
||||
Container memory 3Mi 1Gi 100Mi 200Mi -
|
||||
```
|
||||
|
||||
In this scenario, we have said the following:
|
||||
|
||||
1. If a max constraint is specified for a resource (2 CPU and 1Gi memory in this case), then a limit
|
||||
must be specified for that resource across all containers. Failure to specify a limit will result in
|
||||
a validation error when attempting to create the pod. Note that a default value of limit is set by
|
||||
*default* in file `limits.yaml` (300m CPU and 200Mi memory).
|
||||
2. If a min constraint is specified for a resource (100m CPU and 3Mi memory in this case), then a
|
||||
request must be specified for that resource across all containers. Failure to specify a request will
|
||||
result in a validation error when attempting to create the pod. Note that a default value of request is
|
||||
set by *defaultRequest* in file `limits.yaml` (200m CPU and 100Mi memory).
|
||||
3. For any pod, the sum of all containers memory requests must be >= 6Mi and the sum of all containers
|
||||
memory limits must be <= 1Gi; the sum of all containers CPU requests must be >= 200m and the sum of all
|
||||
containers CPU limits must be <= 2.
|
||||
|
||||
## Step 3: Enforcing limits at point of creation
|
||||
|
||||
The limits enumerated in a namespace are only enforced when a pod is created or updated in
|
||||
the cluster. If you change the limits to a different value range, it does not affect pods that
|
||||
were previously created in a namespace.
|
||||
|
||||
If a resource (CPU or memory) is being restricted by a limit, the user will get an error at time
|
||||
of creation explaining why.
|
||||
|
||||
Let's first spin up a [Deployment](/docs/user-guide/deployments) that creates a single container Pod to demonstrate
|
||||
how default values are applied to each pod.
|
||||
|
||||
```shell
|
||||
$ kubectl run nginx --image=nginx --replicas=1 --namespace=limit-example
|
||||
deployment "nginx" created
|
||||
```
|
||||
|
||||
Note that `kubectl run` creates a Deployment named "nginx" on Kubernetes cluster >= v1.2. If you are running older versions, it creates replication controllers instead.
|
||||
If you want to obtain the old behavior, use `--generator=run/v1` to create replication controllers. See [`kubectl run`](/docs/user-guide/kubectl/kubectl_run/) for more details.
|
||||
The Deployment manages 1 replica of single container Pod. Let's take a look at the Pod it manages. First, find the name of the Pod:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods --namespace=limit-example
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-2040093540-s8vzu 1/1 Running 0 11s
|
||||
```
|
||||
|
||||
Let's print this Pod with yaml output format (using `-o yaml` flag), and then `grep` the `resources` field. Note that your pod name will be different.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods nginx-2040093540-s8vzu --namespace=limit-example -o yaml | grep resources -C 8
|
||||
resourceVersion: "57"
|
||||
selfLink: /api/v1/namespaces/limit-example/pods/nginx-2040093540-ivimu
|
||||
uid: 67b20741-f53b-11e5-b066-64510658e388
|
||||
spec:
|
||||
containers:
|
||||
- image: nginx
|
||||
imagePullPolicy: Always
|
||||
name: nginx
|
||||
resources:
|
||||
limits:
|
||||
cpu: 300m
|
||||
memory: 200Mi
|
||||
requests:
|
||||
cpu: 200m
|
||||
memory: 100Mi
|
||||
terminationMessagePath: /dev/termination-log
|
||||
volumeMounts:
|
||||
```
|
||||
|
||||
Note that our nginx container has picked up the namespace default CPU and memory resource *limits* and *requests*.
|
||||
|
||||
Let's create a pod that exceeds our allowed limits by having it have a container that requests 3 CPU cores.
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/limitrange/invalid-pod.yaml --namespace=limit-example
|
||||
Error from server: error when creating "docs/admin/limitrange/invalid-pod.yaml": Pod "invalid-pod" is forbidden: [Maximum cpu usage per Pod is 2, but limit is 3., Maximum cpu usage per Container is 2, but limit is 3.]
|
||||
```
|
||||
|
||||
Let's create a pod that falls within the allowed limit boundaries.
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/limitrange/valid-pod.yaml --namespace=limit-example
|
||||
pod "valid-pod" created
|
||||
```
|
||||
|
||||
Now look at the Pod's resources field:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods valid-pod --namespace=limit-example -o yaml | grep -C 6 resources
|
||||
uid: 3b1bfd7a-f53c-11e5-b066-64510658e388
|
||||
spec:
|
||||
containers:
|
||||
- image: gcr.io/google_containers/serve_hostname
|
||||
imagePullPolicy: Always
|
||||
name: kubernetes-serve-hostname
|
||||
resources:
|
||||
limits:
|
||||
cpu: "1"
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: "1"
|
||||
memory: 512Mi
|
||||
```
|
||||
|
||||
Note that this pod specifies explicit resource *limits* and *requests* so it did not pick up the namespace
|
||||
default values.
|
||||
|
||||
Note: The *limits* for CPU resource are enforced in the default Kubernetes setup on the physical node
|
||||
that runs the container unless the administrator deploys the kubelet with the following flag:
|
||||
|
||||
```shell
|
||||
$ kubelet --help
|
||||
Usage of kubelet
|
||||
....
|
||||
--cpu-cfs-quota[=true]: Enable CPU CFS quota enforcement for containers that specify CPU limits
|
||||
$ kubelet --cpu-cfs-quota=false ...
|
||||
```
|
||||
|
||||
## Step 4: Cleanup
|
||||
|
||||
To remove the resources used by this example, you can just delete the limit-example namespace.
|
||||
|
||||
```shell
|
||||
$ kubectl delete namespace limit-example
|
||||
namespace "limit-example" deleted
|
||||
$ kubectl get namespaces
|
||||
NAME STATUS AGE
|
||||
default Active 12m
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
Cluster operators that want to restrict the amount of resources a single container or pod may consume
|
||||
are able to define allowable ranges per Kubernetes namespace. In the absence of any explicit assignments,
|
||||
the Kubernetes system is able to apply default resource *limits* and *requests* if desired in order to
|
||||
constrain the amount of resource a pod consumes on a node.
|
||||
[Setting Pod CPU and Memory Limits](/docs/tasks/configure-pod-container/limit-range/)
|
||||
|
||||
@@ -4,63 +4,6 @@ assignees:
|
||||
title: Using Multiple Clusters
|
||||
---
|
||||
|
||||
You may want to set up multiple Kubernetes clusters, both to
|
||||
have clusters in different regions to be nearer to your users, and to tolerate failures and/or invasive maintenance.
|
||||
This document describes some of the issues to consider when making a decision about doing so.
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
If you decide to have multiple clusters, Kubernetes provides a way to [federate them](/docs/admin/federation/).
|
||||
|
||||
## Scope of a single cluster
|
||||
|
||||
On IaaS providers such as Google Compute Engine or Amazon Web Services, a VM exists in a
|
||||
[zone](https://cloud.google.com/compute/docs/zones) or [availability
|
||||
zone](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-regions-availability-zones.html).
|
||||
We suggest that all the VMs in a Kubernetes cluster should be in the same availability zone, because:
|
||||
|
||||
- compared to having a single global Kubernetes cluster, there are fewer single-points of failure
|
||||
- compared to a cluster that spans availability zones, it is easier to reason about the availability properties of a
|
||||
single-zone cluster.
|
||||
- when the Kubernetes developers are designing the system (e.g. making assumptions about latency, bandwidth, or
|
||||
correlated failures) they are assuming all the machines are in a single data center, or otherwise closely connected.
|
||||
|
||||
It is okay to have multiple clusters per availability zone, though on balance we think fewer is better.
|
||||
Reasons to prefer fewer clusters are:
|
||||
|
||||
- improved bin packing of Pods in some cases with more nodes in one cluster (less resource fragmentation)
|
||||
- reduced operational overhead (though the advantage is diminished as ops tooling and processes matures)
|
||||
- reduced costs for per-cluster fixed resource costs, e.g. apiserver VMs (but small as a percentage
|
||||
of overall cluster cost for medium to large clusters).
|
||||
|
||||
Reasons to have multiple clusters include:
|
||||
|
||||
- strict security policies requiring isolation of one class of work from another (but, see Partitioning Clusters
|
||||
below).
|
||||
- test clusters to canary new Kubernetes releases or other cluster software.
|
||||
|
||||
## Selecting the right number of clusters
|
||||
|
||||
The selection of the number of Kubernetes clusters may be a relatively static choice, only revisited occasionally.
|
||||
By contrast, the number of nodes in a cluster and the number of pods in a service may change frequently according to
|
||||
load and growth.
|
||||
|
||||
To pick the number of clusters, first, decide which regions you need to be in to have adequate latency to all your end users, for services that will run
|
||||
on Kubernetes (if you use a Content Distribution Network, the latency requirements for the CDN-hosted content need not
|
||||
be considered). Legal issues might influence this as well. For example, a company with a global customer base might decide to have clusters in US, EU, AP, and SA regions.
|
||||
Call the number of regions to be in `R`.
|
||||
|
||||
Second, decide how many clusters should be able to be unavailable at the same time, while still being available. Call
|
||||
the number that can be unavailable `U`. If you are not sure, then 1 is a fine choice.
|
||||
|
||||
If it is allowable for load-balancing to direct traffic to any region in the event of a cluster failure, then
|
||||
you need at least the larger of `R` or `U + 1` clusters. If it is not (e.g. you want to ensure low latency for all
|
||||
users in the event of a cluster failure), then you need to have `R * (U + 1)` clusters
|
||||
(`U + 1` in each of `R` regions). In any case, try to put each cluster in a different zone.
|
||||
|
||||
Finally, if any of your clusters would need more than the maximum recommended number of nodes for a Kubernetes cluster, then
|
||||
you may need even more clusters. Kubernetes v1.3 supports clusters up to 1000 nodes in size.
|
||||
|
||||
## Working with multiple clusters
|
||||
|
||||
When you have multiple clusters, you would typically create services with the same config in each cluster and put each of those
|
||||
service instances behind a load balancer (AWS Elastic Load Balancer, GCE Forwarding Rule or HTTP Load Balancer) spanning all of them, so that
|
||||
failures of a single cluster are not visible to end users.
|
||||
[Using Multiple Clusters](/docs/concepts/cluster-administration/multiple-clusters/)
|
||||
|
||||
@@ -34,7 +34,7 @@ to build the image:
|
||||
|
||||
```docker
|
||||
FROM busybox
|
||||
ADD _output/local/go/bin/kube-scheduler /usr/local/bin/kube-scheduler
|
||||
ADD ./_output/dockerized/bin/linux/amd64/kube-scheduler /usr/local/bin/kube-scheduler
|
||||
```
|
||||
|
||||
Save the file as `Dockerfile`, build the image and push it to a registry. This example
|
||||
@@ -45,7 +45,7 @@ For more details, please read the GCR
|
||||
|
||||
```shell
|
||||
docker build -t my-kube-scheduler:1.0 .
|
||||
gcloud docker push gcr.io/my-gcp-project/my-kube-scheduler:1.0
|
||||
gcloud docker -- push gcr.io/my-gcp-project/my-kube-scheduler:1.0
|
||||
```
|
||||
|
||||
### 2. Define a Kubernetes Deployment for the scheduler
|
||||
@@ -61,7 +61,7 @@ config. Save it as `my-scheduler.yaml`:
|
||||
{% include code.html language="yaml" file="multiple-schedulers/my-scheduler.yaml" ghlink="/docs/admin/multiple-schedulers/my-scheduler.yaml" %}
|
||||
|
||||
An important thing to note here is that the name of the scheduler specified as an
|
||||
argument to the scheduler command in the container spec should be unique. This is the name that is matched against the value of the optional `scheduler.alpha.kubernetes.io/name` annotation on pods, to determine whether this scheduler is responsible for scheduling a particular pod.
|
||||
argument to the scheduler command in the container spec should be unique. This is the name that is matched against the value of the optional `spec.schedulername` on pods, to determine whether this scheduler is responsible for scheduling a particular pod.
|
||||
|
||||
Please see the
|
||||
[kube-scheduler documentation](/docs/admin/kube-scheduler/) for
|
||||
@@ -92,14 +92,14 @@ pod in this list.
|
||||
### 4. Specify schedulers for pods
|
||||
|
||||
Now that our second scheduler is running, let's create some pods, and direct them to be scheduled by either the default scheduler or the one we just deployed. In order to schedule a given pod using a specific scheduler, we specify the name of the
|
||||
scheduler as an annotation in that pod spec. Let's look at three examples.
|
||||
scheduler in that pod spec. Let's look at three examples.
|
||||
|
||||
|
||||
1. Pod spec without any scheduler annotation
|
||||
- Pod spec without any scheduler name
|
||||
|
||||
{% include code.html language="yaml" file="multiple-schedulers/pod1.yaml" ghlink="/docs/admin/multiple-schedulers/pod1.yaml" %}
|
||||
|
||||
When no scheduler annotation is supplied, the pod is automatically scheduled using the
|
||||
When no scheduler name is supplied, the pod is automatically scheduled using the
|
||||
default-scheduler.
|
||||
|
||||
Save this file as `pod1.yaml` and submit it to the Kubernetes cluster.
|
||||
@@ -108,12 +108,11 @@ scheduler as an annotation in that pod spec. Let's look at three examples.
|
||||
kubectl create -f pod1.yaml
|
||||
```
|
||||
|
||||
2. Pod spec with `default-scheduler` annotation
|
||||
- Pod spec with `default-scheduler`
|
||||
|
||||
{% include code.html language="yaml" file="multiple-schedulers/pod2.yaml" ghlink="/docs/admin/multiple-schedulers/pod2.yaml" %}
|
||||
|
||||
A scheduler is specified by supplying the scheduler name as a value to the annotation
|
||||
with key `scheduler.alpha.kubernetes.io/name`. In this case, we supply the name of the
|
||||
A scheduler is specified by supplying the scheduler name as a value to `spec.schedulername`. In this case, we supply the name of the
|
||||
default scheduler which is `default-scheduler`.
|
||||
|
||||
Save this file as `pod2.yaml` and submit it to the Kubernetes cluster.
|
||||
@@ -122,26 +121,25 @@ scheduler as an annotation in that pod spec. Let's look at three examples.
|
||||
kubectl create -f pod2.yaml
|
||||
```
|
||||
|
||||
3. Pod spec with `my-scheduler` annotation
|
||||
- Pod spec with `my-scheduler`
|
||||
|
||||
{% include code.html language="yaml" file="multiple-schedulers/pod3.yaml" ghlink="/docs/admin/multiple-schedulers/pod3.yaml" %}
|
||||
|
||||
In this case, we specify that this pod should be scheduled using the scheduler that we
|
||||
deployed - `my-scheduler`. Note that the value of the annotation with key
|
||||
`scheduler.alpha.kubernetes.io/name` should match the name supplied to the scheduler
|
||||
deployed - `my-scheduler`. Note that the value of `spec.schedulername` should match the name supplied to the scheduler
|
||||
command as an argument in the deployment config for the scheduler.
|
||||
|
||||
Save this file as `pod3.yaml` and submit it to the Kubernetes cluster.
|
||||
|
||||
```shell
|
||||
kubectl create -f pod3.yaml
|
||||
```
|
||||
```shell
|
||||
kubectl create -f pod3.yaml
|
||||
```
|
||||
|
||||
Verify that all three pods are running.
|
||||
|
||||
```shell
|
||||
kubectl get pods
|
||||
```
|
||||
```shell
|
||||
kubectl get pods
|
||||
```
|
||||
|
||||
### Verifying that the pods were scheduled using the desired schedulers
|
||||
|
||||
@@ -149,9 +147,9 @@ In order to make it easier to work through these examples, we did not verify tha
|
||||
pods were actually scheduled using the desired schedulers. We can verify that by
|
||||
changing the order of pod and deployment config submissions above. If we submit all the
|
||||
pod configs to a Kubernetes cluster before submitting the scheduler deployment config,
|
||||
we see that the pod `annotation-second-scheduler` remains in "Pending" state forever
|
||||
we see that the pod `second-scheduler` remains in "Pending" state forever
|
||||
while the other two pods get scheduled. Once we submit the scheduler deployment config
|
||||
and our new scheduler starts running, the `annotation-second-scheduler` pod gets
|
||||
and our new scheduler starts running, the `second-scheduler` pod gets
|
||||
scheduled as well.
|
||||
|
||||
Alternatively, one could just look at the "Scheduled" entries in the event logs to
|
||||
|
||||
@@ -16,8 +16,11 @@ spec:
|
||||
version: second
|
||||
spec:
|
||||
containers:
|
||||
- command: [/usr/local/bin/kube-scheduler, --address=0.0.0.0,
|
||||
--scheduler-name=my-scheduler]
|
||||
- command:
|
||||
- /usr/local/bin/kube-scheduler
|
||||
- --address=0.0.0.0
|
||||
- --leader-elect=false
|
||||
- --scheduler-name=my-scheduler
|
||||
image: gcr.io/my-gcp-project/my-kube-scheduler:1.0
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
@@ -37,4 +40,4 @@ spec:
|
||||
volumeMounts: []
|
||||
hostNetwork: false
|
||||
hostPID: false
|
||||
volumes: []
|
||||
volumes: []
|
||||
|
||||
@@ -2,11 +2,10 @@ apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: annotation-default-scheduler
|
||||
annotations:
|
||||
scheduler.alpha.kubernetes.io/name: default-scheduler
|
||||
labels:
|
||||
name: multischeduler-example
|
||||
spec:
|
||||
schedulername: default-scheduler
|
||||
containers:
|
||||
- name: pod-with-default-annotation-container
|
||||
image: gcr.io/google_containers/pause:2.0
|
||||
@@ -2,11 +2,10 @@ apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: annotation-second-scheduler
|
||||
annotations:
|
||||
scheduler.alpha.kubernetes.io/name: my-scheduler
|
||||
labels:
|
||||
name: multischeduler-example
|
||||
spec:
|
||||
schedulername: my-scheduler
|
||||
containers:
|
||||
- name: pod-with-second-annotation-container
|
||||
image: gcr.io/google_containers/pause:2.0
|
||||
@@ -229,7 +229,7 @@ cross-zone attachments are not generally permitted by cloud providers:
|
||||
|
||||
```shell
|
||||
> kubectl describe pod mypod | grep Node
|
||||
Node: kubernetes-minion-9vlv/10.240.0.5
|
||||
Node: kubernetes-minion-9vlv/10.240.0.5
|
||||
> kubectl get node kubernetes-minion-9vlv --show-labels
|
||||
NAME STATUS AGE LABELS
|
||||
kubernetes-minion-9vlv Ready 22m beta.kubernetes.io/instance-type=n1-standard-2,failure-domain.beta.kubernetes.io/region=us-central1,failure-domain.beta.kubernetes.io/zone=us-central1-a,kubernetes.io/hostname=kubernetes-minion-9vlv
|
||||
@@ -268,9 +268,9 @@ The pods should be spread across all 3 zones:
|
||||
|
||||
```shell
|
||||
> kubectl describe pod -l app=guestbook | grep Node
|
||||
Node: kubernetes-minion-9vlv/10.240.0.5
|
||||
Node: kubernetes-minion-281d/10.240.0.8
|
||||
Node: kubernetes-minion-olsh/10.240.0.11
|
||||
Node: kubernetes-minion-9vlv/10.240.0.5
|
||||
Node: kubernetes-minion-281d/10.240.0.8
|
||||
Node: kubernetes-minion-olsh/10.240.0.11
|
||||
|
||||
> kubectl get node kubernetes-minion-9vlv kubernetes-minion-281d kubernetes-minion-olsh --show-labels
|
||||
NAME STATUS AGE LABELS
|
||||
|
||||
@@ -44,9 +44,9 @@ You can list the current namespaces in a cluster using:
|
||||
|
||||
```shell
|
||||
$ kubectl get namespaces
|
||||
NAME LABELS STATUS
|
||||
default <none> Active
|
||||
kube-system <none> Active
|
||||
NAME STATUS AGE
|
||||
default Active 11d
|
||||
kube-system Active 11d
|
||||
```
|
||||
|
||||
Kubernetes starts with two initial namespaces:
|
||||
@@ -64,16 +64,16 @@ Or you can get detailed information with:
|
||||
|
||||
```shell
|
||||
$ kubectl describe namespaces <name>
|
||||
Name: default
|
||||
Labels: <none>
|
||||
Status: Active
|
||||
Name: default
|
||||
Labels: <none>
|
||||
Status: Active
|
||||
|
||||
No resource quota.
|
||||
|
||||
Resource Limits
|
||||
Type Resource Min Max Default
|
||||
---- -------- --- --- ---
|
||||
Container cpu - - 100m
|
||||
Type Resource Min Max Default
|
||||
---- -------- --- --- ---
|
||||
Container cpu - - 100m
|
||||
```
|
||||
|
||||
Note that these details show both resource quota (if present) as well as resource limit ranges.
|
||||
|
||||
@@ -145,7 +145,7 @@ dev
|
||||
|
||||
At this point, all requests we make to the Kubernetes cluster from the command line are scoped to the development namespace.
|
||||
|
||||
Let's create some content.
|
||||
Let's create some contents.
|
||||
|
||||
```shell
|
||||
$ kubectl run snowflake --image=kubernetes/serve_hostname --replicas=2
|
||||
|
||||
@@ -6,68 +6,6 @@ assignees:
|
||||
title: Network Plugins
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
__Disclaimer__: Network plugins are in alpha. Its contents will change rapidly.
|
||||
|
||||
Network plugins in Kubernetes come in a few flavors:
|
||||
|
||||
* CNI plugins: adhere to the appc/CNI specification, designed for interoperability.
|
||||
* Kubenet plugin: implements basic `cbr0` using the `bridge` and `host-local` CNI plugins
|
||||
|
||||
## Installation
|
||||
|
||||
The kubelet has a single default network plugin, and a default network common to the entire cluster. It probes for plugins when it starts up, remembers what it found, and executes the selected plugin at appropriate times in the pod lifecycle (this is only true for docker, as rkt manages its own CNI plugins). There are two Kubelet command line parameters to keep in mind when using plugins:
|
||||
|
||||
* `network-plugin-dir`: Kubelet probes this directory for plugins on startup
|
||||
* `network-plugin`: The network plugin to use from `network-plugin-dir`. It must match the name reported by a plugin probed from the plugin directory. For CNI plugins, this is simply "cni".
|
||||
|
||||
## Network Plugin Requirements
|
||||
|
||||
Besides providing the [`NetworkPlugin` interface](https://github.com/kubernetes/kubernetes/tree/{{page.version}}/pkg/kubelet/network/plugins.go) to configure and clean up pod networking, the plugin may also need specific support for kube-proxy. The iptables proxy obviously depends on iptables, and the plugin may need to ensure that container traffic is made available to iptables. For example, if the plugin connects containers to a Linux bridge, the plugin must set the `net/bridge/bridge-nf-call-iptables` sysctl to `1` to ensure that the iptables proxy functions correctly. If the plugin does not use a Linux bridge (but instead something like Open vSwitch or some other mechanism) it should ensure container traffic is appropriately routed for the proxy.
|
||||
|
||||
By default if no kubelet network plugin is specified, the `noop` plugin is used, which sets `net/bridge/bridge-nf-call-iptables=1` to ensure simple configurations (like docker with a bridge) work correctly with the iptables proxy.
|
||||
|
||||
### CNI
|
||||
|
||||
The CNI plugin is selected by passing Kubelet the `--network-plugin=cni` command-line option. Kubelet reads a file from `--cni-conf-dir` (default `/etc/cni/net.d`) and uses the CNI configuration from that file to set up each pod's network. The CNI configuration file must match the [CNI specification](https://github.com/containernetworking/cni/blob/master/SPEC.md#network-configuration), and any required CNI plugins referenced by the configuration must be present in `--cni-bin-dir` (default `/opt/cni/bin`).
|
||||
|
||||
If there are multiple CNI configuration files in the directory, the first one in lexicographic order of file name is used.
|
||||
|
||||
In addition to the CNI plugin specified by the configuration file, Kubernetes requires the standard CNI [`lo`](https://github.com/containernetworking/cni/blob/master/plugins/main/loopback/loopback.go) plugin, at minimum version 0.2.0
|
||||
|
||||
Limitation: Due to [#31307](https://github.com/kubernetes/kubernetes/issues/31307), `HostPort` won't work with CNI networking plugin at the moment. That means all `hostPort` attribute in pod would be simply ignored.
|
||||
|
||||
### kubenet
|
||||
|
||||
Kubenet is a very basic, simple network plugin, on Linux only. It does not, of itself, implement more advanced features like cross-node networking or network policy. It is typically used together with a cloud provider that sets up routing rules for communication between nodes, or in single-node environments.
|
||||
|
||||
Kubenet creates a Linux bridge named `cbr0` and creates a veth pair for each pod with the host end of each pair connected to `cbr0`. The pod end of the pair is assigned an IP address allocated from a range assigned to the node either through configuration or by the controller-manager. `cbr0` is assigned an MTU matching the smallest MTU of an enabled normal interface on the host.
|
||||
|
||||
The plugin requires a few things:
|
||||
|
||||
* The standard CNI `bridge`, `lo` and `host-local` plugins are required, at minimum version 0.2.0. Kubenet will first search for them in `/opt/cni/bin`. Specify `network-plugin-dir` to supply additional search path. The first found match will take effect.
|
||||
* Kubelet must be run with the `--network-plugin=kubenet` argument to enable the plugin
|
||||
* Kubelet should also be run with the `--non-masquerade-cidr=<clusterCidr>` argumment to ensure traffic to IPs outside this range will use IP masquerade.
|
||||
* The node must be assigned an IP subnet through either the `--pod-cidr` kubelet command-line option or the `--allocate-node-cidrs=true --cluster-cidr=<cidr>` controller-manager command-line options.
|
||||
|
||||
### Customizing the MTU (with kubenet)
|
||||
|
||||
The MTU should always be configured correctly to get the best networking performance. Network plugins will usually try
|
||||
to infer a sensible MTU, but sometimes the logic will not result in an optimal MTU. For example, if the
|
||||
Docker bridge or another interface has a small MTU, kubenet will currently select that MTU. Or if you are
|
||||
using IPSEC encapsulation, the MTU must be reduced, and this calculation is out-of-scope for
|
||||
most network plugins.
|
||||
|
||||
Where needed, you can specify the MTU explicitly with the `network-plugin-mtu` kubelet option. For example,
|
||||
on AWS the `eth0` MTU is typically 9001, so you might specify `--network-plugin-mtu=9001`. If you're using IPSEC you
|
||||
might reduce it to allow for encapsulation overhead e.g. `--network-plugin-mtu=8873`.
|
||||
|
||||
This option is provided to the network-plugin; currently **only kubenet supports `network-plugin-mtu`**.
|
||||
|
||||
## Usage Summary
|
||||
|
||||
* `--network-plugin=cni` specifies that we use the `cni` network plugin with actual CNI plugin binaries located in `--cni-bin-dir` (default `/opt/cni/bin`) and CNI plugin configuration located in `--cni-conf-dir` (default `/etc/cni/net.d`).
|
||||
* `--network-plugin=kubenet` specifies that we use the `kubenet` network plugin with CNI `bridge` and `host-local` plugins placed in `/opt/cni/bin` or `network-plugin-dir`.
|
||||
* `--network-plugin-mtu=9001` specifies the MTU to use, currently only used by the `kubenet` network plugin.
|
||||
[Network Plugins](/docs/concepts/cluster-administration/network-plugins/)
|
||||
|
||||
+2
-208
@@ -4,212 +4,6 @@ assignees:
|
||||
title: Networking in Kubernetes
|
||||
---
|
||||
|
||||
Kubernetes approaches networking somewhat differently than Docker does by
|
||||
default. There are 4 distinct networking problems to solve:
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
1. Highly-coupled container-to-container communications: this is solved by
|
||||
[pods](/docs/user-guide/pods/) and `localhost` communications.
|
||||
2. Pod-to-Pod communications: this is the primary focus of this document.
|
||||
3. Pod-to-Service communications: this is covered by [services](/docs/user-guide/services/).
|
||||
4. External-to-Service communications: this is covered by [services](/docs/user-guide/services/).
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
|
||||
## Summary
|
||||
|
||||
Kubernetes assumes that pods can communicate with other pods, regardless of
|
||||
which host they land on. We give every pod its own IP address so you do not
|
||||
need to explicitly create links between pods and you almost never need to deal
|
||||
with mapping container ports to host ports. This creates a clean,
|
||||
backwards-compatible model where pods can be treated much like VMs or physical
|
||||
hosts from the perspectives of port allocation, naming, service discovery, load
|
||||
balancing, application configuration, and migration.
|
||||
|
||||
To achieve this we must impose some requirements on how you set up your cluster
|
||||
networking.
|
||||
|
||||
## Docker model
|
||||
|
||||
Before discussing the Kubernetes approach to networking, it is worthwhile to
|
||||
review the "normal" way that networking works with Docker. By default, Docker
|
||||
uses host-private networking. It creates a virtual bridge, called `docker0` by
|
||||
default, and allocates a subnet from one of the private address blocks defined
|
||||
in [RFC1918](https://tools.ietf.org/html/rfc1918) for that bridge. For each
|
||||
container that Docker creates, it allocates a virtual ethernet device (called
|
||||
`veth`) which is attached to the bridge. The veth is mapped to appear as `eth0`
|
||||
in the container, using Linux namespaces. The in-container `eth0` interface is
|
||||
given an IP address from the bridge's address range.
|
||||
|
||||
The result is that Docker containers can talk to other containers only if they
|
||||
are on the same machine (and thus the same virtual bridge). Containers on
|
||||
different machines can not reach each other - in fact they may end up with the
|
||||
exact same network ranges and IP addresses.
|
||||
|
||||
In order for Docker containers to communicate across nodes, they must be
|
||||
allocated ports on the machine's own IP address, which are then forwarded or
|
||||
proxied to the containers. This obviously means that containers must either
|
||||
coordinate which ports they use very carefully or else be allocated ports
|
||||
dynamically.
|
||||
|
||||
## Kubernetes model
|
||||
|
||||
Coordinating ports across multiple developers is very difficult to do at
|
||||
scale and exposes users to cluster-level issues outside of their control.
|
||||
Dynamic port allocation brings a lot of complications to the system - every
|
||||
application has to take ports as flags, the API servers have to know how to
|
||||
insert dynamic port numbers into configuration blocks, services have to know
|
||||
how to find each other, etc. Rather than deal with this, Kubernetes takes a
|
||||
different approach.
|
||||
|
||||
Kubernetes imposes the following fundamental requirements on any networking
|
||||
implementation (barring any intentional network segmentation policies):
|
||||
|
||||
* all containers can communicate with all other containers without NAT
|
||||
* all nodes can communicate with all containers (and vice-versa) without NAT
|
||||
* the IP that a container sees itself as is the same IP that others see it as
|
||||
|
||||
What this means in practice is that you can not just take two computers
|
||||
running Docker and expect Kubernetes to work. You must ensure that the
|
||||
fundamental requirements are met.
|
||||
|
||||
This model is not only less complex overall, but it is principally compatible
|
||||
with the desire for Kubernetes to enable low-friction porting of apps from VMs
|
||||
to containers. If your job previously ran in a VM, your VM had an IP and could
|
||||
talk to other VMs in your project. This is the same basic model.
|
||||
|
||||
Until now this document has talked about containers. In reality, Kubernetes
|
||||
applies IP addresses at the `Pod` scope - containers within a `Pod` share their
|
||||
network namespaces - including their IP address. This means that containers
|
||||
within a `Pod` can all reach each other's ports on `localhost`. This does imply
|
||||
that containers within a `Pod` must coordinate port usage, but this is no
|
||||
different than processes in a VM. We call this the "IP-per-pod" model. This
|
||||
is implemented in Docker as a "pod container" which holds the network namespace
|
||||
open while "app containers" (the things the user specified) join that namespace
|
||||
with Docker's `--net=container:<id>` function.
|
||||
|
||||
As with Docker, it is possible to request host ports, but this is reduced to a
|
||||
very niche operation. In this case a port will be allocated on the host `Node`
|
||||
and traffic will be forwarded to the `Pod`. The `Pod` itself is blind to the
|
||||
existence or non-existence of host ports.
|
||||
|
||||
## How to achieve this
|
||||
|
||||
There are a number of ways that this network model can be implemented. This
|
||||
document is not an exhaustive study of the various methods, but hopefully serves
|
||||
as an introduction to various technologies and serves as a jumping-off point.
|
||||
|
||||
The following networking options are sorted alphabetically - the order does not
|
||||
imply any preferential status.
|
||||
|
||||
### Contiv
|
||||
|
||||
[Contiv](https://github.com/contiv/netplugin) provides configurable networking (native l3 using BGP, overlay using vxlan, classic l2, or Cisco-SDN/ACI) for various use cases. [Contiv](http://contiv.io) is all open sourced.
|
||||
|
||||
### Flannel
|
||||
|
||||
[Flannel](https://github.com/coreos/flannel#flannel) is a very simple overlay
|
||||
network that satisfies the Kubernetes requirements. Many
|
||||
people have reported success with Flannel and Kubernetes.
|
||||
|
||||
### Google Compute Engine (GCE)
|
||||
|
||||
For the Google Compute Engine cluster configuration scripts, we use [advanced
|
||||
routing](https://cloud.google.com/compute/docs/networking#routing) to
|
||||
assign each VM a subnet (default is `/24` - 254 IPs). Any traffic bound for that
|
||||
subnet will be routed directly to the VM by the GCE network fabric. This is in
|
||||
addition to the "main" IP address assigned to the VM, which is NAT'ed for
|
||||
outbound internet access. A linux bridge (called `cbr0`) is configured to exist
|
||||
on that subnet, and is passed to docker's `--bridge` flag.
|
||||
|
||||
We start Docker with:
|
||||
|
||||
```shell
|
||||
DOCKER_OPTS="--bridge=cbr0 --iptables=false --ip-masq=false"
|
||||
```
|
||||
|
||||
This bridge is created by Kubelet (controlled by the `--network-plugin=kubenet`
|
||||
flag) according to the `Node`'s `spec.podCIDR`.
|
||||
|
||||
Docker will now allocate IPs from the `cbr-cidr` block. Containers can reach
|
||||
each other and `Nodes` over the `cbr0` bridge. Those IPs are all routable
|
||||
within the GCE project network.
|
||||
|
||||
GCE itself does not know anything about these IPs, though, so it will not NAT
|
||||
them for outbound internet traffic. To achieve that we use an iptables rule to
|
||||
masquerade (aka SNAT - to make it seem as if packets came from the `Node`
|
||||
itself) traffic that is bound for IPs outside the GCE project network
|
||||
(10.0.0.0/8).
|
||||
|
||||
```shell
|
||||
iptables -t nat -A POSTROUTING ! -d 10.0.0.0/8 -o eth0 -j MASQUERADE
|
||||
```
|
||||
|
||||
Lastly we enable IP forwarding in the kernel (so the kernel will process
|
||||
packets for bridged containers):
|
||||
|
||||
```shell
|
||||
sysctl net.ipv4.ip_forward=1
|
||||
```
|
||||
|
||||
The result of all this is that all `Pods` can reach each other and can egress
|
||||
traffic to the internet.
|
||||
|
||||
### L2 networks and linux bridging
|
||||
|
||||
If you have a "dumb" L2 network, such as a simple switch in a "bare-metal"
|
||||
environment, you should be able to do something similar to the above GCE setup.
|
||||
Note that these instructions have only been tried very casually - it seems to
|
||||
work, but has not been thoroughly tested. If you use this technique and
|
||||
perfect the process, please let us know.
|
||||
|
||||
Follow the "With Linux Bridge devices" section of [this very nice
|
||||
tutorial](http://blog.oddbit.com/2014/08/11/four-ways-to-connect-a-docker/) from
|
||||
Lars Kellogg-Stedman.
|
||||
|
||||
### Nuage Networks VCS (Virtualized Cloud Services)
|
||||
|
||||
[Nuage](http://www.nuagenetworks.net) provides a highly scalable policy-based Software-Defined Networking (SDN) platform. Nuage uses the open source Open vSwitch for the data plane along with a feature rich SDN Controller built on open standards.
|
||||
|
||||
The Nuage platform uses overlays to provide seamless policy-based networking between Kubernetes Pods and non-Kubernetes environments (VMs and bare metal servers). Nuage's policy abstraction model is designed with applications in mind and makes it easy to declare fine-grained policies for applications.The platform's real-time analytics engine enables visibility and security monitoring for Kubernetes applications.
|
||||
|
||||
### OpenVSwitch
|
||||
|
||||
[OpenVSwitch](/docs/admin/ovs-networking) is a somewhat more mature but also
|
||||
complicated way to build an overlay network. This is endorsed by several of the
|
||||
"Big Shops" for networking.
|
||||
|
||||
### OVN (Open Virtual Networking)
|
||||
|
||||
OVN is an opensource network virtualization solution developed by the
|
||||
Open vSwitch community. It lets one create logical switches, logical routers,
|
||||
stateful ACLs, load-balancers etc to build different virtual networking
|
||||
topologies. The project has a specific Kubernetes plugin and documentation
|
||||
at [ovn-kubernetes](https://github.com/openvswitch/ovn-kubernetes).
|
||||
|
||||
### Project Calico
|
||||
|
||||
[Project Calico](http://docs.projectcalico.org/) is an open source container networking provider and network policy engine.
|
||||
|
||||
Calico provides a highly scalable networking and network policy solution for connecting Kubernetes pods based on the same IP networking principles as the internet. Calico can be deployed without encapsulation or overlays to provide high-performance, high-scale data center networking. Calico also provides fine-grained, intent based network security policy for Kubernetes pods via its distributed firewall.
|
||||
|
||||
Calico can also be run in policy enforcement mode in conjunction with other networking solutions such as Flannel, aka [canal](https://github.com/tigera/canal), or native GCE networking.
|
||||
|
||||
### Romana
|
||||
|
||||
[Romana](http://romana.io) is an open source network and security automation solution that lets you deploy Kubernetes without an overlay network. Romana supports Kubernetes [Network Policy](/docs/user-guide/networkpolicies/) to provide isolation across network namespaces.
|
||||
|
||||
### Weave Net from Weaveworks
|
||||
|
||||
[Weave Net](https://www.weave.works/products/weave-net/) is a
|
||||
resilient and simple to use network for Kubernetes and its hosted applications.
|
||||
Weave Net runs as a [CNI plug-in](https://www.weave.works/docs/net/latest/cni-plugin/)
|
||||
or stand-alone. In either version, it doesn't require any configuration or extra code
|
||||
to run, and in both cases, the network provides one IP address per pod - as is standard for Kubernetes.
|
||||
|
||||
## Other reading
|
||||
|
||||
The early design of the networking model and its rationale, and some future
|
||||
plans are described in more detail in the [networking design
|
||||
document](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/networking.md).
|
||||
[Cluster Networking](/docs/concepts/cluster-administration/networking/)
|
||||
|
||||
+2
-240
@@ -5,244 +5,6 @@ assignees:
|
||||
title: Monitoring Node Health
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
## Node Problem Detector
|
||||
|
||||
*Node problem detector* is a [DaemonSet](/docs/admin/daemons/) monitoring the
|
||||
node health. It collects node problems from various daemons and reports them
|
||||
to the apiserver as [NodeCondition](/docs/admin/node/#node-condition) and
|
||||
[Event](/docs/api-reference/v1/definitions/#_v1_event).
|
||||
|
||||
It supports some known kernel issue detection now, and will detect more and
|
||||
more node problems over time.
|
||||
|
||||
Currently Kubernetes won't take any action on the node conditions and events
|
||||
generated by node problem detector. In the future, a remedy system could be
|
||||
introduced to deal with node problems.
|
||||
|
||||
See more information
|
||||
[here](https://github.com/kubernetes/node-problem-detector).
|
||||
|
||||
## Limitations
|
||||
|
||||
* The kernel issue detection of node problem detector only supports file based
|
||||
kernel log now. It doesn't support log tools like journald.
|
||||
|
||||
* The kernel issue detection of node problem detector has assumption on kernel
|
||||
log format, and now it only works on Ubuntu and Debian. However, it is easy to extend
|
||||
it to [support other log format](/docs/admin/node-problem/#support-other-log-format).
|
||||
|
||||
## Enable/Disable in GCE cluster
|
||||
|
||||
Node problem detector is [running as a cluster addon](cluster-large.md/#addon-resources) enabled by default in the
|
||||
gce cluster.
|
||||
|
||||
You can enable/disable it by setting the environment variable
|
||||
`KUBE_ENABLE_NODE_PROBLEM_DETECTOR` before `kube-up.sh`.
|
||||
|
||||
## Use in Other Environment
|
||||
|
||||
To enable node problem detector in other environment outside of GCE, you can use
|
||||
either `kubectl` or addon pod.
|
||||
|
||||
### Kubectl
|
||||
|
||||
This is the recommended way to start node problem detector outside of GCE. It
|
||||
provides more flexible management, such as overwriting the default
|
||||
configuration to fit it into your environment or detect
|
||||
customized node problems.
|
||||
|
||||
* **Step 1:** Create `node-problem-detector.yaml`:
|
||||
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: node-problem-detector-v0.1
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: node-problem-detector
|
||||
version: v0.1
|
||||
kubernetes.io/cluster-service: "true"
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: node-problem-detector
|
||||
version: v0.1
|
||||
kubernetes.io/cluster-service: "true"
|
||||
spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: node-problem-detector
|
||||
image: gcr.io/google_containers/node-problem-detector:v0.1
|
||||
securityContext:
|
||||
privileged: true
|
||||
resources:
|
||||
limits:
|
||||
cpu: "200m"
|
||||
memory: "100Mi"
|
||||
requests:
|
||||
cpu: "20m"
|
||||
memory: "20Mi"
|
||||
volumeMounts:
|
||||
- name: log
|
||||
mountPath: /log
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: log
|
||||
hostPath:
|
||||
path: /var/log/
|
||||
```
|
||||
|
||||
***Notice that you should make sure the system log directory is right for your
|
||||
OS distro.***
|
||||
|
||||
* **Step 2:** Start node problem detector with `kubectl`:
|
||||
|
||||
```shell
|
||||
kubectl create -f node-problem-detector.yaml
|
||||
```
|
||||
|
||||
### Addon Pod
|
||||
|
||||
This is for those who have their own cluster bootstrap solution, and don't need
|
||||
to overwrite the default configuration. They could leverage the addon pod to
|
||||
further automate the deployment.
|
||||
|
||||
Just create `node-problem-detector.yaml`, and put it under the addon pods directory
|
||||
`/etc/kubernetes/addons/node-problem-detector` on master node.
|
||||
|
||||
## Overwrite the Configuration
|
||||
|
||||
The [default configuration](https://github.com/kubernetes/node-problem-detector/tree/v0.1/config)
|
||||
is embedded when building the docker image of node problem detector.
|
||||
|
||||
However, you can use [ConfigMap](/docs/user-guide/configmap/) to overwrite it
|
||||
following the steps:
|
||||
|
||||
* **Step 1:** Change the config files in `config/`.
|
||||
* **Step 2:** Create the ConfigMap `node-problem-detector-config` with `kubectl create configmap
|
||||
node-problem-detector-config --from-file=config/`.
|
||||
* **Step 3:** Change the `node-problem-detector.yaml` to use the ConfigMap:
|
||||
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: node-problem-detector-v0.1
|
||||
namespace: kube-system
|
||||
labels:
|
||||
k8s-app: node-problem-detector
|
||||
version: v0.1
|
||||
kubernetes.io/cluster-service: "true"
|
||||
spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
k8s-app: node-problem-detector
|
||||
version: v0.1
|
||||
kubernetes.io/cluster-service: "true"
|
||||
spec:
|
||||
hostNetwork: true
|
||||
containers:
|
||||
- name: node-problem-detector
|
||||
image: gcr.io/google_containers/node-problem-detector:v0.1
|
||||
securityContext:
|
||||
privileged: true
|
||||
resources:
|
||||
limits:
|
||||
cpu: "200m"
|
||||
memory: "100Mi"
|
||||
requests:
|
||||
cpu: "20m"
|
||||
memory: "20Mi"
|
||||
volumeMounts:
|
||||
- name: log
|
||||
mountPath: /log
|
||||
readOnly: true
|
||||
- name: config # Overwrite the config/ directory with ConfigMap volume
|
||||
mountPath: /config
|
||||
readOnly: true
|
||||
volumes:
|
||||
- name: log
|
||||
hostPath:
|
||||
path: /var/log/
|
||||
- name: config # Define ConfigMap volume
|
||||
configMap:
|
||||
name: node-problem-detector-config
|
||||
```
|
||||
|
||||
* **Step 4:** Re-create the node problem detector with the new yaml file:
|
||||
|
||||
```shell
|
||||
kubectl delete -f node-problem-detector.yaml # If you have a node-problem-detector running
|
||||
kubectl create -f node-problem-detector.yaml
|
||||
```
|
||||
|
||||
***Notice that this approach only applies to node problem detector started with `kubectl`.***
|
||||
|
||||
For node problem detector running as cluster addon, because addon manager doesn't support
|
||||
ConfigMap, configuration overwriting is not supported now.
|
||||
|
||||
## Kernel Monitor
|
||||
|
||||
*Kernel Monitor* is a problem daemon in node problem detector. It monitors kernel log
|
||||
and detects known kernel issues following predefined rules.
|
||||
|
||||
The Kernel Monitor matches kernel issues according to a set of predefined rule list in
|
||||
[`config/kernel-monitor.json`](https://github.com/kubernetes/node-problem-detector/blob/v0.1/config/kernel-monitor.json).
|
||||
The rule list is extensible, and you can always extend it by [overwriting the
|
||||
configuration](/docs/admin/node-problem/#overwrite-the-configuration).
|
||||
|
||||
### Add New NodeConditions
|
||||
|
||||
To support new node conditions, you can extend the `conditions` field in
|
||||
`config/kernel-monitor.json` with new condition definition:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "NodeConditionType",
|
||||
"reason": "CamelCaseDefaultNodeConditionReason",
|
||||
"message": "arbitrary default node condition message"
|
||||
}
|
||||
```
|
||||
|
||||
### Detect New Problems
|
||||
|
||||
To detect new problems, you can extend the `rules` field in `config/kernel-monitor.json`
|
||||
with new rule definition:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "temporary/permanent",
|
||||
"condition": "NodeConditionOfPermanentIssue",
|
||||
"reason": "CamelCaseShortReason",
|
||||
"message": "regexp matching the issue in the kernel log"
|
||||
}
|
||||
```
|
||||
|
||||
### Change Log Path
|
||||
|
||||
Kernel log in different OS distros may locate in different path. The `log`
|
||||
field in `config/kernel-monitor.json` is the log path inside the container.
|
||||
You can always configure it to match your OS distro.
|
||||
|
||||
### Support Other Log Format
|
||||
|
||||
Kernel monitor uses [`Translator`](https://github.com/kubernetes/node-problem-detector/blob/v0.1/pkg/kernelmonitor/translator/translator.go)
|
||||
plugin to translate kernel log the internal data structure. It is easy to
|
||||
implement a new translator for a new log format.
|
||||
|
||||
## Caveats
|
||||
|
||||
It is recommended to run the node problem detector in your cluster to monitor
|
||||
the node health. However, you should be aware that this will introduce extra
|
||||
resource overhead on each node. Usually this is fine, because:
|
||||
|
||||
* The kernel log is generated relatively slowly.
|
||||
* Resource limit is set for node problem detector.
|
||||
* Even under high load, the resource usage is acceptable.
|
||||
(see [benchmark result](https://github.com/kubernetes/node-problem-detector/issues/2#issuecomment-220255629))
|
||||
[Monitoring Node Health](/docs/tasks/debug-application-cluster/monitor-node-health/)
|
||||
|
||||
+7
-4
@@ -61,7 +61,7 @@ The node condition is represented as a JSON object. For example, the following r
|
||||
]
|
||||
```
|
||||
|
||||
If the Status of the Ready condition is "Unknown" or "False" for longer than the `pod-eviction-timeout`, an argument passed to the [kube-controller-manager](docs/admin/kube-controller-manager/), all of the Pods on the node are scheduled for deletion by the Node Controller. The default eviction timeout duration is **five minutes**. In some cases when the node is unreachable, the apiserver is unable to communicate with the kubelet on it. The decision to delete the pods cannot be communicated to the kubelet until it re-establishes communication with the apiserver. In the meantime, the pods which are scheduled for deletion may continue to run on the partitioned node.
|
||||
If the Status of the Ready condition is "Unknown" or "False" for longer than the `pod-eviction-timeout`, an argument passed to the [kube-controller-manager](/docs/admin/kube-controller-manager/), all of the Pods on the node are scheduled for deletion by the Node Controller. The default eviction timeout duration is **five minutes**. In some cases when the node is unreachable, the apiserver is unable to communicate with the kubelet on it. The decision to delete the pods cannot be communicated to the kubelet until it re-establishes communication with the apiserver. In the meantime, the pods which are scheduled for deletion may continue to run on the partitioned node.
|
||||
|
||||
In versions of Kubernetes prior to 1.5, the node controller would [force delete](/docs/user-guide/pods/#force-deletion-of-pods) these unreachable pods from the apiserver. However, in 1.5 and higher, the node controller does not force delete pods until it is confirmed that they have stopped running in the cluster. One can see these pods which may be running on an unreachable node as being in the "Terminating" or "Unknown" states. In cases where Kubernetes cannot deduce from the underlying infrastructure if a node has permanently left a cluster, the cluster administrator may need to delete the node object by hand. Deleting the node object from Kubernetes causes all the Pod objects running on it to be deleted from the apiserver, freeing up their names.
|
||||
|
||||
@@ -172,10 +172,13 @@ register itself with the API server. This is the preferred pattern, used by mos
|
||||
|
||||
For self-registration, the kubelet is started with the following options:
|
||||
|
||||
- `--api-servers=` - Location of the apiservers.
|
||||
- `--kubeconfig=` - Path to credentials to authenticate itself to the apiserver.
|
||||
- `--cloud-provider=` - How to talk to a cloud provider to read metadata about itself.
|
||||
- `--api-servers` - Location of the apiservers.
|
||||
- `--kubeconfig` - Path to credentials to authenticate itself to the apiserver.
|
||||
- `--cloud-provider` - How to talk to a cloud provider to read metadata about itself.
|
||||
- `--register-node` - Automatically register with the API server.
|
||||
- `--node-ip` IP address of the node.
|
||||
- `--node-labels` - Labels to add when registering the node in the cluster.
|
||||
- `--node-status-update-frequency` - Specifies how often kubelet posts node status to master.
|
||||
|
||||
Currently, any kubelet is authorized to create/modify any node resource, but in practice it only creates/modifies
|
||||
its own. (In the future, we plan to only allow a kubelet to modify its own node resource.)
|
||||
|
||||
@@ -6,364 +6,6 @@ assignees:
|
||||
title: Configuring Out Of Resource Handling
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
The `kubelet` needs to preserve node stability when available compute resources are low.
|
||||
|
||||
This is especially important when dealing with incompressible resources such as memory or disk.
|
||||
|
||||
If either resource is exhausted, the node would become unstable.
|
||||
|
||||
## Eviction Policy
|
||||
|
||||
The `kubelet` can pro-actively monitor for and prevent against total starvation of a compute resource. In
|
||||
cases where it could appear to occur, the `kubelet` can pro-actively fail one or more pods in order to reclaim
|
||||
the starved resource. When the `kubelet` fails a pod, it terminates all containers in the pod, and the `PodPhase`
|
||||
is transitioned to `Failed`.
|
||||
|
||||
### Eviction Signals
|
||||
|
||||
The `kubelet` can support the ability to trigger eviction decisions on the signals described in the
|
||||
table below. The value of each signal is described in the description column based on the `kubelet`
|
||||
summary API.
|
||||
|
||||
| Eviction Signal | Description |
|
||||
|----------------------------|-----------------------------------------------------------------------|
|
||||
| `memory.available` | `memory.available` := `node.status.capacity[memory]` - `node.stats.memory.workingSet` |
|
||||
| `nodefs.available` | `nodefs.available` := `node.stats.fs.available` |
|
||||
| `nodefs.inodesFree` | `nodefs.inodesFree` := `node.stats.fs.inodesFree` |
|
||||
| `imagefs.available` | `imagefs.available` := `node.stats.runtime.imagefs.available` |
|
||||
| `imagefs.inodesFree` | `imagefs.inodesFree` := `node.stats.runtime.imagefs.inodesFree` |
|
||||
|
||||
Each of the above signals support either a literal or percentage based value. The percentage based value
|
||||
is calculated relative to the total capacity associated with each signal.
|
||||
|
||||
`kubelet` supports only two filesystem partitions.
|
||||
|
||||
1. The `nodefs` filesystem that kubelet uses for volumes, daemon logs, etc.
|
||||
1. The `imagefs` filesystem that container runtimes uses for storing images and container writable layers.
|
||||
|
||||
`imagefs` is optional. `kubelet` auto-discovers these filesystems using cAdvisor. `kubelet` does not care about any
|
||||
other filesystems. Any other types of configurations are not currently supported by the kubelet. For example, it is
|
||||
*not OK* to store volumes and logs in a dedicated `filesystem`.
|
||||
|
||||
In future releases, the `kubelet` will deprecate the existing [garbage collection](/docs/admin/garbage-collection/)
|
||||
support in favor of eviction in response to disk pressure.
|
||||
|
||||
### Eviction Thresholds
|
||||
|
||||
The `kubelet` supports the ability to specify eviction thresholds that trigger the `kubelet` to reclaim resources.
|
||||
|
||||
Each threshold is of the following form:
|
||||
|
||||
`<eviction-signal><operator><quantity>`
|
||||
|
||||
* valid `eviction-signal` tokens as defined above.
|
||||
* valid `operator` tokens are `<`
|
||||
* valid `quantity` tokens must match the quantity representation used by Kubernetes
|
||||
* an eviction threshold can be expressed as a percentage if ends with `%` token.
|
||||
|
||||
For example, if a node has `10Gi` of memory, and the desire is to induce eviction
|
||||
if available memory falls below `1Gi`, an eviction threshold can be specified as either
|
||||
of the following (but not both).
|
||||
|
||||
* `memory.available<10%`
|
||||
* `memory.available<1Gi`
|
||||
|
||||
#### Soft Eviction Thresholds
|
||||
|
||||
A soft eviction threshold pairs an eviction threshold with a required
|
||||
administrator specified grace period. No action is taken by the `kubelet`
|
||||
to reclaim resources associated with the eviction signal until that grace
|
||||
period has been exceeded. If no grace period is provided, the `kubelet` will
|
||||
error on startup.
|
||||
|
||||
In addition, if a soft eviction threshold has been met, an operator can
|
||||
specify a maximum allowed pod termination grace period to use when evicting
|
||||
pods from the node. If specified, the `kubelet` will use the lesser value among
|
||||
the `pod.Spec.TerminationGracePeriodSeconds` and the max allowed grace period.
|
||||
If not specified, the `kubelet` will kill pods immediately with no graceful
|
||||
termination.
|
||||
|
||||
To configure soft eviction thresholds, the following flags are supported:
|
||||
|
||||
* `eviction-soft` describes a set of eviction thresholds (e.g. `memory.available<1.5Gi`) that if met over a
|
||||
corresponding grace period would trigger a pod eviction.
|
||||
* `eviction-soft-grace-period` describes a set of eviction grace periods (e.g. `memory.available=1m30s`) that
|
||||
correspond to how long a soft eviction threshold must hold before triggering a pod eviction.
|
||||
* `eviction-max-pod-grace-period` describes the maximum allowed grace period (in seconds) to use when terminating
|
||||
pods in response to a soft eviction threshold being met.
|
||||
|
||||
#### Hard Eviction Thresholds
|
||||
|
||||
A hard eviction threshold has no grace period, and if observed, the `kubelet`
|
||||
will take immediate action to reclaim the associated starved resource. If a
|
||||
hard eviction threshold is met, the `kubelet` will kill the pod immediately
|
||||
with no graceful termination.
|
||||
|
||||
To configure hard eviction thresholds, the following flag is supported:
|
||||
|
||||
* `eviction-hard` describes a set of eviction thresholds (e.g. `memory.available<1Gi`) that if met
|
||||
would trigger a pod eviction.
|
||||
|
||||
The `kubelet` has the following default hard eviction thresholds:
|
||||
|
||||
* `--eviction-hard=memory.available<100Mi`
|
||||
|
||||
### Eviction Monitoring Interval
|
||||
|
||||
The `kubelet` evaluates eviction thresholds per its configured housekeeping interval.
|
||||
|
||||
* `housekeeping-interval` is the interval between container housekeepings.
|
||||
|
||||
### Node Conditions
|
||||
|
||||
The `kubelet` will map one or more eviction signals to a corresponding node condition.
|
||||
|
||||
If a hard eviction threshold has been met, or a soft eviction threshold has been met
|
||||
independent of its associated grace period, the `kubelet` will report a condition that
|
||||
reflects the node is under pressure.
|
||||
|
||||
The following node conditions are defined that correspond to the specified eviction signal.
|
||||
|
||||
| Node Condition | Eviction Signal | Description |
|
||||
|-------------------------|-------------------------------|--------------------------------------------|
|
||||
| `MemoryPressure` | `memory.available` | Available memory on the node has satisfied an eviction threshold |
|
||||
| `DiskPressure` | `nodefs.available`, `nodefs.inodesFree`, `imagefs.available`, or `imagefs.inodesFree` | Available disk space and inodes on either the node's root filesytem or image filesystem has satisfied an eviction threshold |
|
||||
|
||||
The `kubelet` will continue to report node status updates at the frequency specified by
|
||||
`--node-status-update-frequency` which defaults to `10s`.
|
||||
|
||||
### Oscillation of node conditions
|
||||
|
||||
If a node is oscillating above and below a soft eviction threshold, but not exceeding
|
||||
its associated grace period, it would cause the corresponding node condition to
|
||||
constantly oscillate between true and false, and could cause poor scheduling decisions
|
||||
as a consequence.
|
||||
|
||||
To protect against this oscillation, the following flag is defined to control how
|
||||
long the `kubelet` must wait before transitioning out of a pressure condition.
|
||||
|
||||
* `eviction-pressure-transition-period` is the duration for which the `kubelet` has
|
||||
to wait before transitioning out of an eviction pressure condition.
|
||||
|
||||
The `kubelet` would ensure that it has not observed an eviction threshold being met
|
||||
for the specified pressure condition for the period specified before toggling the
|
||||
condition back to `false`.
|
||||
|
||||
### Reclaiming node level resources
|
||||
|
||||
If an eviction threshold has been met and the grace period has passed,
|
||||
the `kubelet` will initiate the process of reclaiming the pressured resource
|
||||
until it has observed the signal has gone below its defined threshold.
|
||||
|
||||
The `kubelet` attempts to reclaim node level resources prior to evicting end-user pods. If
|
||||
disk pressure is observed, the `kubelet` reclaims node level resources differently if the
|
||||
machine has a dedicated `imagefs` configured for the container runtime.
|
||||
|
||||
#### With Imagefs
|
||||
|
||||
If `nodefs` filesystem has met eviction thresholds, `kubelet` will free up disk space in the following order:
|
||||
|
||||
1. Delete dead pods/containers
|
||||
|
||||
If `imagefs` filesystem has met eviction thresholds, `kubelet` will free up disk space in the following order:
|
||||
|
||||
1. Delete all unused images
|
||||
|
||||
#### Without Imagefs
|
||||
|
||||
If `nodefs` filesystem has met eviction thresholds, `kubelet` will free up disk space in the following order:
|
||||
|
||||
1. Delete dead pods/containers
|
||||
1. Delete all unused images
|
||||
|
||||
### Evicting end-user pods
|
||||
|
||||
If the `kubelet` is unable to reclaim sufficient resource on the node,
|
||||
it will begin evicting pods.
|
||||
|
||||
The `kubelet` ranks pods for eviction as follows:
|
||||
|
||||
* by their quality of service
|
||||
* by the consumption of the starved compute resource relative to the pods scheduling request.
|
||||
|
||||
As a result, pod eviction occurs in the following order:
|
||||
|
||||
* `BestEffort` pods that consume the most of the starved resource are failed
|
||||
first.
|
||||
* `Burstable` pods that consume the greatest amount of the starved resource
|
||||
relative to their request for that resource are killed first. If no pod
|
||||
has exceeded its request, the strategy targets the largest consumer of the
|
||||
starved resource.
|
||||
* `Guaranteed` pods that consume the greatest amount of the starved resource
|
||||
relative to their request are killed first. If no pod has exceeded its request,
|
||||
the strategy targets the largest consumer of the starved resource.
|
||||
|
||||
A `Guaranteed` pod is guaranteed to never be evicted because of another pod's
|
||||
resource consumption. If a system daemon (i.e. `kubelet`, `docker`, `journald`, etc.)
|
||||
is consuming more resources than were reserved via `system-reserved` or `kube-reserved` allocations,
|
||||
and the node only has `Guaranteed` pod(s) remaining, then the node must choose to evict a
|
||||
`Guaranteed` pod in order to preserve node stability, and to limit the impact
|
||||
of the unexpected consumption to other `Guaranteed` pod(s).
|
||||
|
||||
Local disk is a `BestEffort` resource. If necessary, `kubelet` will evict pods one at a time to reclaim
|
||||
disk when `DiskPressure` is encountered. The `kubelet` will rank pods by quality of service. If the `kubelet`
|
||||
is responding to `inode` starvation, it will reclaim `inodes` by evicting pods with the lowest quality of service
|
||||
first. If the `kubelet` is responding to lack of available disk, it will rank pods within a quality of service
|
||||
that consumes the largest amount of disk and kill those first.
|
||||
|
||||
#### With Imagefs
|
||||
|
||||
If `nodefs` is triggering evictions, `kubelet` will sort pods based on the usage on `nodefs`
|
||||
- local volumes + logs of all its containers.
|
||||
|
||||
If `imagefs` is triggering evictions, `kubelet` will sort pods based on the writable layer usage of all its containers.
|
||||
|
||||
#### Without Imagefs
|
||||
|
||||
If `nodefs` is triggering evictions, `kubelet` will sort pods based on their total disk usage
|
||||
- local volumes + logs & writable layer of all its containers.
|
||||
|
||||
### Minimum eviction reclaim
|
||||
|
||||
In certain scenarios, eviction of pods could result in reclamation of small amount of resources. This can result in
|
||||
`kubelet` hitting eviction thresholds in repeated successions. In addition to that, eviction of resources like `disk`,
|
||||
is time consuming.
|
||||
|
||||
To mitigate these issues, `kubelet` can have a per-resource `minimum-reclaim`. Whenever `kubelet` observes
|
||||
resource pressure, `kubelet` will attempt to reclaim at least `minimum-reclaim` amount of resource below
|
||||
the configured eviction threshold.
|
||||
|
||||
For example, with the following configuration:
|
||||
|
||||
```
|
||||
--eviction-hard=memory.available<500Mi,nodefs.available<1Gi,imagefs.available<100Gi
|
||||
--eviction-minimum-reclaim="memory.available=0Mi,nodefs.available=500Mi,imagefs.available=2Gi"`
|
||||
```
|
||||
|
||||
If an eviction threshold is triggered for `memory.available`, the `kubelet` will work to ensure
|
||||
that `memory.available` is at least `500Mi`. For `nodefs.available`, the `kubelet` will work
|
||||
to ensure that `nodefs.available` is at least `1.5Gi`, and for `imagefs.available` it will
|
||||
work to ensure that `imagefs.available` is at least `102Gi` before no longer reporting pressure
|
||||
on their associated resources.
|
||||
|
||||
The default `eviction-minimum-reclaim` is `0` for all resources.
|
||||
|
||||
### Scheduler
|
||||
|
||||
The node will report a condition when a compute resource is under pressure. The
|
||||
scheduler views that condition as a signal to dissuade placing additional
|
||||
pods on the node.
|
||||
|
||||
| Node Condition | Scheduler Behavior |
|
||||
| ---------------- | ------------------------------------------------ |
|
||||
| `MemoryPressure` | No new `BestEffort` pods are scheduled to the node. |
|
||||
| `DiskPressure` | No new pods are scheduled to the node. |
|
||||
|
||||
## Node OOM Behavior
|
||||
|
||||
If the node experiences a system OOM (out of memory) event prior to the `kubelet` is able to reclaim memory,
|
||||
the node depends on the [oom_killer](https://lwn.net/Articles/391222/) to respond.
|
||||
|
||||
The `kubelet` sets a `oom_score_adj` value for each container based on the quality of service for the pod.
|
||||
|
||||
| Quality of Service | oom_score_adj |
|
||||
|----------------------------|-----------------------------------------------------------------------|
|
||||
| `Guaranteed` | -998 |
|
||||
| `BestEffort` | 1000 |
|
||||
| `Burstable` | min(max(2, 1000 - (1000 * memoryRequestBytes) / machineMemoryCapacityBytes), 999) |
|
||||
|
||||
If the `kubelet` is unable to reclaim memory prior to a node experiencing system OOM, the `oom_killer` will calculate
|
||||
an `oom_score` based on the percentage of memory its using on the node, and then add the `oom_score_adj` to get an
|
||||
effective `oom_score` for the container, and then kills the container with the highest score.
|
||||
|
||||
The intended behavior should be that containers with the lowest quality of service that
|
||||
are consuming the largest amount of memory relative to the scheduling request should be killed first in order
|
||||
to reclaim memory.
|
||||
|
||||
Unlike pod eviction, if a pod container is OOM killed, it may be restarted by the `kubelet` based on its `RestartPolicy`.
|
||||
|
||||
## Best Practices
|
||||
|
||||
### Schedulable resources and eviction policies
|
||||
|
||||
Let's imagine the following scenario:
|
||||
|
||||
* Node memory capacity: `10Gi`
|
||||
* Operator wants to reserve 10% of memory capacity for system daemons (kernel, `kubelet`, etc.)
|
||||
* Operator wants to evict pods at 95% memory utilization to reduce thrashing and incidence of system OOM.
|
||||
|
||||
To facilitate this scenario, the `kubelet` would be launched as follows:
|
||||
|
||||
```
|
||||
--eviction-hard=memory.available<500Mi
|
||||
--system-reserved=memory=1.5Gi
|
||||
```
|
||||
|
||||
Implicit in this configuration is the understanding that "System reserved" should include the amount of memory
|
||||
covered by the eviction threshold.
|
||||
|
||||
To reach that capacity, either some pod is using more than its request, or the system is using more than `500Mi`.
|
||||
|
||||
This configuration will ensure that the scheduler does not place pods on a node that immediately induce memory pressure
|
||||
and trigger eviction assuming those pods use less than their configured request.
|
||||
|
||||
### DaemonSet
|
||||
|
||||
It is never desired for a `kubelet` to evict a pod that was derived from
|
||||
a `DaemonSet` since the pod will immediately be recreated and rescheduled
|
||||
back to the same node.
|
||||
|
||||
At the moment, the `kubelet` has no ability to distinguish a pod created
|
||||
from `DaemonSet` versus any other object. If/when that information is
|
||||
available, the `kubelet` could pro-actively filter those pods from the
|
||||
candidate set of pods provided to the eviction strategy.
|
||||
|
||||
In general, it is strongly recommended that `DaemonSet` not
|
||||
create `BestEffort` pods to avoid being identified as a candidate pod
|
||||
for eviction. Instead `DaemonSet` should ideally launch `Guaranteed` pods.
|
||||
|
||||
## Deprecation of existing feature flags to reclaim disk
|
||||
|
||||
`kubelet` has been freeing up disk space on demand to keep the node stable.
|
||||
|
||||
As disk based eviction matures, the following `kubelet` flags will be marked for deprecation
|
||||
in favor of the simpler configuration supported around eviction.
|
||||
|
||||
| Existing Flag | New Flag |
|
||||
| ------------- | -------- |
|
||||
| `--image-gc-high-threshold` | `--eviction-hard` or `eviction-soft` |
|
||||
| `--image-gc-low-threshold` | `--eviction-minimum-reclaim` |
|
||||
| `--maximum-dead-containers` | deprecated |
|
||||
| `--maximum-dead-containers-per-container` | deprecated |
|
||||
| `--minimum-container-ttl-duration` | deprecated |
|
||||
| `--low-diskspace-threshold-mb` | `--eviction-hard` or `eviction-soft` |
|
||||
| `--outofdisk-transition-frequency` | `--eviction-pressure-transition-period` |
|
||||
|
||||
## Known issues
|
||||
|
||||
### kubelet may not observe memory pressure right away
|
||||
|
||||
The `kubelet` currently polls `cAdvisor` to collect memory usage stats at a regular interval. If memory usage
|
||||
increases within that window rapidly, the `kubelet` may not observe `MemoryPressure` fast enough, and the `OOMKiller`
|
||||
will still be invoked. We intend to integrate with the `memcg` notification API in a future release to reduce this
|
||||
latency, and instead have the kernel tell us when a threshold has been crossed immediately.
|
||||
|
||||
If you are not trying to achieve extreme utilization, but a sensible measure of overcommit, a viable workaround for
|
||||
this issue is to set eviction thresholds at approximately 75% capacity. This increases the ability of this feature
|
||||
to prevent system OOMs, and promote eviction of workloads so cluster state can rebalance.
|
||||
|
||||
### kubelet may evict more pods than needed
|
||||
|
||||
The pod eviction may evict more pods than needed due to stats collection timing gap. This can be mitigated by adding
|
||||
the ability to get root container stats on an on-demand basis (https://github.com/google/cadvisor/issues/1247) in the future.
|
||||
|
||||
### How kubelet ranks pods for eviction in response to inode exhaustion
|
||||
|
||||
At this time, it is not possible to know how many inodes were consumed by a particular container. If the `kubelet` observes
|
||||
inode exhaustion, it will evict pods by ranking them by quality of service. The following issue has been opened in cadvisor
|
||||
to track per container inode consumption (https://github.com/google/cadvisor/issues/1422) which would allow us to rank pods
|
||||
by inode consumption. For example, this would let us identify a container that created large numbers of 0 byte files, and evict
|
||||
that pod over others.
|
||||
[Configuring Out of Resource Handling](/docs/concepts/cluster-administration/out-of-resource/)
|
||||
|
||||
@@ -6,52 +6,6 @@ assignees:
|
||||
title: Guaranteed Scheduling For Critical Add-On Pods
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
## Overview
|
||||
|
||||
In addition to Kubernetes core components like api-server, scheduler, controller-manager running on a master machine
|
||||
there are a number of add-ons which, for various reasons, must run on a regular cluster node (rather than the Kubernetes master).
|
||||
Some of these add-ons are critical to a fully functional cluster, such as Heapster, DNS, and UI.
|
||||
A cluster may stop working properly if a critical add-on is evicted (either manually or as a side effect of another operation like upgrade)
|
||||
and becomes pending (for example when the cluster is highly utilized and either there are other pending pods that schedule into the space
|
||||
vacated by the evicted critical add-on pod or the amount of resources available on the node changed for some other reason).
|
||||
|
||||
## Rescheduler: guaranteed scheduling of critical add-ons
|
||||
|
||||
Rescheduler ensures that critical add-ons are always scheduled
|
||||
(assuming the cluster has enough resources to run the critical add-on pods in the absence of regular pods).
|
||||
If the scheduler determines that no node has enough free resources to run the critical add-on pod
|
||||
given the pods that are already running in the cluster
|
||||
(indicated by critical add-on pod's pod condition PodScheduled set to false, the reason set to Unschedulable)
|
||||
the rescheduler tries to free up space for the add-on by evicting some pods; then the scheduler will schedule the add-on pod.
|
||||
|
||||
To avoid situation when another pod is scheduled into the space prepared for the critical add-on,
|
||||
the chosen node gets a temporary taint "CriticalAddonsOnly" before the eviction(s)
|
||||
(see [more details](https://github.com/kubernetes/kubernetes/blob/master/docs/design/taint-toleration-dedicated.md)).
|
||||
Each critical add-on has to tolerate it,
|
||||
while the other pods shouldn't tolerate the taint. The taint is removed once the add-on is successfully scheduled.
|
||||
|
||||
*Warning:* currently there is no guarantee which node is chosen and which pods are being killed
|
||||
in order to schedule critical pods, so if rescheduler is enabled your pods might be occasionally
|
||||
killed for this purpose.
|
||||
|
||||
## Config
|
||||
|
||||
Rescheduler doesn't have any user facing configuration (component config) or API.
|
||||
It's enabled by default. It can be disabled:
|
||||
|
||||
* during cluster setup by setting `ENABLE_RESCHEDULER` flag to `false`
|
||||
* on running cluster by deleting its manifest from master node
|
||||
(default path `/etc/kubernetes/manifests/rescheduler.manifest`)
|
||||
|
||||
### Marking add-on as critical
|
||||
|
||||
To be critical an add-on has to run in `kube-system` namespace (configurable via flag)
|
||||
and have the following annotations specified:
|
||||
|
||||
* `scheduler.alpha.kubernetes.io/critical-pod` set to empty string
|
||||
* `scheduler.alpha.kubernetes.io/tolerations` set to `[{"key":"CriticalAddonsOnly", "operator":"Exists"}]`
|
||||
|
||||
The first one marks a pod a critical. The second one is required by Rescheduler algorithm.
|
||||
[Guaranteed Scheduling for Critical Add-On Pods](/docs/concepts/cluster-administration/guaranteed-scheduling-critical-addon-pods/)
|
||||
|
||||
@@ -4,237 +4,6 @@ assignees:
|
||||
title: Resource Quotas
|
||||
---
|
||||
|
||||
When several users or teams share a cluster with a fixed number of nodes,
|
||||
there is a concern that one team could use more than its fair share of resources.
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
Resource quotas are a tool for administrators to address this concern.
|
||||
|
||||
A resource quota, defined by a `ResourceQuota` object, provides constraints that limit
|
||||
aggregate resource consumption per namespace. It can limit the quantity of objects that can
|
||||
be created in a namespace by type, as well as the total amount of compute resources that may
|
||||
be consumed by resources in that project.
|
||||
|
||||
Resource quotas work like this:
|
||||
|
||||
- Different teams work in different namespaces. Currently this is voluntary, but
|
||||
support for making this mandatory via ACLs is planned.
|
||||
- The administrator creates one or more Resource Quota objects for each namespace.
|
||||
- Users create resources (pods, services, etc.) in the namespace, and the quota system
|
||||
tracks usage to ensure it does not exceed hard resource limits defined in a Resource Quota.
|
||||
- If creating or updating a resource violates a quota constraint, the request will fail with HTTP
|
||||
status code `403 FORBIDDEN` with a message explaining the constraint that would have been violated.
|
||||
- If quota is enabled in a namespace for compute resources like `cpu` and `memory`, users must specify
|
||||
requests or limits for those values; otherwise, the quota system may reject pod creation. Hint: Use
|
||||
the LimitRange admission controller to force defaults for pods that make no compute resource requirements.
|
||||
See the [walkthrough](/docs/admin/resourcequota/walkthrough/) for an example to avoid this problem.
|
||||
|
||||
Examples of policies that could be created using namespaces and quotas are:
|
||||
|
||||
- In a cluster with a capacity of 32 GiB RAM, and 16 cores, let team A use 20 Gib and 10 cores,
|
||||
let B use 10GiB and 4 cores, and hold 2GiB and 2 cores in reserve for future allocation.
|
||||
- Limit the "testing" namespace to using 1 core and 1GiB RAM. Let the "production" namespace
|
||||
use any amount.
|
||||
|
||||
In the case where the total capacity of the cluster is less than the sum of the quotas of the namespaces,
|
||||
there may be contention for resources. This is handled on a first-come-first-served basis.
|
||||
|
||||
Neither contention nor changes to quota will affect already created resources.
|
||||
|
||||
## Enabling Resource Quota
|
||||
|
||||
Resource Quota support is enabled by default for many Kubernetes distributions. It is
|
||||
enabled when the apiserver `--admission-control=` flag has `ResourceQuota` as
|
||||
one of its arguments.
|
||||
|
||||
Resource Quota is enforced in a particular namespace when there is a
|
||||
`ResourceQuota` object in that namespace. There should be at most one
|
||||
`ResourceQuota` object in a namespace.
|
||||
|
||||
## Compute Resource Quota
|
||||
|
||||
You can limit the total sum of [compute resources](/docs/user-guide/compute-resources) that can be requested in a given namespace.
|
||||
|
||||
The following resource types are supported:
|
||||
|
||||
| Resource Name | Description |
|
||||
| --------------------- | ----------------------------------------------------------- |
|
||||
| `cpu` | Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value. |
|
||||
| `limits.cpu` | Across all pods in a non-terminal state, the sum of CPU limits cannot exceed this value. |
|
||||
| `limits.memory` | Across all pods in a non-terminal state, the sum of memory limits cannot exceed this value. |
|
||||
| `memory` | Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value. |
|
||||
| `requests.cpu` | Across all pods in a non-terminal state, the sum of CPU requests cannot exceed this value. |
|
||||
| `requests.memory` | Across all pods in a non-terminal state, the sum of memory requests cannot exceed this value. |
|
||||
|
||||
## Storage Resource Quota
|
||||
|
||||
You can limit the total sum of [storage resources](/docs/user-guide/persistent-volumes) that can be requested in a given namespace.
|
||||
|
||||
In addition, you can limit consumption of storage resources based on associated storage-class.
|
||||
|
||||
| Resource Name | Description |
|
||||
| --------------------- | ----------------------------------------------------------- |
|
||||
| `requests.storage` | Across all persistent volume claims, the sum of storage requests cannot exceed this value. |
|
||||
| `persistentvolumeclaims` | The total number of [persistent volume claims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) that can exist in the namespace. |
|
||||
| `<storage-class-name>.storageclass.storage.k8s.io/requests.storage` | Across all persistent volume claims associated with the storage-class-name, the sum of storage requests cannot exceed this value. |
|
||||
| `<storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims` | Across all persistent volume claims associated with the storage-class-name, the total number of [persistent volume claims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) that can exist in the namespace. |
|
||||
|
||||
For example, if an operator wants to quota storage with `gold` storage class separate from `bronze` storage class, the operator can
|
||||
define a quota as follows:
|
||||
|
||||
* `gold.storageclass.storage.k8s.io/requests.storage: 500Gi`
|
||||
* `bronze.storageclass.storage.k8s.io/requests.storage: 100Gi`
|
||||
|
||||
## Object Count Quota
|
||||
|
||||
The number of objects of a given type can be restricted. The following types
|
||||
are supported:
|
||||
|
||||
| Resource Name | Description |
|
||||
| ------------------------------- | ------------------------------------------------- |
|
||||
| `configmaps` | The total number of config maps that can exist in the namespace. |
|
||||
| `persistentvolumeclaims` | The total number of [persistent volume claims](/docs/user-guide/persistent-volumes/#persistentvolumeclaims) that can exist in the namespace. |
|
||||
| `pods` | The total number of pods in a non-terminal state that can exist in the namespace. A pod is in a terminal state if `status.phase in (Failed, Succeeded)` is true. |
|
||||
| `replicationcontrollers` | The total number of replication controllers that can exist in the namespace. |
|
||||
| `resourcequotas` | The total number of [resource quotas](/docs/admin/admission-controllers/#resourcequota) that can exist in the namespace. |
|
||||
| `services` | The total number of services that can exist in the namespace. |
|
||||
| `services.loadbalancers` | The total number of services of type load balancer that can exist in the namespace. |
|
||||
| `services.nodeports` | The total number of services of type node port that can exist in the namespace. |
|
||||
| `secrets` | The total number of secrets that can exist in the namespace. |
|
||||
|
||||
For example, `pods` quota counts and enforces a maximum on the number of `pods`
|
||||
created in a single namespace.
|
||||
|
||||
You might want to set a pods quota on a namespace
|
||||
to avoid the case where a user creates many small pods and exhausts the cluster's
|
||||
supply of Pod IPs.
|
||||
|
||||
## Quota Scopes
|
||||
|
||||
Each quota can have an associated set of scopes. A quota will only measure usage for a resource if it matches
|
||||
the intersection of enumerated scopes.
|
||||
|
||||
When a scope is added to the quota, it limits the number of resources it supports to those that pertain to the scope.
|
||||
Resources specified on the quota outside of the allowed set results in a validation error.
|
||||
|
||||
| Scope | Description |
|
||||
| ----- | ----------- |
|
||||
| `Terminating` | Match pods where `spec.activeDeadlineSeconds >= 0` |
|
||||
| `NotTerminating` | Match pods where `spec.activeDeadlineSeconds is nil` |
|
||||
| `BestEffort` | Match pods that have best effort quality of service. |
|
||||
| `NotBestEffort` | Match pods that do not have best effort quality of service. |
|
||||
|
||||
The `BestEffort` scope restricts a quota to tracking the following resource: `pods`
|
||||
|
||||
The `Terminating`, `NotTerminating`, and `NotBestEffort` scopes restrict a quota to tracking the following resources:
|
||||
|
||||
* `cpu`
|
||||
* `limits.cpu`
|
||||
* `limits.memory`
|
||||
* `memory`
|
||||
* `pods`
|
||||
* `requests.cpu`
|
||||
* `requests.memory`
|
||||
|
||||
## Requests vs Limits
|
||||
|
||||
When allocating compute resources, each container may specify a request and a limit value for either CPU or memory.
|
||||
The quota can be configured to quota either value.
|
||||
|
||||
If the quota has a value specified for `requests.cpu` or `requests.memory`, then it requires that every incoming
|
||||
container makes an explicit request for those resources. If the quota has a value specified for `limits.cpu` or `limits.memory`,
|
||||
then it requires that every incoming container specifies an explicit limit for those resources.
|
||||
|
||||
## Viewing and Setting Quotas
|
||||
|
||||
Kubectl supports creating, updating, and viewing quotas:
|
||||
|
||||
```shell
|
||||
$ kubectl create namespace myspace
|
||||
|
||||
$ cat <<EOF > compute-resources.yaml
|
||||
apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: compute-resources
|
||||
spec:
|
||||
hard:
|
||||
pods: "4"
|
||||
requests.cpu: "1"
|
||||
requests.memory: 1Gi
|
||||
limits.cpu: "2"
|
||||
limits.memory: 2Gi
|
||||
EOF
|
||||
$ kubectl create -f ./compute-resources.yaml --namespace=myspace
|
||||
|
||||
$ cat <<EOF > object-counts.yaml
|
||||
apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: object-counts
|
||||
spec:
|
||||
hard:
|
||||
configmaps: "10"
|
||||
persistentvolumeclaims: "4"
|
||||
replicationcontrollers: "20"
|
||||
secrets: "10"
|
||||
services: "10"
|
||||
services.loadbalancers: "2"
|
||||
EOF
|
||||
$ kubectl create -f ./object-counts.yaml --namespace=myspace
|
||||
|
||||
$ kubectl get quota --namespace=myspace
|
||||
NAME AGE
|
||||
compute-resources 30s
|
||||
object-counts 32s
|
||||
|
||||
$ kubectl describe quota compute-resources --namespace=myspace
|
||||
Name: compute-resources
|
||||
Namespace: myspace
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
limits.cpu 0 2
|
||||
limits.memory 0 2Gi
|
||||
pods 0 4
|
||||
requests.cpu 0 1
|
||||
requests.memory 0 1Gi
|
||||
|
||||
$ kubectl describe quota object-counts --namespace=myspace
|
||||
Name: object-counts
|
||||
Namespace: myspace
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
configmaps 0 10
|
||||
persistentvolumeclaims 0 4
|
||||
replicationcontrollers 0 20
|
||||
secrets 1 10
|
||||
services 0 10
|
||||
services.loadbalancers 0 2
|
||||
```
|
||||
|
||||
## Quota and Cluster Capacity
|
||||
|
||||
Resource Quota objects are independent of the Cluster Capacity. They are
|
||||
expressed in absolute units. So, if you add nodes to your cluster, this does *not*
|
||||
automatically give each namespace the ability to consume more resources.
|
||||
|
||||
Sometimes more complex policies may be desired, such as:
|
||||
|
||||
- proportionally divide total cluster resources among several teams.
|
||||
- allow each tenant to grow resource usage as needed, but have a generous
|
||||
limit to prevent accidental resource exhaustion.
|
||||
- detect demand from one namespace, add nodes, and increase quota.
|
||||
|
||||
Such policies could be implemented using ResourceQuota as a building-block, by
|
||||
writing a 'controller' which watches the quota usage and adjusts the quota
|
||||
hard limits of each namespace according to other signals.
|
||||
|
||||
Note that resource quota divides up aggregate cluster resources, but it creates no
|
||||
restrictions around nodes: pods from several namespaces may run on the same node.
|
||||
|
||||
## Example
|
||||
|
||||
See a [detailed example for how to use resource quota](/docs/admin/resourcequota/walkthrough/).
|
||||
|
||||
## Read More
|
||||
|
||||
See [ResourceQuota design doc](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/admission_control_resource_quota.md) for more information.
|
||||
[Resource Quotas](/docs/concepts/policy/resource-quotas/)
|
||||
|
||||
@@ -4,75 +4,8 @@ assignees:
|
||||
- janetkuo
|
||||
title: Limiting Storage Consumption
|
||||
---
|
||||
This example demonstrates an easy way to limit the amount of storage consumed in a namespace.
|
||||
|
||||
The following resources are used in the demonstration:
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
* [Resource Quota](/docs/admin/resourcequota/)
|
||||
* [Limit Range](/docs/admin/limitrange/)
|
||||
* [Persistent Volume Claim](/docs/user-guide/persistent-volumes/)
|
||||
[Limiting Storage Consumption](/docs/tasks/administer-cluster/limit-storage-consumption/)
|
||||
|
||||
This example assumes you have a functional Kubernetes setup.
|
||||
|
||||
## Limiting Storage Consumption
|
||||
|
||||
The cluster-admin is operating a cluster on behalf of a user population and the admin wants to control
|
||||
how much storage a single namespace can consume in order to control cost.
|
||||
|
||||
The admin would like to limit:
|
||||
|
||||
1. The number of persistent volume claims in a namespace
|
||||
2. The amount of storage each claim can request
|
||||
3. The amount of cumulative storage the namespace can have
|
||||
|
||||
|
||||
## LimitRange to limit requests for storage
|
||||
|
||||
Adding a `LimitRange` to a namespace enforces storage request sizes to a minimum and maximum. Storage is requested
|
||||
via `PersistentVolumeClaim`. The admission controller that enforces limit ranges will reject any PVC that is above or below
|
||||
the values set by the admin.
|
||||
|
||||
In this example, a PVC requesting 10Gi of storage would be rejected because it exceeds the 2Gi max.
|
||||
|
||||
```
|
||||
apiVersion: v1
|
||||
kind: LimitRange
|
||||
metadata:
|
||||
name: storagelimits
|
||||
spec:
|
||||
limits:
|
||||
- type: PersistentVolumeClaim
|
||||
max:
|
||||
storage: 2Gi
|
||||
min:
|
||||
storage: 1Gi
|
||||
```
|
||||
|
||||
Minimum storage requests are used when the underlying storage provider requires certain minimums. For example,
|
||||
AWS EBS volumes have a 1Gi minimum requirement.
|
||||
|
||||
## StorageQuota to limit PVC count and cumulative storage capacity
|
||||
|
||||
Admins can limit the number of PVCs in a namespace as well as the cumulative capacity of those PVCs. New PVCs that exceed
|
||||
either maximum value will be rejected.
|
||||
|
||||
In this example, a 6th PVC in the namespace would be rejected because it exceeds the maximum count of 5. Alternatively,
|
||||
a 5Gi maximum quota when combined with the 2Gi max limit above, cannot have 3 PVCs where each has 2Gi. That would be 6Gi requested
|
||||
for a namespace capped at 5Gi.
|
||||
|
||||
```
|
||||
apiVersion: v1
|
||||
kind: ResourceQuota
|
||||
metadata:
|
||||
name: storagequota
|
||||
spec:
|
||||
hard:
|
||||
persistentvolumeclaims: "5"
|
||||
requests.storage: "5Gi"
|
||||
```
|
||||
|
||||
## Summary
|
||||
|
||||
A limit range can put a ceiling on how much storage is requested while a resource quota can effectively cap the storage
|
||||
consumed by a namespace through claim counts and cumulative storage capacity. The allows a cluster-admin to plan their
|
||||
cluster's storage budget without risk of any one project going over their allotment.
|
||||
|
||||
@@ -5,362 +5,6 @@ assignees:
|
||||
title: Applying Resource Quotas and Limits
|
||||
---
|
||||
|
||||
This example demonstrates a typical setup to control for resource usage in a namespace.
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
It demonstrates using the following resources:
|
||||
|
||||
* [Namespace](/docs/admin/namespaces)
|
||||
* [Resource Quota](/docs/admin/resourcequota/)
|
||||
* [Limit Range](/docs/admin/limitrange/)
|
||||
|
||||
This example assumes you have a functional Kubernetes setup.
|
||||
|
||||
## Scenario
|
||||
|
||||
The cluster-admin is operating a cluster on behalf of a user population and the cluster-admin
|
||||
wants to control the amount of resources that can be consumed in a particular namespace to promote
|
||||
fair sharing of the cluster and control cost.
|
||||
|
||||
The cluster-admin has the following goals:
|
||||
|
||||
* Limit the amount of compute resource for running pods
|
||||
* Limit the number of persistent volume claims to control access to storage
|
||||
* Limit the number of load balancers to control cost
|
||||
* Prevent the use of node ports to preserve scarce resources
|
||||
* Provide default compute resource requests to enable better scheduling decisions
|
||||
|
||||
## Step 1: Create a namespace
|
||||
|
||||
This example will work in a custom namespace to demonstrate the concepts involved.
|
||||
|
||||
Let's create a new namespace called quota-example:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/resourcequota/namespace.yaml
|
||||
namespace "quota-example" created
|
||||
$ kubectl get namespaces
|
||||
NAME STATUS AGE
|
||||
default Active 2m
|
||||
kube-system Active 2m
|
||||
quota-example Active 39s
|
||||
```
|
||||
|
||||
## Step 2: Apply an object-count quota to the namespace
|
||||
|
||||
The cluster-admin wants to control the following resources:
|
||||
|
||||
* persistent volume claims
|
||||
* load balancers
|
||||
* node ports
|
||||
|
||||
Let's create a simple quota that controls object counts for those resource types in this namespace.
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/resourcequota/object-counts.yaml --namespace=quota-example
|
||||
resourcequota "object-counts" created
|
||||
```
|
||||
|
||||
The quota system will observe that a quota has been created, and will calculate consumption
|
||||
in the namespace in response. This should happen quickly.
|
||||
|
||||
Let's describe the quota to see what is currently being consumed in this namespace:
|
||||
|
||||
```shell
|
||||
$ kubectl describe quota object-counts --namespace=quota-example
|
||||
Name: object-counts
|
||||
Namespace: quota-example
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
persistentvolumeclaims 0 2
|
||||
services.loadbalancers 0 2
|
||||
services.nodeports 0 0
|
||||
```
|
||||
|
||||
The quota system will now prevent users from creating more than the specified amount for each resource.
|
||||
|
||||
|
||||
## Step 3: Apply a compute-resource quota to the namespace
|
||||
|
||||
To limit the amount of compute resource that can be consumed in this namespace,
|
||||
let's create a quota that tracks compute resources.
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/resourcequota/compute-resources.yaml --namespace=quota-example
|
||||
resourcequota "compute-resources" created
|
||||
```
|
||||
|
||||
Let's describe the quota to see what is currently being consumed in this namespace:
|
||||
|
||||
```shell
|
||||
$ kubectl describe quota compute-resources --namespace=quota-example
|
||||
Name: compute-resources
|
||||
Namespace: quota-example
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
limits.cpu 0 2
|
||||
limits.memory 0 2Gi
|
||||
pods 0 4
|
||||
requests.cpu 0 1
|
||||
requests.memory 0 1Gi
|
||||
```
|
||||
|
||||
The quota system will now prevent the namespace from having more than 4 non-terminal pods. In
|
||||
addition, it will enforce that each container in a pod makes a `request` and defines a `limit` for
|
||||
`cpu` and `memory`.
|
||||
|
||||
## Step 4: Applying default resource requests and limits
|
||||
|
||||
Pod authors rarely specify resource requests and limits for their pods.
|
||||
|
||||
Since we applied a quota to our project, let's see what happens when an end-user creates a pod that has unbounded
|
||||
cpu and memory by creating an nginx container.
|
||||
|
||||
To demonstrate, lets create a deployment that runs nginx:
|
||||
|
||||
```shell
|
||||
$ kubectl run nginx --image=nginx --replicas=1 --namespace=quota-example
|
||||
deployment "nginx" created
|
||||
```
|
||||
|
||||
Now let's look at the pods that were created.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods --namespace=quota-example
|
||||
```
|
||||
|
||||
What happened? I have no pods! Let's describe the deployment to get a view of what is happening.
|
||||
|
||||
```shell
|
||||
$ kubectl describe deployment nginx --namespace=quota-example
|
||||
Name: nginx
|
||||
Namespace: quota-example
|
||||
CreationTimestamp: Mon, 06 Jun 2016 16:11:37 -0400
|
||||
Labels: run=nginx
|
||||
Selector: run=nginx
|
||||
Replicas: 0 updated | 1 total | 0 available | 1 unavailable
|
||||
StrategyType: RollingUpdate
|
||||
MinReadySeconds: 0
|
||||
RollingUpdateStrategy: 1 max unavailable, 1 max surge
|
||||
OldReplicaSets: <none>
|
||||
NewReplicaSet: nginx-3137573019 (0/1 replicas created)
|
||||
...
|
||||
```
|
||||
|
||||
A deployment created a corresponding replica set and attempted to size it to create a single pod.
|
||||
|
||||
Let's look at the replica set to get more detail.
|
||||
|
||||
```shell
|
||||
$ kubectl describe rs nginx-3137573019 --namespace=quota-example
|
||||
Name: nginx-3137573019
|
||||
Namespace: quota-example
|
||||
Image(s): nginx
|
||||
Selector: pod-template-hash=3137573019,run=nginx
|
||||
Labels: pod-template-hash=3137573019
|
||||
run=nginx
|
||||
Replicas: 0 current / 1 desired
|
||||
Pods Status: 0 Running / 0 Waiting / 0 Succeeded / 0 Failed
|
||||
No volumes.
|
||||
Events:
|
||||
FirstSeen LastSeen Count From SubobjectPath Type Reason Message
|
||||
--------- -------- ----- ---- ------------- -------- ------ -------
|
||||
4m 7s 11 {replicaset-controller } Warning FailedCreate Error creating: pods "nginx-3137573019-" is forbidden: Failed quota: compute-resources: must specify limits.cpu,limits.memory,requests.cpu,requests.memory
|
||||
```
|
||||
|
||||
The Kubernetes API server is rejecting the replica set requests to create a pod because our pods
|
||||
do not specify `requests` or `limits` for `cpu` and `memory`.
|
||||
|
||||
So let's set some default values for the amount of `cpu` and `memory` a pod can consume:
|
||||
|
||||
```shell
|
||||
$ kubectl create -f docs/admin/resourcequota/limits.yaml --namespace=quota-example
|
||||
limitrange "limits" created
|
||||
$ kubectl describe limits limits --namespace=quota-example
|
||||
Name: limits
|
||||
Namespace: quota-example
|
||||
Type Resource Min Max Default Request Default Limit Max Limit/Request Ratio
|
||||
---- -------- --- --- --------------- ------------- -----------------------
|
||||
Container memory - - 256Mi 512Mi -
|
||||
Container cpu - - 100m 200m -
|
||||
```
|
||||
|
||||
If the Kubernetes API server observes a request to create a pod in this namespace, and the containers
|
||||
in that pod do not make any compute resource requests, a default request and default limit will be applied
|
||||
as part of admission control.
|
||||
|
||||
In this example, each pod created will have compute resources equivalent to the following:
|
||||
|
||||
```shell
|
||||
$ kubectl run nginx \
|
||||
--image=nginx \
|
||||
--replicas=1 \
|
||||
--requests=cpu=100m,memory=256Mi \
|
||||
--limits=cpu=200m,memory=512Mi \
|
||||
--namespace=quota-example
|
||||
```
|
||||
|
||||
Now that we have applied default compute resources for our namespace, our replica set should be able to create
|
||||
its pods.
|
||||
|
||||
```shell
|
||||
$ kubectl get pods --namespace=quota-example
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
nginx-3137573019-fvrig 1/1 Running 0 6m
|
||||
```
|
||||
|
||||
And if we print out our quota usage in the namespace:
|
||||
|
||||
```shell
|
||||
$ kubectl describe quota --namespace=quota-example
|
||||
Name: compute-resources
|
||||
Namespace: quota-example
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
limits.cpu 200m 2
|
||||
limits.memory 512Mi 2Gi
|
||||
pods 1 4
|
||||
requests.cpu 100m 1
|
||||
requests.memory 256Mi 1Gi
|
||||
|
||||
|
||||
Name: object-counts
|
||||
Namespace: quota-example
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
persistentvolumeclaims 0 2
|
||||
services.loadbalancers 0 2
|
||||
services.nodeports 0 0
|
||||
```
|
||||
|
||||
As you can see, the pod that was created is consuming explicit amounts of compute resources, and the usage is being
|
||||
tracked by Kubernetes properly.
|
||||
|
||||
## Step 5: Advanced quota scopes
|
||||
|
||||
Let's imagine you did not want to specify default compute resource consumption in your namespace.
|
||||
|
||||
Instead, you want to let users run a specific number of `BestEffort` pods in their namespace to take
|
||||
advantage of slack compute resources, and then require that users make an explicit resource request for
|
||||
pods that require a higher quality of service.
|
||||
|
||||
Let's create a new namespace with two quotas to demonstrate this behavior:
|
||||
|
||||
```shell
|
||||
$ kubectl create namespace quota-scopes
|
||||
namespace "quota-scopes" created
|
||||
$ kubectl create -f docs/admin/resourcequota/best-effort.yaml --namespace=quota-scopes
|
||||
resourcequota "best-effort" created
|
||||
$ kubectl create -f docs/admin/resourcequota/not-best-effort.yaml --namespace=quota-scopes
|
||||
resourcequota "not-best-effort" created
|
||||
$ kubectl describe quota --namespace=quota-scopes
|
||||
Name: best-effort
|
||||
Namespace: quota-scopes
|
||||
Scopes: BestEffort
|
||||
* Matches all pods that have best effort quality of service.
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
pods 0 10
|
||||
|
||||
|
||||
Name: not-best-effort
|
||||
Namespace: quota-scopes
|
||||
Scopes: NotBestEffort
|
||||
* Matches all pods that do not have best effort quality of service.
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
limits.cpu 0 2
|
||||
limits.memory 0 2Gi
|
||||
pods 0 4
|
||||
requests.cpu 0 1
|
||||
requests.memory 0 1Gi
|
||||
```
|
||||
|
||||
In this scenario, a pod that makes no compute resource requests will be tracked by the `best-effort` quota.
|
||||
|
||||
A pod that does make compute resource requests will be tracked by the `not-best-effort` quota.
|
||||
|
||||
Let's demonstrate this by creating two deployments:
|
||||
|
||||
```shell
|
||||
$ kubectl run best-effort-nginx --image=nginx --replicas=8 --namespace=quota-scopes
|
||||
deployment "best-effort-nginx" created
|
||||
$ kubectl run not-best-effort-nginx \
|
||||
--image=nginx \
|
||||
--replicas=2 \
|
||||
--requests=cpu=100m,memory=256Mi \
|
||||
--limits=cpu=200m,memory=512Mi \
|
||||
--namespace=quota-scopes
|
||||
deployment "not-best-effort-nginx" created
|
||||
```
|
||||
|
||||
Even though no default limits were specified, the `best-effort-nginx` deployment will create
|
||||
all 8 pods. This is because it is tracked by the `best-effort` quota, and the `not-best-effort`
|
||||
quota will just ignore it. The `not-best-effort` quota will track the `not-best-effort-nginx`
|
||||
deployment since it creates pods with `Burstable` quality of service.
|
||||
|
||||
Let's list the pods in the namespace:
|
||||
|
||||
```shell
|
||||
$ kubectl get pods --namespace=quota-scopes
|
||||
NAME READY STATUS RESTARTS AGE
|
||||
best-effort-nginx-3488455095-2qb41 1/1 Running 0 51s
|
||||
best-effort-nginx-3488455095-3go7n 1/1 Running 0 51s
|
||||
best-effort-nginx-3488455095-9o2xg 1/1 Running 0 51s
|
||||
best-effort-nginx-3488455095-eyg40 1/1 Running 0 51s
|
||||
best-effort-nginx-3488455095-gcs3v 1/1 Running 0 51s
|
||||
best-effort-nginx-3488455095-rq8p1 1/1 Running 0 51s
|
||||
best-effort-nginx-3488455095-udhhd 1/1 Running 0 51s
|
||||
best-effort-nginx-3488455095-zmk12 1/1 Running 0 51s
|
||||
not-best-effort-nginx-2204666826-7sl61 1/1 Running 0 23s
|
||||
not-best-effort-nginx-2204666826-ke746 1/1 Running 0 23s
|
||||
```
|
||||
|
||||
As you can see, all 10 pods have been allowed to be created.
|
||||
|
||||
Let's describe current quota usage in the namespace:
|
||||
|
||||
```shell
|
||||
$ kubectl describe quota --namespace=quota-scopes
|
||||
Name: best-effort
|
||||
Namespace: quota-scopes
|
||||
Scopes: BestEffort
|
||||
* Matches all pods that have best effort quality of service.
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
pods 8 10
|
||||
|
||||
|
||||
Name: not-best-effort
|
||||
Namespace: quota-scopes
|
||||
Scopes: NotBestEffort
|
||||
* Matches all pods that do not have best effort quality of service.
|
||||
Resource Used Hard
|
||||
-------- ---- ----
|
||||
limits.cpu 400m 2
|
||||
limits.memory 1Gi 2Gi
|
||||
pods 2 4
|
||||
requests.cpu 200m 1
|
||||
requests.memory 512Mi 1Gi
|
||||
```
|
||||
|
||||
As you can see, the `best-effort` quota has tracked the usage for the 8 pods we created in
|
||||
the `best-effort-nginx` deployment, and the `not-best-effort` quota has tracked the usage for
|
||||
the 2 pods we created in the `not-best-effort-nginx` quota.
|
||||
|
||||
Scopes provide a mechanism to subdivide the set of resources that are tracked by
|
||||
any quota document to allow greater flexibility in how operators deploy and track resource
|
||||
consumption.
|
||||
|
||||
In addition to `BestEffort` and `NotBestEffort` scopes, there are scopes to restrict
|
||||
long-running versus time-bound pods. The `Terminating` scope will match any pod
|
||||
where `spec.activeDeadlineSeconds is not nil`. The `NotTerminating` scope will match any pod
|
||||
where `spec.activeDeadlineSeconds is nil`. These scopes allow you to quota pods based on their
|
||||
anticipated permanence on a node in your cluster.
|
||||
|
||||
## Summary
|
||||
|
||||
Actions that consume node resources for cpu and memory can be subject to hard quota limits defined by the namespace quota.
|
||||
|
||||
Any action that consumes those resources can be tweaked, or can pick up namespace level defaults to meet your end goal.
|
||||
|
||||
Quota can be apportioned based on quality of service and anticipated permanence on a node in your cluster.
|
||||
[Applying Resource Quotas and Limits](/docs/tasks/configure-pod-container/apply-resource-quota-limit/)
|
||||
|
||||
+6
-6
@@ -10,11 +10,11 @@ The Salt scripts are shared across multiple hosting providers and depending on w
|
||||
|
||||
## Salt cluster setup
|
||||
|
||||
The **salt-master** service runs on the kubernetes-master [(except on the default GCE setup)](#standalone-salt-configuration-on-gce).
|
||||
The **salt-master** service runs on the kubernetes-master [(except on the default GCE and OpenStack-Heat setup)](#standalone-salt-configuration-on-gce-and-others).
|
||||
|
||||
The **salt-minion** service runs on the kubernetes-master and each kubernetes-node in the cluster.
|
||||
|
||||
Each salt-minion service is configured to interact with the **salt-master** service hosted on the kubernetes-master via the **master.conf** file [(except on GCE)](#standalone-salt-configuration-on-gce).
|
||||
Each salt-minion service is configured to interact with the **salt-master** service hosted on the kubernetes-master via the **master.conf** file [(except on GCE and OpenStack-Heat)](#standalone-salt-configuration-on-gce-and-others).
|
||||
|
||||
```shell
|
||||
[root@kubernetes-master] $ cat /etc/salt/minion.d/master.conf
|
||||
@@ -25,15 +25,15 @@ The salt-master is contacted by each salt-minion and depending upon the machine
|
||||
|
||||
If you are running the Vagrant based environment, the **salt-api** service is running on the kubernetes-master. It is configured to enable the vagrant user to introspect the salt cluster in order to find out about machines in the Vagrant environment via a REST API.
|
||||
|
||||
## Standalone Salt Configuration on GCE
|
||||
## Standalone Salt Configuration on GCE and others
|
||||
|
||||
On GCE, the master and nodes are all configured as [standalone minions](http://docs.saltstack.com/en/latest/topics/tutorials/standalone_minion.html). The configuration for each VM is derived from the VM's [instance metadata](https://cloud.google.com/compute/docs/metadata) and then stored in Salt grains (`/etc/salt/minion.d/grains.conf`) and pillars (`/srv/salt-overlay/pillar/cluster-params.sls`) that local Salt uses to enforce state.
|
||||
On GCE and OpenStack, using the Openstack-Heat provider, the master and nodes are all configured as [standalone minions](http://docs.saltstack.com/en/latest/topics/tutorials/standalone_minion.html). The configuration for each VM is derived from the VM's [instance metadata](https://cloud.google.com/compute/docs/metadata) and then stored in Salt grains (`/etc/salt/minion.d/grains.conf`) and pillars (`/srv/salt-overlay/pillar/cluster-params.sls`) that local Salt uses to enforce state.
|
||||
|
||||
All remaining sections that refer to master/minion setups should be ignored for GCE. One fallout of the GCE setup is that the Salt mine doesn't exist - there is no sharing of configuration amongst nodes.
|
||||
All remaining sections that refer to master/minion setups should be ignored for GCE and OpenStack. One fallout of this setup is that the Salt mine doesn't exist - there is no sharing of configuration amongst nodes.
|
||||
|
||||
## Salt security
|
||||
|
||||
*(Not applicable on default GCE setup.)*
|
||||
*(Not applicable on default GCE and OpenStack-Heat setup.)*
|
||||
|
||||
Security is not enabled on the salt-master, and the salt-master is configured to auto-accept incoming requests from minions. It is not recommended to use this security configuration in production environments without deeper study. (In some environments this isn't as bad as it might sound if the salt master port isn't externally accessible and you trust everyone on your network.)
|
||||
|
||||
|
||||
@@ -71,8 +71,9 @@ account. To create additional API tokens for a service account, create a secret
|
||||
of type `ServiceAccountToken` with an annotation referencing the service
|
||||
account, and the controller will update it with a generated token:
|
||||
|
||||
```json
|
||||
secret.json:
|
||||
|
||||
```json
|
||||
{
|
||||
"kind": "Secret",
|
||||
"apiVersion": "v1",
|
||||
@@ -100,4 +101,4 @@ kubectl delete secret mysecretname
|
||||
### Service Account Controller
|
||||
|
||||
Service Account Controller manages ServiceAccount inside namespaces, and ensures
|
||||
a ServiceAccount named "default" exists in every active namespace.
|
||||
a ServiceAccount named "default" exists in every active namespace.
|
||||
|
||||
+2
-119
@@ -4,123 +4,6 @@ assignees:
|
||||
title: Static Pods
|
||||
---
|
||||
|
||||
**If you are running clustered Kubernetes and are using static pods to run a pod on every node, you should probably be using a [DaemonSet](/docs/admin/daemons/)!**
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
*Static pods* are managed directly by kubelet daemon on a specific node, without API server observing it. It does not have associated any replication controller, kubelet daemon itself watches it and restarts it when it crashes. There is no health check though. Static pods are always bound to one kubelet daemon and always run on the same node with it.
|
||||
|
||||
Kubelet automatically creates so-called *mirror pod* on Kubernetes API server for each static pod, so the pods are visible there, but they cannot be controlled from the API server.
|
||||
|
||||
## Static pod creation
|
||||
|
||||
Static pod can be created in two ways: either by using configuration file(s) or by HTTP.
|
||||
|
||||
### Configuration files
|
||||
|
||||
The configuration files are just standard pod definition in json or yaml format in specific directory. Use `kubelet --pod-manifest-path=<the directory>` to start kubelet daemon, which periodically scans the directory and creates/deletes static pods as yaml/json files appear/disappear there.
|
||||
|
||||
For example, this is how to start a simple web server as a static pod:
|
||||
|
||||
1. Choose a node where we want to run the static pod. In this example, it's `my-node1`.
|
||||
|
||||
```shell
|
||||
[joe@host ~] $ ssh my-node1
|
||||
```
|
||||
|
||||
2. Choose a directory, say `/etc/kubelet.d` and place a web server pod definition there, e.g. `/etc/kubernetes.d/static-web.yaml`:
|
||||
|
||||
```shell
|
||||
[root@my-node1 ~] $ mkdir /etc/kubernetes.d/
|
||||
[root@my-node1 ~] $ cat <<EOF >/etc/kubernetes.d/static-web.yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: static-web
|
||||
labels:
|
||||
role: myrole
|
||||
spec:
|
||||
containers:
|
||||
- name: web
|
||||
image: nginx
|
||||
ports:
|
||||
- name: web
|
||||
containerPort: 80
|
||||
protocol: TCP
|
||||
EOF
|
||||
```
|
||||
|
||||
2. Configure your kubelet daemon on the node to use this directory by running it with `--pod-manifest-path=/etc/kubelet.d/` argument. On Fedora edit `/etc/kubernetes/kubelet` to include this line:
|
||||
|
||||
```conf
|
||||
KUBELET_ARGS="--cluster-dns=10.254.0.10 --cluster-domain=kube.local --pod-manifest-path=/etc/kubelet.d/"
|
||||
```
|
||||
|
||||
Instructions for other distributions or Kubernetes installations may vary.
|
||||
|
||||
3. Restart kubelet. On Fedora, this is:
|
||||
|
||||
```shell
|
||||
[root@my-node1 ~] $ systemctl restart kubelet
|
||||
```
|
||||
|
||||
## Pods created via HTTP
|
||||
|
||||
Kubelet periodically downloads a file specified by `--manifest-url=<URL>` argument and interprets it as a json/yaml file with a pod definition. It works the same as `--pod-manifest-path=<directory>`, i.e. it's reloaded every now and then and changes are applied to running static pods (see below).
|
||||
|
||||
## Behavior of static pods
|
||||
|
||||
When kubelet starts, it automatically starts all pods defined in directory specified in `--pod-manifest-path=` or `--manifest-url=` arguments, i.e. our static-web. (It may take some time to pull nginx image, be patient…):
|
||||
|
||||
```shell
|
||||
[joe@my-node1 ~] $ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS NAMES
|
||||
f6d05272b57e nginx:latest "nginx" 8 minutes ago Up 8 minutes k8s_web.6f802af4_static-web-fk-node1_default_67e24ed9466ba55986d120c867395f3c_378e5f3c
|
||||
```
|
||||
|
||||
If we look at our Kubernetes API server (running on host `my-master`), we see that a new mirror-pod was created there too:
|
||||
|
||||
```shell
|
||||
[joe@host ~] $ ssh my-master
|
||||
[joe@my-master ~] $ kubectl get pods
|
||||
POD IP CONTAINER(S) IMAGE(S) HOST LABELS STATUS CREATED MESSAGE
|
||||
static-web-my-node1 172.17.0.3 my-node1/192.168.100.71 role=myrole Running 11 minutes
|
||||
web nginx Running 11 minutes
|
||||
```
|
||||
|
||||
Labels from the static pod are propagated into the mirror-pod and can be used as usual for filtering.
|
||||
|
||||
Notice we cannot delete the pod with the API server (e.g. via [`kubectl`](/docs/user-guide/kubectl/) command), kubelet simply won't remove it.
|
||||
|
||||
```shell
|
||||
[joe@my-master ~] $ kubectl delete pod static-web-my-node1
|
||||
pods/static-web-my-node1
|
||||
[joe@my-master ~] $ kubectl get pods
|
||||
POD IP CONTAINER(S) IMAGE(S) HOST ...
|
||||
static-web-my-node1 172.17.0.3 my-node1/192.168.100.71 ...
|
||||
```
|
||||
|
||||
Back to our `my-node1` host, we can try to stop the container manually and see, that kubelet automatically restarts it in a while:
|
||||
|
||||
```shell
|
||||
[joe@host ~] $ ssh my-node1
|
||||
[joe@my-node1 ~] $ docker stop f6d05272b57e
|
||||
[joe@my-node1 ~] $ sleep 20
|
||||
[joe@my-node1 ~] $ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED ...
|
||||
5b920cbaf8b1 nginx:latest "nginx -g 'daemon of 2 seconds ago ...
|
||||
```
|
||||
|
||||
## Dynamic addition and removal of static pods
|
||||
|
||||
Running kubelet periodically scans the configured directory (`/etc/kubelet.d` in our example) for changes and adds/removes pods as files appear/disappear in this directory.
|
||||
|
||||
```shell
|
||||
[joe@my-node1 ~] $ mv /etc/kubernetes.d/static-web.yaml /tmp
|
||||
[joe@my-node1 ~] $ sleep 20
|
||||
[joe@my-node1 ~] $ docker ps
|
||||
// no nginx container is running
|
||||
[joe@my-node1 ~] $ mv /tmp/static-web.yaml /etc/kubernetes.d/
|
||||
[joe@my-node1 ~] $ sleep 20
|
||||
[joe@my-node1 ~] $ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED ...
|
||||
e7a62e3427f1 nginx:latest "nginx -g 'daemon of 27 seconds ago
|
||||
```
|
||||
[Static Pods](/docs/concepts/cluster-administration/static-pod/)
|
||||
|
||||
+2
-115
@@ -4,119 +4,6 @@ assignees:
|
||||
title: Using Sysctls in a Kubernetes Cluster
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
This document describes how sysctls are used within a Kubernetes cluster.
|
||||
|
||||
## What is a Sysctl?
|
||||
|
||||
In Linux, the sysctl interface allows an administrator to modify kernel
|
||||
parameters at runtime. Parameters are available via the `/proc/sys/` virtual
|
||||
process file system. The parameters cover various subsystems such as:
|
||||
|
||||
- kernel (common prefix: `kernel.`)
|
||||
- networking (common prefix: `net.`)
|
||||
- virtual memory (common prefix: `vm.`)
|
||||
- MDADM (common prefix: `dev.`)
|
||||
- More subsystems are described in [Kernel docs](https://www.kernel.org/doc/Documentation/sysctl/README).
|
||||
|
||||
To get a list of all parameters, you can run
|
||||
|
||||
```
|
||||
$ sudo sysctl -a
|
||||
```
|
||||
|
||||
## Namespaced vs. Node-Level Sysctls
|
||||
|
||||
A number of sysctls are _namespaced_ in today's Linux kernels. This means that
|
||||
they can be set independently for each pod on a node. Being namespaced is a
|
||||
requirement for sysctls to be accessible in a pod context within Kubernetes.
|
||||
|
||||
The following sysctls are known to be _namespaced_:
|
||||
|
||||
- `kernel.shm*`,
|
||||
- `kernel.msg*`,
|
||||
- `kernel.sem`,
|
||||
- `fs.mqueue.*`,
|
||||
- `net.*`.
|
||||
|
||||
Sysctls which are not namespaced are called _node-level_ and must be set
|
||||
manually by the cluster admin, either by means of the underlying Linux
|
||||
distribution of the nodes (e.g. via `/etc/sysctls.conf`) or using a DaemonSet
|
||||
with privileged containers.
|
||||
|
||||
**Note**: it is good practice to consider nodes with special sysctl settings as
|
||||
_tainted_ within a cluster, and only schedule pods onto them which need those
|
||||
sysctl settings. It is suggested to use the Kubernetes [_taints and toleration_
|
||||
feature](/docs/user-guide/kubectl/kubectl_taint.md) to implement this.
|
||||
|
||||
## Safe vs. Unsafe Sysctls
|
||||
|
||||
Sysctls are grouped into _safe_ and _unsafe_ sysctls. In addition to proper
|
||||
namespacing a _safe_ sysctl must be properly _isolated_ between pods on the same
|
||||
node. This means that setting a _safe_ sysctl for one pod
|
||||
|
||||
- must not have any influence on any other pod on the node
|
||||
- must not allow to harm the node's health
|
||||
- must not allow to gain CPU or memory resources outside of the resource limits
|
||||
of a pod.
|
||||
|
||||
By far, most of the _namespaced_ sysctls are not necessarily considered _safe_.
|
||||
|
||||
For Kubernetes 1.4, the following sysctls are supported in the _safe_ set:
|
||||
|
||||
- `kernel.shm_rmid_forced`,
|
||||
- `net.ipv4.ip_local_port_range`,
|
||||
- `net.ipv4.tcp_syncookies`.
|
||||
|
||||
This list will be extended in future Kubernetes versions when the kubelet
|
||||
supports better isolation mechanisms.
|
||||
|
||||
All _safe_ sysctls are enabled by default.
|
||||
|
||||
All _unsafe_ sysctls are disabled by default and must be allowed manually by the
|
||||
cluster admin on a per-node basis. Pods with disabled unsafe sysctls will be
|
||||
scheduled, but will fail to launch.
|
||||
|
||||
**Warning**: Due to their nature of being _unsafe_, the use of _unsafe_ sysctls
|
||||
is at-your-own-risk and can lead to severe problems like wrong behavior of
|
||||
containers, resource shortage or complete breakage of a node.
|
||||
|
||||
## Enabling Unsafe Sysctls
|
||||
|
||||
With the warning above in mind, the cluster admin can allow certain _unsafe_
|
||||
sysctls for very special situations like e.g. high-performance or real-time
|
||||
application tuning. _Unsafe_ sysctls are enabled on a node-by-node basis with a
|
||||
flag of the kubelet, e.g.:
|
||||
|
||||
```shell
|
||||
$ kubelet --experimental-allowed-unsafe-sysctls 'kernel.msg*,net.ipv4.route.min_pmtu' ...
|
||||
```
|
||||
|
||||
Only _namespaced_ sysctls can be enabled this way.
|
||||
|
||||
## Setting Sysctls for a Pod
|
||||
|
||||
The sysctl feature is an alpha API in Kubernetes 1.4. Therefore, sysctls are set
|
||||
using annotations on pods. They apply to all containers in the same pod.
|
||||
|
||||
Here is an example, with different annotations for _safe_ and _unsafe_ sysctls:
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: sysctl-example
|
||||
annotations:
|
||||
security.alpha.kubernetes.io/sysctls: kernel.shm_rmid_forced=1
|
||||
security.alpha.kubernetes.io/unsafe-sysctls: net.ipv4.route.min_pmtu=1000,kernel.msgmax=1 2 3
|
||||
spec:
|
||||
...
|
||||
```
|
||||
|
||||
**Note**: a pod with the _unsafe_ sysctls specified above will fail to launch on
|
||||
any node which has not enabled those two _unsafe_ sysctls explicitly. As with
|
||||
_node-level_ sysctls it is recommended to use [_taints and toleration_
|
||||
feature](/docs/user-guide/kubectl/kubectl_taint.md) or [labels on nodes](/docs
|
||||
/user-guide/labels.md) to schedule those pods onto the right nodes.
|
||||
[Using Sysctls in a Kubernetes Cluster](/docs/concepts/cluster-administration/sysctl-cluster/)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
assignees:
|
||||
- mml
|
||||
title: Cluster Management Guide
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
This document outlines the potentially disruptive changes that exist in the 1.6 release cycle. Operators, administrators, and developers should
|
||||
take note of the changes below in order to maintain continuity across their upgrade process.
|
||||
|
||||
## Cluster defaults set to etcd 3
|
||||
|
||||
In the 1.6 release cycle, the default backend storage layer has been upgraded to fully leverage [etcd 3 capabilities](https://coreos.com/blog/etcd3-a-new-etcd.html) by default.
|
||||
For new clusters, there is nothing an operator will need to do, it should "just work". However, if you are upgrading from a 1.5 cluster, care should be taken to ensure
|
||||
continuity.
|
||||
|
||||
It is possible to maintain v2 compatibility mode while running etcd 3 for an interim period of time. To do this, you will simply need to update an argument passed to your apiserver during
|
||||
startup:
|
||||
|
||||
```
|
||||
$ kube-apiserver --storage-backend='etcd2' $(EXISTING_ARGS)
|
||||
```
|
||||
|
||||
However, for long-term maintenance of the cluster, we recommend that the operator plan an outage window in order to perform a [v2->v3 data upgrade](https://coreos.com/etcd/docs/latest/upgrades/upgrade_3_0.html).
|
||||
@@ -3620,7 +3620,7 @@ The StatefulSet guarantees that a given network identity will always map to the
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">nodeSelector</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection/README">http://kubernetes.io/docs/user-guide/node-selection/README</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection">http://kubernetes.io/docs/user-guide/node-selection</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">object</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
|
||||
@@ -3609,7 +3609,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">nodeSelector</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection/README">http://kubernetes.io/docs/user-guide/node-selection/README</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection">http://kubernetes.io/docs/user-guide/node-selection</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">object</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
|
||||
@@ -3457,7 +3457,7 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">nodeSelector</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection/README">http://kubernetes.io/docs/user-guide/node-selection/README</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection">http://kubernetes.io/docs/user-guide/node-selection</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">object</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
@@ -4617,10 +4617,10 @@ Populated by the system when a graceful deletion is requested. Read-only. More i
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">host</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">Host is the fully qualified domain name of a network host, as defined by RFC 3986. Note the following deviations from the "host" part of the URI as defined in the RFC: 1. IPs are not allowed. Currently an IngressRuleValue can only apply to the<br>
|
||||
IP in the Spec of the parent Ingress.<br>
|
||||
IP in the Spec of the parent Ingress.<br>
|
||||
2. The <code>:</code> delimiter is not respected because ports are not allowed.<br>
|
||||
Currently the port of an Ingress is implicitly :80 for http and<br>
|
||||
:443 for https.<br>
|
||||
Currently the port of an Ingress is implicitly :80 for http and<br>
|
||||
:443 for https.<br>
|
||||
Both these may change in the future. Incoming requests are matched against the host before the IngressRuleValue. If the host is unspecified, the Ingress routes all traffic based on the specified IngressRuleValue.</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">string</p></td>
|
||||
|
||||
@@ -8010,7 +8010,7 @@ Appears In <a href="#pod-v1">Pod</a> <a href="#podtemplatespec-v1">PodTemplateSp
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nodeSelector <br /> <em>object</em></td>
|
||||
<td>NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection/README">http://kubernetes.io/docs/user-guide/node-selection/README</a></td>
|
||||
<td>NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection">http://kubernetes.io/docs/user-guide/node-selection</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>restartPolicy <br /> <em>string</em></td>
|
||||
|
||||
+244
-244
@@ -1,252 +1,252 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo</title>
|
||||
<meta name="keywords" content="javascript, jquery, plugins, scroll, scrollTo, smooth, animation, to, effect, ariel, flesler, window, overflow, element, navigation, customizable" />
|
||||
<meta name="description" content="Demo of jQuery.scrollTo. Lightweight, cross-browser and highly customizable animated scrolling with jQuery, made by Ariel Flesler." />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<link type="text/css" rel="stylesheet" href="css/style.css" />
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
jQuery(function( $ ){
|
||||
/**
|
||||
* Demo binding and preparation, no need to read this part
|
||||
*/
|
||||
//borrowed from jQuery easing plugin
|
||||
//http://gsgd.co.uk/sandbox/jquery.easing.php
|
||||
$.easing.elasout = function(x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
||||
};
|
||||
$('a.back').click(function() {
|
||||
$(this).parents('div.pane').scrollTo(0, 800, { queue:true });
|
||||
$(this).parents('div.section').find('span.message').text( this.title);
|
||||
return false;
|
||||
});
|
||||
//just for the example, to stop the click on the links.
|
||||
$('ul.links').click(function(e){
|
||||
var link = e.target;
|
||||
if (link.target === '_blank') {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
link.blur();
|
||||
if (link.title) {
|
||||
$(this).parent().find('span.message').text(link.title);
|
||||
}
|
||||
});
|
||||
|
||||
// This one is important, many browsers don't reset scroll on refreshes
|
||||
// Reset all scrollable panes to (0,0)
|
||||
$('div.pane').scrollTo(0);
|
||||
// Reset the screen to (0,0)
|
||||
$.scrollTo(0);
|
||||
|
||||
// TOC, shows how to scroll the whole window
|
||||
$('#toc a').click(function() {//$.scrollTo works EXACTLY the same way, but scrolls the whole screen
|
||||
$.scrollTo(this.hash, 1500, { easing:'elasout' });
|
||||
$(this.hash).find('span.message').text(this.title);
|
||||
return false;
|
||||
});
|
||||
|
||||
// Target examples bindings
|
||||
var $target = $('#pane-target');
|
||||
$('#target-examples a').click(function() {
|
||||
$target.stop(true);
|
||||
});
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo</title>
|
||||
<meta name="keywords" content="javascript, jquery, plugins, scroll, scrollTo, smooth, animation, to, effect, ariel, flesler, window, overflow, element, navigation, customizable" />
|
||||
<meta name="description" content="Demo of jQuery.scrollTo. Lightweight, cross-browser and highly customizable animated scrolling with jQuery, made by Ariel Flesler." />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<link type="text/css" rel="stylesheet" href="css/style.css" />
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.min.js"></script>
|
||||
<script type="text/javascript">
|
||||
jQuery(function( $ ){
|
||||
/**
|
||||
* Demo binding and preparation, no need to read this part
|
||||
*/
|
||||
//borrowed from jQuery easing plugin
|
||||
//http://gsgd.co.uk/sandbox/jquery.easing.php
|
||||
$.easing.elasout = function(x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
||||
};
|
||||
$('a.back').click(function() {
|
||||
$(this).parents('div.pane').scrollTo(0, 800, { queue:true });
|
||||
$(this).parents('div.section').find('span.message').text( this.title);
|
||||
return false;
|
||||
});
|
||||
//just for the example, to stop the click on the links.
|
||||
$('ul.links').click(function(e){
|
||||
var link = e.target;
|
||||
if (link.target === '_blank') {
|
||||
return;
|
||||
}
|
||||
e.preventDefault();
|
||||
link.blur();
|
||||
if (link.title) {
|
||||
$(this).parent().find('span.message').text(link.title);
|
||||
}
|
||||
});
|
||||
|
||||
// This one is important, many browsers don't reset scroll on refreshes
|
||||
// Reset all scrollable panes to (0,0)
|
||||
$('div.pane').scrollTo(0);
|
||||
// Reset the screen to (0,0)
|
||||
$.scrollTo(0);
|
||||
|
||||
// TOC, shows how to scroll the whole window
|
||||
$('#toc a').click(function() {//$.scrollTo works EXACTLY the same way, but scrolls the whole screen
|
||||
$.scrollTo(this.hash, 1500, { easing:'elasout' });
|
||||
$(this.hash).find('span.message').text(this.title);
|
||||
return false;
|
||||
});
|
||||
|
||||
// Target examples bindings
|
||||
var $target = $('#pane-target');
|
||||
$('#target-examples a').click(function() {
|
||||
$target.stop(true);
|
||||
});
|
||||
|
||||
$('#relative-selector').click(function() {
|
||||
$target.scrollTo('li:eq(7)', 800);
|
||||
});
|
||||
$('#jquery-object').click(function() {
|
||||
$target.scrollTo($('#pane-target li:eq(14)') , 800);
|
||||
});
|
||||
$('#dom-element').click(function() {
|
||||
$target.scrollTo(document.getElementById('twenty'), 800);
|
||||
});
|
||||
$('#absolute-number').click(function() {
|
||||
$target.scrollTo(150, 800);
|
||||
});
|
||||
$('#absolute-number-hash').click(function() {
|
||||
$target.scrollTo({ top:800, left:700}, 800);
|
||||
});
|
||||
$('#absolute-px').click(function() {
|
||||
$target.scrollTo('520px', 800);
|
||||
});
|
||||
$('#absolute-px-hash').click(function() {
|
||||
$target.scrollTo({top:'110px', left:'290px'}, 800);
|
||||
});
|
||||
$('#relative-px').click(function() {
|
||||
$target.scrollTo('+=100', 500);
|
||||
});
|
||||
$('#relative-px-hash').click(function() {
|
||||
$target.scrollTo({top:'-=100px', left:'+=100'}, 500);
|
||||
});
|
||||
$('#percentage-px').click(function() {
|
||||
$target.scrollTo('50%', 800);
|
||||
});
|
||||
$('#percentage-px-hash').click(function() {
|
||||
$target.scrollTo({top:'50%', left:'20%'}, 800);
|
||||
});
|
||||
|
||||
// Settings examples bindings, they will all scroll to the same place, with different settings
|
||||
var $settings = $('#pane-settings');
|
||||
$('#settings-examples a').click(function() {
|
||||
// before each animation, reset to (0,0), skip this.
|
||||
$settings.stop(true).scrollTo(0);
|
||||
});
|
||||
|
||||
$('#settings-no').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 1000);
|
||||
});
|
||||
$('#settings-axis').click(function() {// only scroll horizontally
|
||||
$settings.scrollTo('li:eq(15)', 1000, { axis:'x' });
|
||||
});
|
||||
$('#settings-duration').click(function() {// it's the same as specifying it in the 2nd argument
|
||||
$settings.scrollTo('li:eq(15)', { duration: 3000 });
|
||||
});
|
||||
$('#settings-easing').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 2500, { easing:'elasout' });
|
||||
});
|
||||
$('#settings-margin').click(function() {//scroll to the "outer" position of the element
|
||||
$settings.scrollTo('li:eq(15)', 1000, { margin:true });
|
||||
});
|
||||
$('#settings-offset').click(function() {//same as { top:-50, left:-50 }
|
||||
$settings.scrollTo('li:eq(15)', 1000, { offset:-50 });
|
||||
});
|
||||
$('#settings-offset-hash').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 1000, { offset:{ top:-5, left:-30 } });
|
||||
});
|
||||
$('#settings-offset-function').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 1000, {offset: function() { return {top:-30, left:-5}; }});
|
||||
});
|
||||
$('#settings-over').click(function() {//same as { top:-50, left:-50 }
|
||||
$settings.scrollTo('li:eq(15)', 1000, { over:0.5 });
|
||||
});
|
||||
$('#settings-over-hash').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 1000, { over:{ top:0.2, left:-0.5 } });
|
||||
});
|
||||
$('#settings-interrupt').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 10000, { interrupt:true });
|
||||
});
|
||||
$('#settings-queue').click(function() {//in this case, having 'axis' as 'xy' or 'yx' matters.
|
||||
$settings.scrollTo('li:eq(15)', 2000, { queue:true });
|
||||
});
|
||||
$('#settings-onAfter').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 2000, {
|
||||
onAfter:function() {
|
||||
$('#settings-message').text('Got there!');
|
||||
}
|
||||
});
|
||||
});
|
||||
$('#settings-onAfterFirst').click(function() {//onAfterFirst exists only when queuing
|
||||
$settings.scrollTo('li:eq(15)', 1600, {
|
||||
queue:true,
|
||||
onAfterFirst:function() {
|
||||
$('#settings-message').text('Got there horizontally!');
|
||||
},
|
||||
onAfter:function() {
|
||||
$('#settings-message').text('Got there vertically!');
|
||||
}
|
||||
});
|
||||
});
|
||||
$('#settings-step').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 2000, {step:function(now) {
|
||||
$('#settings-message').text(now.toFixed(2));
|
||||
}});
|
||||
});
|
||||
$('#settings-progress').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 2000, {progress:function(_, now) {
|
||||
$('#settings-message').text(Math.round(now*100) + '%');
|
||||
}});
|
||||
});
|
||||
$('#settings-fail').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 10000, {interrupt:true, fail:function() {
|
||||
$('#settings-message').text('Scroll interrupted!');
|
||||
}});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
$('#relative-selector').click(function() {
|
||||
$target.scrollTo('li:eq(7)', 800);
|
||||
});
|
||||
$('#jquery-object').click(function() {
|
||||
$target.scrollTo($('#pane-target li:eq(14)') , 800);
|
||||
});
|
||||
$('#dom-element').click(function() {
|
||||
$target.scrollTo(document.getElementById('twenty'), 800);
|
||||
});
|
||||
$('#absolute-number').click(function() {
|
||||
$target.scrollTo(150, 800);
|
||||
});
|
||||
$('#absolute-number-hash').click(function() {
|
||||
$target.scrollTo({ top:800, left:700}, 800);
|
||||
});
|
||||
$('#absolute-px').click(function() {
|
||||
$target.scrollTo('520px', 800);
|
||||
});
|
||||
$('#absolute-px-hash').click(function() {
|
||||
$target.scrollTo({top:'110px', left:'290px'}, 800);
|
||||
});
|
||||
$('#relative-px').click(function() {
|
||||
$target.scrollTo('+=100', 500);
|
||||
});
|
||||
$('#relative-px-hash').click(function() {
|
||||
$target.scrollTo({top:'-=100px', left:'+=100'}, 500);
|
||||
});
|
||||
$('#percentage-px').click(function() {
|
||||
$target.scrollTo('50%', 800);
|
||||
});
|
||||
$('#percentage-px-hash').click(function() {
|
||||
$target.scrollTo({top:'50%', left:'20%'}, 800);
|
||||
});
|
||||
|
||||
// Settings examples bindings, they will all scroll to the same place, with different settings
|
||||
var $settings = $('#pane-settings');
|
||||
$('#settings-examples a').click(function() {
|
||||
// before each animation, reset to (0,0), skip this.
|
||||
$settings.stop(true).scrollTo(0);
|
||||
});
|
||||
|
||||
$('#settings-no').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 1000);
|
||||
});
|
||||
$('#settings-axis').click(function() {// only scroll horizontally
|
||||
$settings.scrollTo('li:eq(15)', 1000, { axis:'x' });
|
||||
});
|
||||
$('#settings-duration').click(function() {// it's the same as specifying it in the 2nd argument
|
||||
$settings.scrollTo('li:eq(15)', { duration: 3000 });
|
||||
});
|
||||
$('#settings-easing').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 2500, { easing:'elasout' });
|
||||
});
|
||||
$('#settings-margin').click(function() {//scroll to the "outer" position of the element
|
||||
$settings.scrollTo('li:eq(15)', 1000, { margin:true });
|
||||
});
|
||||
$('#settings-offset').click(function() {//same as { top:-50, left:-50 }
|
||||
$settings.scrollTo('li:eq(15)', 1000, { offset:-50 });
|
||||
});
|
||||
$('#settings-offset-hash').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 1000, { offset:{ top:-5, left:-30 } });
|
||||
});
|
||||
$('#settings-offset-function').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 1000, {offset: function() { return {top:-30, left:-5}; }});
|
||||
});
|
||||
$('#settings-over').click(function() {//same as { top:-50, left:-50 }
|
||||
$settings.scrollTo('li:eq(15)', 1000, { over:0.5 });
|
||||
});
|
||||
$('#settings-over-hash').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 1000, { over:{ top:0.2, left:-0.5 } });
|
||||
});
|
||||
$('#settings-interrupt').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 10000, { interrupt:true });
|
||||
});
|
||||
$('#settings-queue').click(function() {//in this case, having 'axis' as 'xy' or 'yx' matters.
|
||||
$settings.scrollTo('li:eq(15)', 2000, { queue:true });
|
||||
});
|
||||
$('#settings-onAfter').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 2000, {
|
||||
onAfter:function() {
|
||||
$('#settings-message').text('Got there!');
|
||||
}
|
||||
});
|
||||
});
|
||||
$('#settings-onAfterFirst').click(function() {//onAfterFirst exists only when queuing
|
||||
$settings.scrollTo('li:eq(15)', 1600, {
|
||||
queue:true,
|
||||
onAfterFirst:function() {
|
||||
$('#settings-message').text('Got there horizontally!');
|
||||
},
|
||||
onAfter:function() {
|
||||
$('#settings-message').text('Got there vertically!');
|
||||
}
|
||||
});
|
||||
});
|
||||
$('#settings-step').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 2000, {step:function(now) {
|
||||
$('#settings-message').text(now.toFixed(2));
|
||||
}});
|
||||
});
|
||||
$('#settings-progress').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 2000, {progress:function(_, now) {
|
||||
$('#settings-message').text(Math.round(now*100) + '%');
|
||||
}});
|
||||
});
|
||||
$('#settings-fail').click(function() {
|
||||
$settings.scrollTo('li:eq(15)', 10000, {interrupt:true, fail:function() {
|
||||
$('#settings-message').text('Scroll interrupted!');
|
||||
}});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>jQuery.scrollTo <strong>by Ariel Flesler</strong></h1>
|
||||
|
||||
<div id="toc" class="part">
|
||||
<h3>Table of contents <strong>(try these)</strong></h3>
|
||||
<ul>
|
||||
<li><a title="$.scrollTo('#target-examples', 800, {easing:'elasout'});" href="#target-examples">Ways to specify the target</a></li>
|
||||
<li><a title="$.scrollTo('#settings-examples', 800, {easing:'elasout'});" href="#settings-examples">Settings</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="links" class="part">
|
||||
<h3>Links</h3>
|
||||
<ul>
|
||||
<li><a target="_blank" href="https://github.com/flesler/jquery.scrollTo">Github</a></li>
|
||||
<li><a target="_blank" href="http://flesler.blogspot.com/2007/10/jqueryscrollto.html">Main blog article</a></li>
|
||||
<li><a target="_blank" href="http://demos.flesler.com/jquery/localScroll/">LocalScroll Demo</a></li>
|
||||
<li><a target="_blank" href="http://demos.flesler.com/jquery/serialScroll/">SerialScroll Demo</a></li>
|
||||
<li><a target="_blank" href="index.old.html">Old Demo</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="target-examples" class="section part">
|
||||
<h3>Ways to specify the target <span id="target-message" class="message">Click an option, to see it in action</span></h3>
|
||||
<ul class="links">
|
||||
<li><a title="$(...).scrollTo('li:eq(7)', 800);" id="relative-selector" href="#">Relative selector</a></li>
|
||||
<li><a title="$(...).scrollTo($('div li:eq(14)'), 800);" id="jquery-object" href="#">jQuery object</a></li>
|
||||
<li><a title="$(...).scrollTo(document.getElementById('twenty'), 800);" id="dom-element" href="#">DOM Element</a></li>
|
||||
<li><a title="$(...).scrollTo(150, 800);" id="absolute-number" href="#">Absolute number</a></li>
|
||||
<li><a title="$(...).scrollTo({ top:800, left:700}, 800);" id="absolute-number-hash" href="#">Absolute number(hash)</a></li>
|
||||
</ul>
|
||||
<ul class="links">
|
||||
<li><a title="$(...).scrollTo('520px', 800);" id="absolute-px" href="#">Absolute px</a></li>
|
||||
<li><a title="$(...).scrollTo({top:'110px', left:'290px'}, 800);" id="absolute-px-hash" href="#">Absolute px(hash)</a></li>
|
||||
<li><a title="$(...).scrollTo('+=100px', 800);" id="relative-px" href="#">Relative px</a></li>
|
||||
<li><a title="$(...).scrollTo({top:'-=100px', left:'+=100'}, 800);" id="relative-px-hash" href="#">Relative px(hash)</a></li>
|
||||
<li><a title="$(...).scrollTo('50%', 800);" id="percentage-px" href="#">Percent</a></li>
|
||||
<li><a title="$(...).scrollTo({top:'50%', left:'20%'}, 800);" id="percentage-px-hash" href="#">Percent(hash)</a></li>
|
||||
</ul>
|
||||
<div id="pane-target" class="pane">
|
||||
<ul class="elements" style="height:1011px; width:1820px;">
|
||||
<li><p>0</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>1</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>2</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>3</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>4</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>5</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>6</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>7</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>8</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>9</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>10</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>11</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>12</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>13</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>14</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>15</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>16</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>17</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>18</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>19</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li id="twenty"><p>20</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>21</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>22</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>23</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>24</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>25</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>26</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>27</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>28</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>29</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="settings-examples" class="section part">
|
||||
<h3>Settings <span id="settings-message" class="message">The examples shown here, are summarized for brevity</span></h3>
|
||||
<ul class="links">
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000);" id="settings-no" href="#">no settings</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {axis:'x'});//only scroll on this axis (can be x, y, xy or yx)" id="settings-axis" href="#">axis</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {margin:true});//deduct the margin and border from the final position" id="settings-margin" href="#">margin</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {offset:-50});//add or deduct from the final position" id="settings-offset" href="#">offset</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {offset: {top:-5, left:-30} });" id="settings-offset-hash" href="#">offset(hash)</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {offset: function() { return {top:-30, left:-5}; }});" id="settings-offset-function" href="#">offset(function)</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {over:0.5});//add or deduct a fraction of its height/width" id="settings-over" href="#">over</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {over:{top:0.2, left:-0.5});" id="settings-over-hash" href="#">over(hash)</a></li>
|
||||
<li><a title="Scroll manually to interrupt the animation" id="settings-interrupt" href="#">interrupt</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1600, {onAfter:function() { } });//called after the scrolling ends" id="settings-onAfter" href="#">onAfter</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1600, {queue:true, onAfterFirst:function() { } });//called after the first axis scrolled" id="settings-onAfterFirst" href="#">onAfterFirst</a></li>
|
||||
</ul>
|
||||
<h4>Settings inherited from <a href="http://api.jquery.com/animate/#animate-properties-options" target="_blank">$().animate()</a></h4>
|
||||
<ul class="links">
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', {duration:3000});//another way of calling the plugin" id="settings-duration" href="#">duration</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 2500, {easing:'elasout'});//specify an easing equation" id="settings-easing" href="#">easing</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1600, {queue:true});//scroll one axis, then the other" id="settings-queue" href="#">queue</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 2500, {step:function() { }'});//specify a step function" id="settings-step" href="#">step</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 2500, {progress:function() { }'});//specify a progress function" id="settings-progress" href="#">progress</a></li>
|
||||
<li><a title="Scroll manually to interrupt and trigger the callback" id="settings-fail" href="#">fail</a></li>
|
||||
<li><a href="http://api.jquery.com/animate/#animate-properties-options" target="_blank">more</a></li>
|
||||
</ul>
|
||||
<div id="pane-settings" class="pane">
|
||||
<ul class="elements" style="height:1062px;width:1877px;">
|
||||
<li><p>0</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>1</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>2</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>3</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>4</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>5</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>6</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>7</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>8</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>9</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>10</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>11</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>12</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>13</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>14</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>15</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>16</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>17</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>18</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>19</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>20</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>21</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>22</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>23</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>24</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>25</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>26</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>27</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>28</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>29</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<h1>jQuery.scrollTo <strong>by Ariel Flesler</strong></h1>
|
||||
|
||||
<div id="toc" class="part">
|
||||
<h3>Table of contents <strong>(try these)</strong></h3>
|
||||
<ul>
|
||||
<li><a title="$.scrollTo('#target-examples', 800, {easing:'elasout'});" href="#target-examples">Ways to specify the target</a></li>
|
||||
<li><a title="$.scrollTo('#settings-examples', 800, {easing:'elasout'});" href="#settings-examples">Settings</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="links" class="part">
|
||||
<h3>Links</h3>
|
||||
<ul>
|
||||
<li><a target="_blank" href="https://github.com/flesler/jquery.scrollTo">Github</a></li>
|
||||
<li><a target="_blank" href="http://flesler.blogspot.com/2007/10/jqueryscrollto.html">Main blog article</a></li>
|
||||
<li><a target="_blank" href="http://demos.flesler.com/jquery/localScroll/">LocalScroll Demo</a></li>
|
||||
<li><a target="_blank" href="http://demos.flesler.com/jquery/serialScroll/">SerialScroll Demo</a></li>
|
||||
<li><a target="_blank" href="index.old.html">Old Demo</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div id="target-examples" class="section part">
|
||||
<h3>Ways to specify the target <span id="target-message" class="message">Click an option, to see it in action</span></h3>
|
||||
<ul class="links">
|
||||
<li><a title="$(...).scrollTo('li:eq(7)', 800);" id="relative-selector" href="#">Relative selector</a></li>
|
||||
<li><a title="$(...).scrollTo($('div li:eq(14)'), 800);" id="jquery-object" href="#">jQuery object</a></li>
|
||||
<li><a title="$(...).scrollTo(document.getElementById('twenty'), 800);" id="dom-element" href="#">DOM Element</a></li>
|
||||
<li><a title="$(...).scrollTo(150, 800);" id="absolute-number" href="#">Absolute number</a></li>
|
||||
<li><a title="$(...).scrollTo({ top:800, left:700}, 800);" id="absolute-number-hash" href="#">Absolute number(hash)</a></li>
|
||||
</ul>
|
||||
<ul class="links">
|
||||
<li><a title="$(...).scrollTo('520px', 800);" id="absolute-px" href="#">Absolute px</a></li>
|
||||
<li><a title="$(...).scrollTo({top:'110px', left:'290px'}, 800);" id="absolute-px-hash" href="#">Absolute px(hash)</a></li>
|
||||
<li><a title="$(...).scrollTo('+=100px', 800);" id="relative-px" href="#">Relative px</a></li>
|
||||
<li><a title="$(...).scrollTo({top:'-=100px', left:'+=100'}, 800);" id="relative-px-hash" href="#">Relative px(hash)</a></li>
|
||||
<li><a title="$(...).scrollTo('50%', 800);" id="percentage-px" href="#">Percent</a></li>
|
||||
<li><a title="$(...).scrollTo({top:'50%', left:'20%'}, 800);" id="percentage-px-hash" href="#">Percent(hash)</a></li>
|
||||
</ul>
|
||||
<div id="pane-target" class="pane">
|
||||
<ul class="elements" style="height:1011px; width:1820px;">
|
||||
<li><p>0</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>1</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>2</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>3</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>4</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>5</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>6</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>7</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>8</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>9</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>10</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>11</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>12</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>13</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>14</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>15</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>16</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>17</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>18</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>19</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li id="twenty"><p>20</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>21</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>22</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>23</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>24</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>25</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>26</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>27</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>28</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>29</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div id="settings-examples" class="section part">
|
||||
<h3>Settings <span id="settings-message" class="message">The examples shown here, are summarized for brevity</span></h3>
|
||||
<ul class="links">
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000);" id="settings-no" href="#">no settings</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {axis:'x'});//only scroll on this axis (can be x, y, xy or yx)" id="settings-axis" href="#">axis</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {margin:true});//deduct the margin and border from the final position" id="settings-margin" href="#">margin</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {offset:-50});//add or deduct from the final position" id="settings-offset" href="#">offset</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {offset: {top:-5, left:-30} });" id="settings-offset-hash" href="#">offset(hash)</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {offset: function() { return {top:-30, left:-5}; }});" id="settings-offset-function" href="#">offset(function)</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {over:0.5});//add or deduct a fraction of its height/width" id="settings-over" href="#">over</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1000, {over:{top:0.2, left:-0.5});" id="settings-over-hash" href="#">over(hash)</a></li>
|
||||
<li><a title="Scroll manually to interrupt the animation" id="settings-interrupt" href="#">interrupt</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1600, {onAfter:function() { } });//called after the scrolling ends" id="settings-onAfter" href="#">onAfter</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1600, {queue:true, onAfterFirst:function() { } });//called after the first axis scrolled" id="settings-onAfterFirst" href="#">onAfterFirst</a></li>
|
||||
</ul>
|
||||
<h4>Settings inherited from <a href="http://api.jquery.com/animate/#animate-properties-options" target="_blank">$().animate()</a></h4>
|
||||
<ul class="links">
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', {duration:3000});//another way of calling the plugin" id="settings-duration" href="#">duration</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 2500, {easing:'elasout'});//specify an easing equation" id="settings-easing" href="#">easing</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 1600, {queue:true});//scroll one axis, then the other" id="settings-queue" href="#">queue</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 2500, {step:function() { }'});//specify a step function" id="settings-step" href="#">step</a></li>
|
||||
<li><a title="$(...).scrollTo('li:eq(15)', 2500, {progress:function() { }'});//specify a progress function" id="settings-progress" href="#">progress</a></li>
|
||||
<li><a title="Scroll manually to interrupt and trigger the callback" id="settings-fail" href="#">fail</a></li>
|
||||
<li><a href="http://api.jquery.com/animate/#animate-properties-options" target="_blank">more</a></li>
|
||||
</ul>
|
||||
<div id="pane-settings" class="pane">
|
||||
<ul class="elements" style="height:1062px;width:1877px;">
|
||||
<li><p>0</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>1</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>2</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>3</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>4</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>5</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>6</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>7</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>8</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>9</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>10</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>11</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>12</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>13</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>14</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>15</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>16</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>17</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>18</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>19</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>20</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>21</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>22</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>23</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>24</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>25</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>26</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>27</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>28</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li><li><p>29</p><a href="#" title="$(...).scrollTo(0, 800, {queue:true});" class="back">go back</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+121
-121
@@ -1,128 +1,128 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.ScrollTo</title>
|
||||
<meta name="keywords" content="javascript, jquery, plugins, scroll, scrollTo, smooth, animation, to, effect, ariel, flesler, window, overflow, element, navigation, customizable" />
|
||||
<meta name="description" content="Demo of jQuery.scrollTo. Lightweight, cross-browser and highly customizable animated scrolling with jQuery, made by Ariel Flesler." />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<link type="text/css" rel="stylesheet" href="css/style.old.css" />
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript">
|
||||
jQuery(function( $ ){
|
||||
//borrowed from jQuery easing plugin
|
||||
//http://gsgd.co.uk/sandbox/jquery.easing.php
|
||||
$.easing.elasout = function(x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
||||
};
|
||||
$('button').click(function(){//this is not the cleanest way to do this, I'm just keeping it short.
|
||||
var index = parseInt( $(this).prev('input').val() ) || 0;
|
||||
var $c = $(this).parent().next();
|
||||
$c.stop().scrollTo('li:eq('+index+')', {duration:2500, easing:'elasout',axis:$c.attr('id')});
|
||||
});
|
||||
$('#btn_screen').click(function(){
|
||||
$.scrollTo( $('#txt_screen').val(), {duration:2500} );
|
||||
});
|
||||
$('div.container a').click(function(){
|
||||
var $c = $(this).parents('.container');
|
||||
$c.stop().scrollTo( 0, {duration:2000,axis:$c.attr('id'), queue:true} );
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.ScrollTo</title>
|
||||
<meta name="keywords" content="javascript, jquery, plugins, scroll, scrollTo, smooth, animation, to, effect, ariel, flesler, window, overflow, element, navigation, customizable" />
|
||||
<meta name="description" content="Demo of jQuery.scrollTo. Lightweight, cross-browser and highly customizable animated scrolling with jQuery, made by Ariel Flesler." />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<link type="text/css" rel="stylesheet" href="css/style.old.css" />
|
||||
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript">
|
||||
jQuery(function( $ ){
|
||||
//borrowed from jQuery easing plugin
|
||||
//http://gsgd.co.uk/sandbox/jquery.easing.php
|
||||
$.easing.elasout = function(x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
||||
};
|
||||
$('button').click(function(){//this is not the cleanest way to do this, I'm just keeping it short.
|
||||
var index = parseInt( $(this).prev('input').val() ) || 0;
|
||||
var $c = $(this).parent().next();
|
||||
$c.stop().scrollTo('li:eq('+index+')', {duration:2500, easing:'elasout',axis:$c.attr('id')});
|
||||
});
|
||||
$('#btn_screen').click(function(){
|
||||
$.scrollTo( $('#txt_screen').val(), {duration:2500} );
|
||||
});
|
||||
$('div.container a').click(function(){
|
||||
var $c = $(this).parents('.container');
|
||||
$c.stop().scrollTo( 0, {duration:2000,axis:$c.attr('id'), queue:true} );
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>jQuery.ScrollTo <strong>by Ariel Flesler</strong></h1>
|
||||
<div id="links" class="part" style="width:135px">
|
||||
<h3>Links</h3>
|
||||
<ul>
|
||||
<li><a target="_blank" href="http://plugins.jquery.com/project/ScrollTo">Project Page</a></li>
|
||||
<li><a target="_blank" href="http://flesler.blogspot.com/2007/10/jqueryscrollto.html">Main blog article</a></li>
|
||||
<li><a target="_blank" href="http://flesler.blogspot.com/search/label/jQuery.ScrollTo">All articles</a></li>
|
||||
<li><a target="_blank" href="http://flesler.webs.com/jQuery.LocalScroll/">LocalScroll Demo</a></li>
|
||||
<li><a target="_blank" href="http://flesler.webs.com/jQuery.SerialScroll/">SerialScroll Demo</a></li>
|
||||
<li><a target="_blank" href="./" rel="prev" rev="next">New Demo</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<label for="txt_screen">Scroll the window to <input id="txt_screen" type="text" value=".pane:eq(1)" /><input id="btn_screen" type="button" value="Scroll" /></label><br /><br />
|
||||
<label>Scroll to the #<input type="text" value="3" /> element inside this container<button>Scroll</button></label>
|
||||
<div id="y" class="container">
|
||||
<ul>
|
||||
<li style="background-color:#9933CC;"><p>0</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>1</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#FF0000;"><p>2</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>3</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#663366;"><p>4</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>5</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#FFFFCC;"><p>6</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#00FF00;"><p>7</p><a href="#">back to top</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<label>Scroll to the #<input type="text" value="3" /> element inside this container<button>Scroll</button></label>
|
||||
<div id="x" class="container">
|
||||
<ul style="width:4820px;">
|
||||
<li style="background-color:#9933CC;"><p>0</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>1</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FF0000;"><p>2</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>3</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#663366;"><p>4</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>5</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFFFCC;"><p>6</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FF00;"><p>7</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#9933CC;"><p>8</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>9</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FF0000;"><p>10</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>11</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#663366;"><p>12</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>13</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFFFCC;"><p>14</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FF00;"><p>15</p><a href="#">back to start</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<label>Scroll to the #<input type="text" value="16" /> element inside this container<button>Scroll</button></label>
|
||||
<div id="xy" class="container">
|
||||
<ul style="width:1500px;">
|
||||
<li style="background-color:#9933CC;"><p>0</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>1</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FF0000;"><p>2</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>3</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#663366;"><p>4</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>5</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFFFCC;"><p>6</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FF00;"><p>7</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#9933CC;"><p>8</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>9</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FF0000;"><p>10</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>11</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#663366;"><p>12</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>13</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFFFCC;"><p>14</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FF00;"><p>15</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#9933CC;"><p>16</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>17</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FF0000;"><p>18</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>19</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#663366;"><p>20</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>21</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFFFCC;"><p>22</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FF00;"><p>23</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#9933CC;"><p>24</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>25</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FF0000;"><p>26</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>27</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#663366;"><p>28</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>29</p><a href="#">back to start</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pane" style="background-color:#000000;margin-top:40px;"></div>
|
||||
<div class="pane" style="background-color:#333333;"></div>
|
||||
<div class="pane" style="background-color:#666666;"></div>
|
||||
<div class="pane" style="background-color:#999999;"></div>
|
||||
<div class="pane" style="background-color:#CCCCCC;"></div>
|
||||
<h1>jQuery.ScrollTo <strong>by Ariel Flesler</strong></h1>
|
||||
<div id="links" class="part" style="width:135px">
|
||||
<h3>Links</h3>
|
||||
<ul>
|
||||
<li><a target="_blank" href="http://plugins.jquery.com/project/ScrollTo">Project Page</a></li>
|
||||
<li><a target="_blank" href="http://flesler.blogspot.com/2007/10/jqueryscrollto.html">Main blog article</a></li>
|
||||
<li><a target="_blank" href="http://flesler.blogspot.com/search/label/jQuery.ScrollTo">All articles</a></li>
|
||||
<li><a target="_blank" href="http://flesler.webs.com/jQuery.LocalScroll/">LocalScroll Demo</a></li>
|
||||
<li><a target="_blank" href="http://flesler.webs.com/jQuery.SerialScroll/">SerialScroll Demo</a></li>
|
||||
<li><a target="_blank" href="./" rel="prev" rev="next">New Demo</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<label for="txt_screen">Scroll the window to <input id="txt_screen" type="text" value=".pane:eq(1)" /><input id="btn_screen" type="button" value="Scroll" /></label><br /><br />
|
||||
<label>Scroll to the #<input type="text" value="3" /> element inside this container<button>Scroll</button></label>
|
||||
<div id="y" class="container">
|
||||
<ul>
|
||||
<li style="background-color:#9933CC;"><p>0</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>1</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#FF0000;"><p>2</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>3</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#663366;"><p>4</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>5</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#FFFFCC;"><p>6</p><a href="#">back to top</a></li>
|
||||
<li style="background-color:#00FF00;"><p>7</p><a href="#">back to top</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<label>Scroll to the #<input type="text" value="3" /> element inside this container<button>Scroll</button></label>
|
||||
<div id="x" class="container">
|
||||
<ul style="width:4820px;">
|
||||
<li style="background-color:#9933CC;"><p>0</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>1</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FF0000;"><p>2</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>3</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#663366;"><p>4</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>5</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFFFCC;"><p>6</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FF00;"><p>7</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#9933CC;"><p>8</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>9</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FF0000;"><p>10</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>11</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#663366;"><p>12</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>13</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFFFCC;"><p>14</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FF00;"><p>15</p><a href="#">back to start</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<label>Scroll to the #<input type="text" value="16" /> element inside this container<button>Scroll</button></label>
|
||||
<div id="xy" class="container">
|
||||
<ul style="width:1500px;">
|
||||
<li style="background-color:#9933CC;"><p>0</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>1</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FF0000;"><p>2</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>3</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#663366;"><p>4</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>5</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFFFCC;"><p>6</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FF00;"><p>7</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#9933CC;"><p>8</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>9</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FF0000;"><p>10</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>11</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#663366;"><p>12</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>13</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFFFCC;"><p>14</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FF00;"><p>15</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#9933CC;"><p>16</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>17</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FF0000;"><p>18</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>19</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#663366;"><p>20</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>21</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFFFCC;"><p>22</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FF00;"><p>23</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#9933CC;"><p>24</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FFCC99;"><p>25</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#FF0000;"><p>26</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#00FFCC;"><p>27</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#663366;"><p>28</p><a href="#">back to start</a></li>
|
||||
<li style="background-color:#CCCCFF;"><p>29</p><a href="#">back to start</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="pane" style="background-color:#000000;margin-top:40px;"></div>
|
||||
<div class="pane" style="background-color:#333333;"></div>
|
||||
<div class="pane" style="background-color:#666666;"></div>
|
||||
<div class="pane" style="background-color:#999999;"></div>
|
||||
<div class="pane" style="background-color:#CCCCCC;"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+15
-15
@@ -1,21 +1,21 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Element MaxY - Compat Mode</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Element MaxY - Compat Mode</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>jQuery.scrollTo - Test Element MaxY - Compat Mode</h1>
|
||||
|
||||
<div id="viewport" style="width:600px;height:500px;overflow: auto">
|
||||
<div id="ua" style="height:1500px; width:500px; padding:0 40px; background-color:#AAA">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$('#viewport').test();
|
||||
</script>
|
||||
<h1>jQuery.scrollTo - Test Element MaxY - Compat Mode</h1>
|
||||
|
||||
<div id="viewport" style="width:600px;height:500px;overflow: auto">
|
||||
<div id="ua" style="height:1500px; width:500px; padding:0 40px; background-color:#AAA">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$('#viewport').test();
|
||||
</script>
|
||||
</html>
|
||||
|
||||
+15
-15
@@ -1,20 +1,20 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Element MaxY - Quirks Mode</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Element MaxY - Quirks Mode</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>jQuery.scrollTo - Test Element MaxY - Quirks Mode</h1>
|
||||
|
||||
<div id="viewport" style="width:600px;height:500px;overflow: auto">
|
||||
<div id="ua" style="height:1500px; width:500px; padding:0 40px; background-color:#AAA">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$('#viewport').test();
|
||||
</script>
|
||||
<h1>jQuery.scrollTo - Test Element MaxY - Quirks Mode</h1>
|
||||
|
||||
<div id="viewport" style="width:600px;height:500px;overflow: auto">
|
||||
<div id="ua" style="height:1500px; width:500px; padding:0 40px; background-color:#AAA">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$('#viewport').test();
|
||||
</script>
|
||||
</html>
|
||||
|
||||
+13
-13
@@ -1,19 +1,19 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Window MaxY - Compat Mode</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Window MaxY - Compat Mode</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>jQuery.scrollTo - Test Window MaxY - Compat Mode</h1>
|
||||
|
||||
<div id="ua" style="height:1500px; width:500px; padding:0 50px; background-color:#AAA">
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(window).test();
|
||||
</script>
|
||||
<h1>jQuery.scrollTo - Test Window MaxY - Compat Mode</h1>
|
||||
|
||||
<div id="ua" style="height:1500px; width:500px; padding:0 50px; background-color:#AAA">
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(window).test();
|
||||
</script>
|
||||
</html>
|
||||
|
||||
+12
-12
@@ -1,18 +1,18 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Window MaxY - Quirks Mode</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Window MaxY - Quirks Mode</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>jQuery.scrollTo - Test Window MaxY - Quirks Mode</h1>
|
||||
<h1>jQuery.scrollTo - Test Window MaxY - Quirks Mode</h1>
|
||||
|
||||
<div id="ua" style="height:1500px; width:500px; padding:0 50px; background-color:#AAA">
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(window).test();
|
||||
</script>
|
||||
<div id="ua" style="height:1500px; width:500px; padding:0 50px; background-color:#AAA">
|
||||
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(window).test();
|
||||
</script>
|
||||
</html>
|
||||
|
||||
Generated
Vendored
+13
-13
@@ -1,20 +1,20 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Window MaxY to Iframe - Compat Mode</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Window MaxY to Iframe - Compat Mode</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>jQuery.scrollTo - Test Window MaxY to Iframe - Compat Mode</h1>
|
||||
<h1>jQuery.scrollTo - Test Window MaxY to Iframe - Compat Mode</h1>
|
||||
|
||||
<iframe src="WinMaxY-compat.html?notest" style="width:500px" /></iframe>
|
||||
|
||||
<script type="text/javascript">
|
||||
setTimeout(function(){
|
||||
$('iframe').test();
|
||||
}, 1500 );
|
||||
</script>
|
||||
<iframe src="WinMaxY-compat.html?notest" style="width:500px" /></iframe>
|
||||
|
||||
<script type="text/javascript">
|
||||
setTimeout(function(){
|
||||
$('iframe').test();
|
||||
}, 1500 );
|
||||
</script>
|
||||
</html>
|
||||
|
||||
Generated
Vendored
+14
-14
@@ -1,19 +1,19 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Window MaxY to Iframe - Quirks Mode</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Window MaxY to Iframe - Quirks Mode</title>
|
||||
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.js"></script>
|
||||
<script type="text/javascript" src="../jquery.scrollTo.js"></script>
|
||||
<script type="text/javascript" src="test.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>jQuery.scrollTo - Test Window MaxY to Iframe - Quirks Mode</h1>
|
||||
|
||||
<iframe src="WinMaxY-quirks.html?notest" style="width:500px"></iframe>
|
||||
|
||||
<script type="text/javascript">
|
||||
setTimeout(function(){
|
||||
$('iframe').test();
|
||||
}, 1500 );
|
||||
</script>
|
||||
<h1>jQuery.scrollTo - Test Window MaxY to Iframe - Quirks Mode</h1>
|
||||
|
||||
<iframe src="WinMaxY-quirks.html?notest" style="width:500px"></iframe>
|
||||
|
||||
<script type="text/javascript">
|
||||
setTimeout(function(){
|
||||
$('iframe').test();
|
||||
}, 1500 );
|
||||
</script>
|
||||
</html>
|
||||
|
||||
Generated
Vendored
+5
-5
@@ -1,11 +1,11 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Window MaxY with Iframe - Compat Mode</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Window MaxY with Iframe - Compat Mode</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>jQuery.scrollTo - Test Window MaxY with Iframe - Compat Mode</h1>
|
||||
|
||||
<iframe src="WinMaxY-compat.html" />
|
||||
<h1>jQuery.scrollTo - Test Window MaxY with Iframe - Compat Mode</h1>
|
||||
|
||||
<iframe src="WinMaxY-compat.html" />
|
||||
</html>
|
||||
|
||||
Generated
Vendored
+4
-4
@@ -1,10 +1,10 @@
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Window MaxY with Iframe - Quirks Mode</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo - Test Window MaxY with Iframe - Quirks Mode</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>jQuery.scrollTo - Test Window MaxY with Iframe - Quirks Mode</h1>
|
||||
<h1>jQuery.scrollTo - Test Window MaxY with Iframe - Quirks Mode</h1>
|
||||
|
||||
<iframe src="WinMaxY-quirks.html" />
|
||||
<iframe src="WinMaxY-quirks.html" />
|
||||
</html>
|
||||
|
||||
+17
-17
@@ -1,24 +1,24 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo Tests</title>
|
||||
<meta name="keywords" content="javascript, jquery, plugins, scroll, scrollTo, smooth, animation, to, effect, ariel, flesler, window, overflow, element, navigation, customizable" />
|
||||
<meta name="description" content="Tests for jQuery ScrollTo. Made by Ariel Flesler." />
|
||||
<meta name="robots" content="index,follow" />
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<title>jQuery.scrollTo Tests</title>
|
||||
<meta name="keywords" content="javascript, jquery, plugins, scroll, scrollTo, smooth, animation, to, effect, ariel, flesler, window, overflow, element, navigation, customizable" />
|
||||
<meta name="description" content="Tests for jQuery ScrollTo. Made by Ariel Flesler." />
|
||||
<meta name="robots" content="index,follow" />
|
||||
</head>
|
||||
<body>
|
||||
<h1>jQuery.scrollTo Tests</h1>
|
||||
|
||||
<ul>
|
||||
<li><a href="WinMaxY-compat.html">Max window scrolling (compat mode)</a></li>
|
||||
<li><a href="WinMaxY-quirks.html">Max window scrolling (quirks mode)</a></li>
|
||||
<li><a href="ElemMaxY-compat.html">Max element scrolling (compat mode)</a></li>
|
||||
<li><a href="ElemMaxY-quirks.html">Max element scrolling (quirks mode)</a></li>
|
||||
<li><a href="WinMaxY-with-iframe-compat.html">Max window scrolling, within an iframe (compat mode)</a></li>
|
||||
<li><a href="WinMaxY-with-iframe-quirks.html">Max window scrolling, within an iframe (quirks mode)</a></li>
|
||||
<li><a href="WinMaxY-to-iframe-compat.html">Max iframe scrolling from outside (compat mode)</a></li>
|
||||
<li><a href="WinMaxY-to-iframe-quirks.html">Max iframe scrolling from outside (quirks mode)</a></li>
|
||||
</ul>
|
||||
<h1>jQuery.scrollTo Tests</h1>
|
||||
|
||||
<ul>
|
||||
<li><a href="WinMaxY-compat.html">Max window scrolling (compat mode)</a></li>
|
||||
<li><a href="WinMaxY-quirks.html">Max window scrolling (quirks mode)</a></li>
|
||||
<li><a href="ElemMaxY-compat.html">Max element scrolling (compat mode)</a></li>
|
||||
<li><a href="ElemMaxY-quirks.html">Max element scrolling (quirks mode)</a></li>
|
||||
<li><a href="WinMaxY-with-iframe-compat.html">Max window scrolling, within an iframe (compat mode)</a></li>
|
||||
<li><a href="WinMaxY-with-iframe-quirks.html">Max window scrolling, within an iframe (quirks mode)</a></li>
|
||||
<li><a href="WinMaxY-to-iframe-compat.html">Max iframe scrolling from outside (compat mode)</a></li>
|
||||
<li><a href="WinMaxY-to-iframe-quirks.html">Max iframe scrolling from outside (quirks mode)</a></li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+5
-5
@@ -55,11 +55,11 @@ For jQuery to work in Node, a window with a document is required. Since no such
|
||||
|
||||
```js
|
||||
require("jsdom").env("", function(err, window) {
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
if (err) {
|
||||
console.error(err);
|
||||
return;
|
||||
}
|
||||
|
||||
var $ = require("jquery")(window);
|
||||
var $ = require("jquery")(window);
|
||||
});
|
||||
```
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Awesome page</title>
|
||||
<title>Awesome page</title>
|
||||
</head>
|
||||
<body>
|
||||
hello world!
|
||||
hello world!
|
||||
</body>
|
||||
</html>
|
||||
|
||||
+2
-2
@@ -1,8 +1,8 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Other page</title>
|
||||
<title>Other page</title>
|
||||
</head>
|
||||
<body>
|
||||
hello there!
|
||||
hello there!
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -4176,7 +4176,7 @@ The resulting set of endpoints can be viewed as:<br>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">nodeSelector</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection/README">http://kubernetes.io/docs/user-guide/node-selection/README</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node’s labels for the pod to be scheduled on that node. More info: <a href="http://kubernetes.io/docs/user-guide/node-selection">http://kubernetes.io/docs/user-guide/node-selection</a></p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">false</p></td>
|
||||
<td class="tableblock halign-left valign-top"><p class="tableblock">object</p></td>
|
||||
<td class="tableblock halign-left valign-top"></td>
|
||||
@@ -8267,4 +8267,4 @@ Last updated 2016-11-17 06:26:10 UTC
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
+2
-100
@@ -6,104 +6,6 @@ assignees:
|
||||
title: Kubernetes API Overview
|
||||
---
|
||||
|
||||
Primary system and API concepts are documented in the [User guide](/docs/user-guide/).
|
||||
{% include user-guide-content-moved.md %}
|
||||
|
||||
Overall API conventions are described in the [API conventions doc](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api-conventions.md).
|
||||
|
||||
Remote access to the API is discussed in the [access doc](/docs/admin/accessing-the-api).
|
||||
|
||||
The Kubernetes API also serves as the foundation for the declarative configuration schema for the system. The [Kubectl](/docs/user-guide/kubectl) command-line tool can be used to create, update, delete, and get API objects.
|
||||
|
||||
Kubernetes also stores its serialized state (currently in [etcd](https://coreos.com/docs/distributed-configuration/getting-started-with-etcd/)) in terms of the API resources.
|
||||
|
||||
Kubernetes itself is decomposed into multiple components, which interact through its API.
|
||||
|
||||
## API changes
|
||||
|
||||
In our experience, any system that is successful needs to grow and change as new use cases emerge or existing ones change. Therefore, we expect the Kubernetes API to continuously change and grow. However, we intend to not break compatibility with existing clients, for an extended period of time. In general, new API resources and new resource fields can be expected to be added frequently. Elimination of resources or fields will require following a deprecation process. The precise deprecation policy for eliminating features is TBD, but once we reach our 1.0 milestone, there will be a specific policy.
|
||||
|
||||
What constitutes a compatible change and how to change the API are detailed by the [API change document](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api_changes.md).
|
||||
|
||||
## OpenAPI and Swagger definitions
|
||||
|
||||
Complete API details are documented using [Swagger v1.2](http://swagger.io/) and [OpenAPI](https://www.openapis.org/). The Kubernetes apiserver (aka "master") exposes an API that can be used to retrieve the Swagger v1.2 Kubernetes API spec located at `/swaggerapi`. You can also enable a UI to browse the API documentation at `/swagger-ui` by passing the `--enable-swagger-ui=true` flag to apiserver.
|
||||
|
||||
We also host a version of the [latest v1.2 API documentation UI](http://kubernetes.io/kubernetes/third_party/swagger-ui/). This is updated with the latest release, so if you are using a different version of Kubernetes you will want to use the spec from your apiserver.
|
||||
|
||||
Staring kubernetes 1.4, OpenAPI spec is also available at `/swagger.json`. While we are transitioning from Swagger v1.2 to OpenAPI (aka Swagger v2.0), some of the tools such as kubectl and swagger-ui are still using v1.2 spec. OpenAPI spec is in Beta as of Kubernetes 1.5.
|
||||
|
||||
Kubernetes implements an alternative Protobuf based serialization format for the API that is primarily intended for intra-cluster communication, documented in the [design proposal](https://github.com/kubernetes/kubernetes/blob/{{ page.githubbranch }}/docs/proposals/protobuf.md) and the IDL files for each schema are located in the Go packages that define the API objects.
|
||||
|
||||
## API versioning
|
||||
|
||||
To make it easier to eliminate fields or restructure resource representations, Kubernetes supports
|
||||
multiple API versions, each at a different API path, such as `/api/v1` or
|
||||
`/apis/extensions/v1beta1`.
|
||||
|
||||
We chose to version at the API level rather than at the resource or field level to ensure that the API presents a clear, consistent view of system resources and behavior, and to enable controlling access to end-of-lifed and/or experimental APIs. The JSON and Protobuf serialization schemas follow the same guidelines for schema changes - all descriptions below cover both formats.
|
||||
|
||||
Note that API versioning and Software versioning are only indirectly related. The [API and release
|
||||
versioning proposal](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/design/versioning.md) describes the relationship between API versioning and
|
||||
software versioning.
|
||||
|
||||
|
||||
Different API versions imply different levels of stability and support. The criteria for each level are described
|
||||
in more detail in the [API Changes documentation](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/api_changes.md#alpha-beta-and-stable-versions). They are summarized here:
|
||||
|
||||
- Alpha level:
|
||||
- The version names contain `alpha` (e.g. `v1alpha1`).
|
||||
- May be buggy. Enabling the feature may expose bugs. Disabled by default.
|
||||
- Support for feature may be dropped at any time without notice.
|
||||
- The API may change in incompatible ways in a later software release without notice.
|
||||
- Recommended for use only in short-lived testing clusters, due to increased risk of bugs and lack of long-term support.
|
||||
- Beta level:
|
||||
- The version names contain `beta` (e.g. `v2beta3`).
|
||||
- Code is well tested. Enabling the feature is considered safe. Enabled by default.
|
||||
- Support for the overall feature will not be dropped, though details may change.
|
||||
- The schema and/or semantics of objects may change in incompatible ways in a subsequent beta or stable release. When this happens,
|
||||
we will provide instructions for migrating to the next version. This may require deleting, editing, and re-creating
|
||||
API objects. The editing process may require some thought. This may require downtime for applications that rely on the feature.
|
||||
- Recommended for only non-business-critical uses because of potential for incompatible changes in subsequent releases. If you have
|
||||
multiple clusters which can be upgraded independently, you may be able to relax this restriction.
|
||||
- **Please do try our beta features and give feedback on them! Once they exit beta, it may not be practical for us to make more changes.**
|
||||
- Stable level:
|
||||
- The version name is `vX` where `X` is an integer.
|
||||
- Stable versions of features will appear in released software for many subsequent versions.
|
||||
|
||||
## API groups
|
||||
|
||||
To make it easier to extend the Kubernetes API, we implemented [*API groups*](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/api-group.md).
|
||||
The API group is specified in a REST path and in the `apiVersion` field of a serialized object.
|
||||
|
||||
Currently there are several API groups in use:
|
||||
|
||||
1. the "core" (oftentimes called "legacy", due to not having explicit group name) group, which is at
|
||||
REST path `/api/v1` and is not specified as part of the `apiVersion` field, e.g. `apiVersion: v1`.
|
||||
1. the named groups are at REST path `/apis/$GROUP_NAME/$VERSION`, and use `apiVersion: $GROUP_NAME/$VERSION`
|
||||
(e.g. `apiVersion: batch/v1`). Full list of supported API groups can be seen in [Kubernetes API reference](/docs/reference/).
|
||||
|
||||
|
||||
There are two supported paths to extending the API.
|
||||
1. [Third Party Resources](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/extending-api.md)
|
||||
are for users with very basic CRUD needs.
|
||||
1. Coming soon: users needing the full set of Kubernetes API semantics can implement their own apiserver
|
||||
and use the [aggregator](https://github.com/kubernetes/community/blob/master/contributors/design-proposals/aggregated-api-servers.md)
|
||||
to make it seamless for clients.
|
||||
|
||||
|
||||
## Enabling API groups
|
||||
|
||||
Certain resources and API groups are enabled by default. They can be enabled or disabled by setting `--runtime-config`
|
||||
on apiserver. `--runtime-config` accepts comma separated values. For ex: to disable batch/v1, set
|
||||
`--runtime-config=batch/v1=false`, to enable batch/v2alpha1, set `--runtime-config=batch/v2alpha1`.
|
||||
The flag accepts comma separated set of key=value pairs describing runtime configuration of the apiserver.
|
||||
|
||||
IMPORTANT: Enabling or disabling groups or resources requires restarting apiserver and controller-manager
|
||||
to pick up the `--runtime-config` changes.
|
||||
|
||||
## Enabling resources in the groups
|
||||
|
||||
DaemonSets, Deployments, HorizontalPodAutoscalers, Ingress, Jobs and ReplicaSets are enabled by default.
|
||||
Other extensions resources can be enabled by setting `--runtime-config` on
|
||||
apiserver. `--runtime-config` accepts comma separated values. For ex: to disable deployments and jobs, set
|
||||
`--runtime-config=extensions/v1beta1/deployments=false,extensions/v1beta1/jobs=false`
|
||||
[The Kubernetes API](/docs/concepts/overview/kubernetes-api/)
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: ReplicaSet
|
||||
metadata:
|
||||
name: my-repset
|
||||
spec:
|
||||
replicas: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
pod-is-for: garbage-collection-example
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
pod-is-for: garbage-collection-example
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx
|
||||
image: nginx
|
||||
@@ -0,0 +1,325 @@
|
||||
---
|
||||
title: Accessing Clusters
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
## Accessing the cluster API
|
||||
|
||||
### Accessing for the first time with kubectl
|
||||
|
||||
When accessing the Kubernetes API for the first time, we suggest using the
|
||||
Kubernetes CLI, `kubectl`.
|
||||
|
||||
To access a cluster, you need to know the location of the cluster and have credentials
|
||||
to access it. Typically, this is automatically set-up when you work through
|
||||
a [Getting started guide](/docs/getting-started-guides/),
|
||||
or someone else setup the cluster and provided you with credentials and a location.
|
||||
|
||||
Check the location and credentials that kubectl knows about with this command:
|
||||
|
||||
```shell
|
||||
$ kubectl config view
|
||||
```
|
||||
|
||||
Many of the [examples](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/) provide an introduction to using
|
||||
kubectl and complete documentation is found in the [kubectl manual](/docs/user-guide/kubectl/index).
|
||||
|
||||
### Directly accessing the REST API
|
||||
|
||||
Kubectl handles locating and authenticating to the apiserver.
|
||||
If you want to directly access the REST API with an http client like
|
||||
curl or wget, or a browser, there are several ways to locate and authenticate:
|
||||
|
||||
- Run kubectl in proxy mode.
|
||||
- Recommended approach.
|
||||
- Uses stored apiserver location.
|
||||
- Verifies identity of apiserver using self-signed cert. No MITM possible.
|
||||
- Authenticates to apiserver.
|
||||
- In future, may do intelligent client-side load-balancing and failover.
|
||||
- Provide the location and credentials directly to the http client.
|
||||
- Alternate approach.
|
||||
- Works with some types of client code that are confused by using a proxy.
|
||||
- Need to import a root cert into your browser to protect against MITM.
|
||||
|
||||
#### Using kubectl proxy
|
||||
|
||||
The following command runs kubectl in a mode where it acts as a reverse proxy. It handles
|
||||
locating the apiserver and authenticating.
|
||||
Run it like this:
|
||||
|
||||
```shell
|
||||
$ kubectl proxy --port=8080 &
|
||||
```
|
||||
|
||||
See [kubectl proxy](/docs/user-guide/kubectl/kubectl_proxy) for more details.
|
||||
|
||||
Then you can explore the API with curl, wget, or a browser, like so:
|
||||
|
||||
```shell
|
||||
$ curl http://localhost:8080/api/
|
||||
{
|
||||
"versions": [
|
||||
"v1"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Without kubectl proxy (before v1.3.x)
|
||||
|
||||
It is possible to avoid using kubectl proxy by passing an authentication token
|
||||
directly to the apiserver, like this:
|
||||
|
||||
```shell
|
||||
$ APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ")
|
||||
$ TOKEN=$(kubectl config view | grep token | cut -f 2 -d ":" | tr -d " ")
|
||||
$ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
|
||||
{
|
||||
"versions": [
|
||||
"v1"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Without kubectl proxy (post v1.3.x)
|
||||
|
||||
In Kubernetes version 1.3 or later, `kubectl config view` no longer displays the token. Use `kubectl describe secret...` to get the token for the default service account, like this:
|
||||
|
||||
``` shell
|
||||
$ APISERVER=$(kubectl config view | grep server | cut -f 2- -d ":" | tr -d " ")
|
||||
$ TOKEN=$(kubectl describe secret $(kubectl get secrets | grep default | cut -f1 -d ' ') | grep -E '^token' | cut -f2 -d':' | tr -d '\t')
|
||||
$ curl $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
|
||||
{
|
||||
"kind": "APIVersions",
|
||||
"versions": [
|
||||
"v1"
|
||||
],
|
||||
"serverAddressByClientCIDRs": [
|
||||
{
|
||||
"clientCIDR": "0.0.0.0/0",
|
||||
"serverAddress": "10.0.1.149:443"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The above examples use the `--insecure` flag. This leaves it subject to MITM
|
||||
attacks. When kubectl accesses the cluster it uses a stored root certificate
|
||||
and client certificates to access the server. (These are installed in the
|
||||
`~/.kube` directory). Since cluster certificates are typically self-signed, it
|
||||
may take special configuration to get your http client to use root
|
||||
certificate.
|
||||
|
||||
On some clusters, the apiserver does not require authentication; it may serve
|
||||
on localhost, or be protected by a firewall. There is not a standard
|
||||
for this. [Configuring Access to the API](/docs/admin/accessing-the-api)
|
||||
describes how a cluster admin can configure this. Such approaches may conflict
|
||||
with future high-availability support.
|
||||
|
||||
### Programmatic access to the API
|
||||
|
||||
The Kubernetes project-supported Go client library is at [https://github.com/kubernetes/client-go](https://github.com/kubernetes/client-go).
|
||||
|
||||
To use it,
|
||||
|
||||
* To get the library, run the following command: `go get k8s.io/client-go/<version number>/kubernetes` See [https://github.com/kubernetes/client-go](https://github.com/kubernetes/client-go) to see which versions are supported.
|
||||
* Write an application atop of the client-go clients. Note that client-go defines its own API objects, so if needed, please import API definitions from client-go rather than from the main repository, e.g., `import "k8s.io/client-go/1.4/pkg/api/v1"` is correct.
|
||||
|
||||
The Go client can use the same [kubeconfig file](/docs/concepts/cluster-administration/authenticate-across-clusters-kubeconfig/)
|
||||
as the kubectl CLI does to locate and authenticate to the apiserver. See this [example](https://github.com/kubernetes/client-go/blob/master/examples/out-of-cluster/main.go):
|
||||
|
||||
```golang
|
||||
import (
|
||||
"fmt"
|
||||
"k8s.io/client-go/1.4/kubernetes"
|
||||
"k8s.io/client-go/1.4/pkg/api/v1"
|
||||
"k8s.io/client-go/1.4/tools/clientcmd"
|
||||
)
|
||||
...
|
||||
// uses the current context in kubeconfig
|
||||
config, _ := clientcmd.BuildConfigFromFlags("", "path to kubeconfig")
|
||||
// creates the clientset
|
||||
clientset, _:= kubernetes.NewForConfig(config)
|
||||
// access the API to list pods
|
||||
pods, _:= clientset.Core().Pods("").List(v1.ListOptions{})
|
||||
fmt.Printf("There are %d pods in the cluster\n", len(pods.Items))
|
||||
...
|
||||
```
|
||||
|
||||
If the application is deployed as a Pod in the cluster, please refer to the [next section](#accessing-the-api-from-a-pod).
|
||||
|
||||
There are [client libraries](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/docs/devel/client-libraries.md) for accessing the API from other languages. See documentation for other libraries for how they authenticate.
|
||||
|
||||
### Accessing the API from a Pod
|
||||
|
||||
When accessing the API from a pod, locating and authenticating
|
||||
to the api server are somewhat different.
|
||||
|
||||
The recommended way to locate the apiserver within the pod is with
|
||||
the `kubernetes` DNS name, which resolves to a Service IP which in turn
|
||||
will be routed to an apiserver.
|
||||
|
||||
The recommended way to authenticate to the apiserver is with a
|
||||
[service account](/docs/user-guide/service-accounts) credential. By kube-system, a pod
|
||||
is associated with a service account, and a credential (token) for that
|
||||
service account is placed into the filesystem tree of each container in that pod,
|
||||
at `/var/run/secrets/kubernetes.io/serviceaccount/token`.
|
||||
|
||||
If available, a certificate bundle is placed into the filesystem tree of each
|
||||
container at `/var/run/secrets/kubernetes.io/serviceaccount/ca.crt`, and should be
|
||||
used to verify the serving certificate of the apiserver.
|
||||
|
||||
Finally, the default namespace to be used for namespaced API operations is placed in a file
|
||||
at `/var/run/secrets/kubernetes.io/serviceaccount/namespace` in each container.
|
||||
|
||||
From within a pod the recommended ways to connect to API are:
|
||||
|
||||
- run a kubectl proxy as one of the containers in the pod, or as a background
|
||||
process within a container. This proxies the
|
||||
Kubernetes API to the localhost interface of the pod, so that other processes
|
||||
in any container of the pod can access it. See this [example of using kubectl proxy
|
||||
in a pod](https://github.com/kubernetes/kubernetes/tree/{{page.githubbranch}}/examples/kubectl-container/).
|
||||
- use the Go client library, and create a client using the `rest.InClusterConfig()` and `kubernetes.NewForConfig()` functions.
|
||||
They handle locating and authenticating to the apiserver. [example](https://github.com/kubernetes/client-go/blob/master/examples/in-cluster/main.go)
|
||||
|
||||
In each case, the credentials of the pod are used to communicate securely with the apiserver.
|
||||
|
||||
|
||||
## Accessing services running on the cluster
|
||||
|
||||
The previous section was about connecting the Kubernetes API server. This section is about
|
||||
connecting to other services running on Kubernetes cluster. In Kubernetes, the
|
||||
[nodes](/docs/admin/node), [pods](/docs/user-guide/pods) and [services](/docs/user-guide/services) all have
|
||||
their own IPs. In many cases, the node IPs, pod IPs, and some service IPs on a cluster will not be
|
||||
routable, so they will not be reachable from a machine outside the cluster,
|
||||
such as your desktop machine.
|
||||
|
||||
### Ways to connect
|
||||
|
||||
You have several options for connecting to nodes, pods and services from outside the cluster:
|
||||
|
||||
- Access services through public IPs.
|
||||
- Use a service with type `NodePort` or `LoadBalancer` to make the service reachable outside
|
||||
the cluster. See the [services](/docs/user-guide/services) and
|
||||
[kubectl expose](/docs/user-guide/kubectl/kubectl_expose) documentation.
|
||||
- Depending on your cluster environment, this may just expose the service to your corporate network,
|
||||
or it may expose it to the internet. Think about whether the service being exposed is secure.
|
||||
Does it do its own authentication?
|
||||
- Place pods behind services. To access one specific pod from a set of replicas, such as for debugging,
|
||||
place a unique label on the pod it and create a new service which selects this label.
|
||||
- In most cases, it should not be necessary for application developer to directly access
|
||||
nodes via their nodeIPs.
|
||||
- Access services, nodes, or pods using the Proxy Verb.
|
||||
- Does apiserver authentication and authorization prior to accessing the remote service.
|
||||
Use this if the services are not secure enough to expose to the internet, or to gain
|
||||
access to ports on the node IP, or for debugging.
|
||||
- Proxies may cause problems for some web applications.
|
||||
- Only works for HTTP/HTTPS.
|
||||
- Described [here](#manually-constructing-apiserver-proxy-urls).
|
||||
- Access from a node or pod in the cluster.
|
||||
- Run a pod, and then connect to a shell in it using [kubectl exec](/docs/user-guide/kubectl/kubectl_exec).
|
||||
Connect to other nodes, pods, and services from that shell.
|
||||
- Some clusters may allow you to ssh to a node in the cluster. From there you may be able to
|
||||
access cluster services. This is a non-standard method, and will work on some clusters but
|
||||
not others. Browsers and other tools may or may not be installed. Cluster DNS may not work.
|
||||
|
||||
### Discovering builtin services
|
||||
|
||||
Typically, there are several services which are started on a cluster by kube-system. Get a list of these
|
||||
with the `kubectl cluster-info` command:
|
||||
|
||||
```shell
|
||||
$ kubectl cluster-info
|
||||
|
||||
Kubernetes master is running at https://104.197.5.247
|
||||
elasticsearch-logging is running at https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging
|
||||
kibana-logging is running at https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/kibana-logging
|
||||
kube-dns is running at https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/kube-dns
|
||||
grafana is running at https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/monitoring-grafana
|
||||
heapster is running at https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/monitoring-heapster
|
||||
```
|
||||
|
||||
This shows the proxy-verb URL for accessing each service.
|
||||
For example, this cluster has cluster-level logging enabled (using Elasticsearch), which can be reached
|
||||
at `https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging/` if suitable credentials are passed, or through a kubectl proxy at, for example:
|
||||
`http://localhost:8080/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging/`.
|
||||
(See [above](#accessing-the-cluster-api) for how to pass credentials or use kubectl proxy.)
|
||||
|
||||
#### Manually constructing apiserver proxy URLs
|
||||
|
||||
As mentioned above, you use the `kubectl cluster-info` command to retrieve the service's proxy URL. To create proxy URLs that include service endpoints, suffixes, and parameters, you simply append to the service's proxy URL:
|
||||
`http://`*`kubernetes_master_address`*`/api/v1/proxy/namespaces/`*`namespace_name`*`/services/`*`service_name[:port_name]`*
|
||||
|
||||
If you haven't specified a name for your port, you don't have to specify *port_name* in the URL
|
||||
|
||||
##### Examples
|
||||
|
||||
* To access the Elasticsearch service endpoint `_search?q=user:kimchy`, you would use: `http://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging/_search?q=user:kimchy`
|
||||
* To access the Elasticsearch cluster health information `_cluster/health?pretty=true`, you would use: `https://104.197.5.247/api/v1/proxy/namespaces/kube-system/services/elasticsearch-logging/_cluster/health?pretty=true`
|
||||
|
||||
```json
|
||||
{
|
||||
"cluster_name" : "kubernetes_logging",
|
||||
"status" : "yellow",
|
||||
"timed_out" : false,
|
||||
"number_of_nodes" : 1,
|
||||
"number_of_data_nodes" : 1,
|
||||
"active_primary_shards" : 5,
|
||||
"active_shards" : 5,
|
||||
"relocating_shards" : 0,
|
||||
"initializing_shards" : 0,
|
||||
"unassigned_shards" : 5
|
||||
}
|
||||
```
|
||||
|
||||
#### Using web browsers to access services running on the cluster
|
||||
|
||||
You may be able to put an apiserver proxy url into the address bar of a browser. However:
|
||||
|
||||
- Web browsers cannot usually pass tokens, so you may need to use basic (password) auth. Apiserver can be configured to accept basic auth,
|
||||
but your cluster may not be configured to accept basic auth.
|
||||
- Some web apps may not work, particularly those with client side javascript that construct urls in a
|
||||
way that is unaware of the proxy path prefix.
|
||||
|
||||
## Requesting redirects
|
||||
|
||||
The redirect capabilities have been deprecated and removed. Please use a proxy (see below) instead.
|
||||
|
||||
## So Many Proxies
|
||||
|
||||
There are several different proxies you may encounter when using Kubernetes:
|
||||
|
||||
1. The [kubectl proxy](#directly-accessing-the-rest-api):
|
||||
- runs on a user's desktop or in a pod
|
||||
- proxies from a localhost address to the Kubernetes apiserver
|
||||
- client to proxy uses HTTP
|
||||
- proxy to apiserver uses HTTPS
|
||||
- locates apiserver
|
||||
- adds authentication headers
|
||||
1. The [apiserver proxy](#discovering-builtin-services):
|
||||
- is a bastion built into the apiserver
|
||||
- connects a user outside of the cluster to cluster IPs which otherwise might not be reachable
|
||||
- runs in the apiserver processes
|
||||
- client to proxy uses HTTPS (or http if apiserver so configured)
|
||||
- proxy to target may use HTTP or HTTPS as chosen by proxy using available information
|
||||
- can be used to reach a Node, Pod, or Service
|
||||
- does load balancing when used to reach a Service
|
||||
1. The [kube proxy](/docs/user-guide/services/#ips-and-vips):
|
||||
- runs on each node
|
||||
- proxies UDP and TCP
|
||||
- does not understand HTTP
|
||||
- provides load balancing
|
||||
- is just used to reach services
|
||||
1. A Proxy/Load-balancer in front of apiserver(s):
|
||||
- existence and implementation varies from cluster to cluster (e.g. nginx)
|
||||
- sits between all clients and one or more apiservers
|
||||
- acts as load balancer if there are several apiservers.
|
||||
1. Cloud Load Balancers on external services:
|
||||
- are provided by some cloud providers (e.g. AWS ELB, Google Cloud Load Balancer)
|
||||
- are created automatically when the Kubernetes service has type `LoadBalancer`
|
||||
- use UDP/TCP only
|
||||
- implementation varies by cloud provider.
|
||||
|
||||
Kubernetes users will typically not need to worry about anything other than the first two types. The cluster admin
|
||||
will typically ensure that the latter types are setup correctly.
|
||||
@@ -0,0 +1,67 @@
|
||||
---
|
||||
assignees:
|
||||
- soltysh
|
||||
- sttts
|
||||
title: Auditing
|
||||
---
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
Kubernetes Audit provides a security-relevant chronological set of records documenting
|
||||
the sequence of activities that have affected system by individual users, administrators
|
||||
or other components of the system. It allows cluster administrator to
|
||||
answer the following questions:
|
||||
- what happened?
|
||||
- when did it happen?
|
||||
- who initiated it?
|
||||
- on what did it happen?
|
||||
- where was it observed?
|
||||
- from where was it initiated?
|
||||
- to where was it going?
|
||||
|
||||
NOTE: Currently, Kubernetes provides only basic audit capabilities, there is still a lot
|
||||
of work going on to provide fully featured auditing capabilities (see [this issue](https://github.com/kubernetes/features/issues/22)).
|
||||
|
||||
Kubernetes audit is part of [kube-apiserver](/docs/admin/kube-apiserver) logging all requests
|
||||
coming to the server. Each audit log contains two entries:
|
||||
|
||||
1. The request line containing:
|
||||
- unique id allowing to match the response line (see 2)
|
||||
- source ip of the request
|
||||
- HTTP method being invoked
|
||||
- original user invoking the operation
|
||||
- impersonated user for the operation
|
||||
- namespace of the request or <none>
|
||||
- URI as requested
|
||||
2. The response line containing:
|
||||
- the unique id from 1
|
||||
- response code
|
||||
|
||||
Example output for user `admin` asking for a list of pods:
|
||||
|
||||
```
|
||||
2016-09-07T13:03:57.400333046Z AUDIT: id="5c3b8227-4af9-4322-8a71-542231c3887b" ip="127.0.0.1" method="GET" user="admin" as="<self>" namespace="default" uri="/api/v1/namespaces/default/pods"
|
||||
2016-09-07T13:03:57.400710987Z AUDIT: id="5c3b8227-4af9-4322-8a71-542231c3887b" response="200"
|
||||
```
|
||||
|
||||
NOTE: The audit capabilities are available *only* for the secured endpoint of the API server.
|
||||
|
||||
## Configuration
|
||||
|
||||
[Kube-apiserver](/docs/admin/kube-apiserver) provides following options which are responsible
|
||||
for configuring where and how audit logs are handled:
|
||||
|
||||
- `audit-log-path` - enables the audit log pointing to a file where the requests are being logged to.
|
||||
- `audit-log-maxage` - specifies maximum number of days to retain old audit log files based on the timestamp encoded in their filename.
|
||||
- `audit-log-maxbackup` - specifies maximum number of old audit log files to retain.
|
||||
- `audit-log-maxsize` - specifies maximum size in megabytes of the audit log file before it gets rotated. Defaults to 100MB
|
||||
|
||||
If an audit log file already exists, Kubernetes appends new audit logs to that file.
|
||||
Otherwise, Kubernetes creates an audit log file at the location you specified in
|
||||
`audit-log-path`. If the audit log file exceeds the size you specify in `audit-log-maxsize`,
|
||||
Kubernetes will rename the current log file by appending the current timestamp on
|
||||
the file name (before the file extension) and create a new audit log file.
|
||||
Kubernetes may delete old log files when creating a new log file; you can configure
|
||||
how many files are retained and how old they can be by specifying the `audit-log-maxbackup`
|
||||
and `audit-log-maxage` options.
|
||||
@@ -0,0 +1,314 @@
|
||||
---
|
||||
assignees:
|
||||
- mikedanese
|
||||
- thockin
|
||||
title: Authenticating Across Clusters with kubeconfig
|
||||
---
|
||||
|
||||
Authentication in Kubernetes can differ for different individuals.
|
||||
|
||||
- A running kubelet might have one way of authenticating (i.e. certificates).
|
||||
- Users might have a different way of authenticating (i.e. tokens).
|
||||
- Administrators might have a list of certificates which they provide individual users.
|
||||
- There may be multiple clusters, and we may want to define them all in one place - giving users the ability to use their own certificates and reusing the same global configuration.
|
||||
|
||||
So in order to easily switch between multiple clusters, for multiple users, a kubeconfig file was defined.
|
||||
|
||||
This file contains a series of authentication mechanisms and cluster connection information associated with nicknames. It also introduces the concept of a tuple of authentication information (user) and cluster connection information called a context that is also associated with a nickname.
|
||||
|
||||
Multiple kubeconfig files are allowed, if specified explicitly. At runtime they are loaded and merged along with override options specified from the command line (see [rules](#loading-and-merging-rules) below).
|
||||
|
||||
## Related discussion
|
||||
|
||||
[http://issue.k8s.io/1755](http://issue.k8s.io/1755)
|
||||
|
||||
## Components of a kubeconfig file
|
||||
|
||||
### Example kubeconfig file
|
||||
|
||||
```yaml
|
||||
current-context: federal-context
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
api-version: v1
|
||||
server: http://cow.org:8080
|
||||
name: cow-cluster
|
||||
- cluster:
|
||||
certificate-authority: path/to/my/cafile
|
||||
server: https://horse.org:4443
|
||||
name: horse-cluster
|
||||
- cluster:
|
||||
insecure-skip-tls-verify: true
|
||||
server: https://pig.org:443
|
||||
name: pig-cluster
|
||||
contexts:
|
||||
- context:
|
||||
cluster: horse-cluster
|
||||
namespace: chisel-ns
|
||||
user: green-user
|
||||
name: federal-context
|
||||
- context:
|
||||
cluster: pig-cluster
|
||||
namespace: saw-ns
|
||||
user: black-user
|
||||
name: queen-anne-context
|
||||
kind: Config
|
||||
preferences:
|
||||
colors: true
|
||||
users:
|
||||
- name: blue-user
|
||||
user:
|
||||
token: blue-token
|
||||
- name: green-user
|
||||
user:
|
||||
client-certificate: path/to/my/client/cert
|
||||
client-key: path/to/my/client/key
|
||||
```
|
||||
|
||||
### Breakdown/explanation of components
|
||||
|
||||
#### cluster
|
||||
|
||||
```yaml
|
||||
clusters:
|
||||
- cluster:
|
||||
certificate-authority: path/to/my/cafile
|
||||
server: https://horse.org:4443
|
||||
name: horse-cluster
|
||||
- cluster:
|
||||
insecure-skip-tls-verify: true
|
||||
server: https://pig.org:443
|
||||
name: pig-cluster
|
||||
```
|
||||
|
||||
A `cluster` contains endpoint data for a kubernetes cluster. This includes the fully
|
||||
qualified url for the kubernetes apiserver, as well as the cluster's certificate
|
||||
authority or `insecure-skip-tls-verify: true`, if the cluster's serving
|
||||
certificate is not signed by a system trusted certificate authority.
|
||||
A `cluster` has a name (nickname) which acts as a dictionary key for the cluster
|
||||
within this kubeconfig file. You can add or modify `cluster` entries using
|
||||
[`kubectl config set-cluster`](/docs/user-guide/kubectl/kubectl_config_set-cluster/).
|
||||
|
||||
#### user
|
||||
|
||||
```yaml
|
||||
users:
|
||||
- name: blue-user
|
||||
user:
|
||||
token: blue-token
|
||||
- name: green-user
|
||||
user:
|
||||
client-certificate: path/to/my/client/cert
|
||||
client-key: path/to/my/client/key
|
||||
```
|
||||
|
||||
A `user` defines client credentials for authenticating to a kubernetes cluster. A
|
||||
`user` has a name (nickname) which acts as its key within the list of user entries
|
||||
after kubeconfig is loaded/merged. Available credentials are `client-certificate`,
|
||||
`client-key`, `token`, and `username/password`. `username/password` and `token`
|
||||
are mutually exclusive, but client certs and keys can be combined with them.
|
||||
You can add or modify `user` entries using
|
||||
[`kubectl config set-credentials`](/docs/user-guide/kubectl/kubectl_config_set-credentials).
|
||||
|
||||
#### context
|
||||
|
||||
```yaml
|
||||
contexts:
|
||||
- context:
|
||||
cluster: horse-cluster
|
||||
namespace: chisel-ns
|
||||
user: green-user
|
||||
name: federal-context
|
||||
```
|
||||
|
||||
A `context` defines a named [`cluster`](#cluster),[`user`](#user),[`namespace`](/docs/user-guide/namespaces) tuple
|
||||
which is used to send requests to the specified cluster using the provided authentication info and
|
||||
namespace. Each of the three is optional; it is valid to specify a context with only one of `cluster`,
|
||||
`user`,`namespace`, or to specify none. Unspecified values, or named values that don't have corresponding
|
||||
entries in the loaded kubeconfig (e.g. if the context specified a `pink-user` for the above kubeconfig file)
|
||||
will be replaced with the default. See [Loading and merging rules](#loading-and-merging) below for override/merge behavior.
|
||||
You can add or modify `context` entries with [`kubectl config set-context`](/docs/user-guide/kubectl/kubectl_config_set-context).
|
||||
|
||||
#### current-context
|
||||
|
||||
```yaml
|
||||
current-context: federal-context
|
||||
```
|
||||
|
||||
`current-context` is the nickname or 'key' for the cluster,user,namespace tuple that kubectl
|
||||
will use by default when loading config from this file. You can override any of the values in kubectl
|
||||
from the commandline, by passing `--context=CONTEXT`, `--cluster=CLUSTER`, `--user=USER`, and/or `--namespace=NAMESPACE` respectively.
|
||||
You can change the `current-context` with [`kubectl config use-context`](/docs/user-guide/kubectl/kubectl_config_use-context).
|
||||
|
||||
#### miscellaneous
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Config
|
||||
preferences:
|
||||
colors: true
|
||||
```
|
||||
|
||||
`apiVersion` and `kind` identify the version and schema for the client parser and should not
|
||||
be edited manually.
|
||||
|
||||
`preferences` specify optional (and currently unused) kubectl preferences.
|
||||
|
||||
## Viewing kubeconfig files
|
||||
|
||||
`kubectl config view` will display the current kubeconfig settings. By default
|
||||
it will show you all loaded kubeconfig settings; you can filter the view to just
|
||||
the settings relevant to the `current-context` by passing `--minify`. See
|
||||
[`kubectl config view`](/docs/user-guide/kubectl/kubectl_config_view) for other options.
|
||||
|
||||
## Building your own kubeconfig file
|
||||
|
||||
NOTE, that if you are deploying k8s via kube-up.sh, you do not need to create your own kubeconfig files, the script will do it for you.
|
||||
|
||||
In any case, you can easily use this file as a template to create your own kubeconfig files.
|
||||
|
||||
So, lets do a quick walk through the basics of the above file so you can easily modify it as needed...
|
||||
|
||||
The above file would likely correspond to an api-server which was launched using the `--token-auth-file=tokens.csv` option, where the tokens.csv file looked something like this:
|
||||
|
||||
```conf
|
||||
blue-user,blue-user,1
|
||||
mister-red,mister-red,2
|
||||
```
|
||||
|
||||
Also, since we have other users who validate using **other** mechanisms, the api-server would have probably been launched with other authentication options (there are many such options, make sure you understand which ones YOU care about before crafting a kubeconfig file, as nobody needs to implement all the different permutations of possible authentication schemes).
|
||||
|
||||
- Since the user for the current context is "green-user", any client of the api-server using this kubeconfig file would naturally be able to log in successfully, because we are providing the green-user's client credentials.
|
||||
- Similarly, we can operate as the "blue-user" if we choose to change the value of current-context.
|
||||
|
||||
In the above scenario, green-user would have to log in by providing certificates, whereas blue-user would just provide the token. All this information would be handled for us by the
|
||||
|
||||
## Loading and merging rules
|
||||
|
||||
The rules for loading and merging the kubeconfig files are straightforward, but there are a lot of them. The final config is built in this order:
|
||||
|
||||
1. Get the kubeconfig from disk. This is done with the following hierarchy and merge rules:
|
||||
|
||||
|
||||
If the `CommandLineLocation` (the value of the `kubeconfig` command line option) is set, use this file only. No merging. Only one instance of this flag is allowed.
|
||||
|
||||
|
||||
Else, if `EnvVarLocation` (the value of `$KUBECONFIG`) is available, use it as a list of files that should be merged.
|
||||
Merge files together based on the following rules.
|
||||
Empty filenames are ignored. Files with non-deserializable content produced errors.
|
||||
The first file to set a particular value or map key wins and the value or map key is never changed.
|
||||
This means that the first file to set `CurrentContext` will have its context preserved. It also means that if two files specify a "red-user", only values from the first file's red-user are used. Even non-conflicting entries from the second file's "red-user" are discarded.
|
||||
|
||||
|
||||
Otherwise, use HomeDirectoryLocation (`~/.kube/config`) with no merging.
|
||||
1. Determine the context to use based on the first hit in this chain
|
||||
1. command line argument - the value of the `context` command line option
|
||||
1. `current-context` from the merged kubeconfig file
|
||||
1. Empty is allowed at this stage
|
||||
1. Determine the cluster info and user to use. At this point, we may or may not have a context. They are built based on the first hit in this chain. (run it twice, once for user, once for cluster)
|
||||
1. command line argument - `user` for user name and `cluster` for cluster name
|
||||
1. If context is present, then use the context's value
|
||||
1. Empty is allowed
|
||||
1. Determine the actual cluster info to use. At this point, we may or may not have a cluster info. Build each piece of the cluster info based on the chain (first hit wins):
|
||||
1. command line arguments - `server`, `api-version`, `certificate-authority`, and `insecure-skip-tls-verify`
|
||||
1. If cluster info is present and a value for the attribute is present, use it.
|
||||
1. If you don't have a server location, error.
|
||||
1. Determine the actual user info to use. User is built using the same rules as cluster info, EXCEPT that you can only have one authentication technique per user.
|
||||
1. Load precedence is 1) command line flag, 2) user fields from kubeconfig
|
||||
1. The command line flags are: `client-certificate`, `client-key`, `username`, `password`, and `token`.
|
||||
1. If there are two conflicting techniques, fail.
|
||||
1. For any information still missing, use default values and potentially prompt for authentication information
|
||||
1. All file references inside of a kubeconfig file are resolved relative to the location of the kubeconfig file itself. When file references are presented on the command line
|
||||
they are resolved relative to the current working directory. When paths are saved in the ~/.kube/config, relative paths are stored relatively while absolute paths are stored absolutely.
|
||||
|
||||
Any path in a kubeconfig file is resolved relative to the location of the kubeconfig file itself.
|
||||
|
||||
|
||||
## Manipulation of kubeconfig via `kubectl config <subcommand>`
|
||||
|
||||
In order to more easily manipulate kubeconfig files, there are a series of subcommands to `kubectl config` to help.
|
||||
See [kubectl/kubectl_config](/docs/user-guide/kubectl/kubectl_config) for help.
|
||||
|
||||
### Example
|
||||
|
||||
```shell
|
||||
$ kubectl config set-credentials myself --username=admin --password=secret
|
||||
$ kubectl config set-cluster local-server --server=http://localhost:8080
|
||||
$ kubectl config set-context default-context --cluster=local-server --user=myself
|
||||
$ kubectl config use-context default-context
|
||||
$ kubectl config set contexts.default-context.namespace the-right-prefix
|
||||
$ kubectl config view
|
||||
```
|
||||
|
||||
produces this output
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
server: http://localhost:8080
|
||||
name: local-server
|
||||
contexts:
|
||||
- context:
|
||||
cluster: local-server
|
||||
namespace: the-right-prefix
|
||||
user: myself
|
||||
name: default-context
|
||||
current-context: default-context
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: myself
|
||||
user:
|
||||
password: secret
|
||||
username: admin
|
||||
```
|
||||
|
||||
and a kubeconfig file that looks like this
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
clusters:
|
||||
- cluster:
|
||||
server: http://localhost:8080
|
||||
name: local-server
|
||||
contexts:
|
||||
- context:
|
||||
cluster: local-server
|
||||
namespace: the-right-prefix
|
||||
user: myself
|
||||
name: default-context
|
||||
current-context: default-context
|
||||
kind: Config
|
||||
preferences: {}
|
||||
users:
|
||||
- name: myself
|
||||
user:
|
||||
password: secret
|
||||
username: admin
|
||||
```
|
||||
|
||||
#### Commands for the example file
|
||||
|
||||
```shell
|
||||
$ kubectl config set preferences.colors true
|
||||
$ kubectl config set-cluster cow-cluster --server=http://cow.org:8080 --api-version=v1
|
||||
$ kubectl config set-cluster horse-cluster --server=https://horse.org:4443 --certificate-authority=path/to/my/cafile
|
||||
$ kubectl config set-cluster pig-cluster --server=https://pig.org:443 --insecure-skip-tls-verify=true
|
||||
$ kubectl config set-credentials blue-user --token=blue-token
|
||||
$ kubectl config set-credentials green-user --client-certificate=path/to/my/client/cert --client-key=path/to/my/client/key
|
||||
$ kubectl config set-context queen-anne-context --cluster=pig-cluster --user=black-user --namespace=saw-ns
|
||||
$ kubectl config set-context federal-context --cluster=horse-cluster --user=green-user --namespace=chisel-ns
|
||||
$ kubectl config use-context federal-context
|
||||
```
|
||||
|
||||
### Final notes for tying it all together
|
||||
|
||||
So, tying this all together, a quick start to create your own kubeconfig file:
|
||||
|
||||
- Take a good look and understand how your api-server is being launched: You need to know YOUR security requirements and policies before you can design a kubeconfig file for convenient authentication.
|
||||
|
||||
- Replace the snippet above with information for your cluster's api-server endpoint.
|
||||
|
||||
- Make sure your api-server is launched in such a way that at least one user (i.e. green-user) credentials are provided to it. You will of course have to look at api-server documentation in order to determine the current state-of-the-art in terms of providing authentication details.
|
||||
@@ -0,0 +1,382 @@
|
||||
---
|
||||
assignees:
|
||||
- bprashanth
|
||||
- quinton-hoole
|
||||
title: Cross-cluster Service Discovery using Federated Services
|
||||
---
|
||||
|
||||
This guide explains how to use Kubernetes Federated Services to deploy
|
||||
a common Service across multiple Kubernetes clusters. This makes it
|
||||
easy to achieve cross-cluster service discovery and availability zone
|
||||
fault tolerance for your Kubernetes applications.
|
||||
|
||||
|
||||
* TOC
|
||||
{:toc}
|
||||
|
||||
## Prerequisites
|
||||
|
||||
This guide assumes that you have a running Kubernetes Cluster
|
||||
Federation installation. If not, then head over to the
|
||||
[federation admin guide](/docs/admin/federation/) to learn how to
|
||||
bring up a cluster federation (or have your cluster administrator do
|
||||
this for you). Other tutorials, for example
|
||||
[this one](https://github.com/kelseyhightower/kubernetes-cluster-federation)
|
||||
by Kelsey Hightower, are also available to help you.
|
||||
|
||||
You are also expected to have a basic
|
||||
[working knowledge of Kubernetes](/docs/getting-started-guides/) in
|
||||
general, and [Services](/docs/user-guide/services/) in particular.
|
||||
|
||||
## Overview
|
||||
|
||||
Federated Services are created in much that same way as traditional
|
||||
[Kubernetes Services](/docs/user-guide/services/) by making an API
|
||||
call which specifies the desired properties of your service. In the
|
||||
case of Federated Services, this API call is directed to the
|
||||
Federation API endpoint, rather than a Kubernetes cluster API
|
||||
endpoint. The API for Federated Services is 100% compatible with the
|
||||
API for traditional Kubernetes Services.
|
||||
|
||||
Once created, the Federated Service automatically:
|
||||
|
||||
1. Creates matching Kubernetes Services in every cluster underlying your Cluster Federation,
|
||||
2. Monitors the health of those service "shards" (and the clusters in which they reside), and
|
||||
3. Manages a set of DNS records in a public DNS provider (like Google Cloud DNS, or AWS Route 53), thus ensuring that clients
|
||||
of your federated service can seamlessly locate an appropriate healthy service endpoint at all times, even in the event of cluster,
|
||||
availability zone or regional outages.
|
||||
|
||||
Clients inside your federated Kubernetes clusters (i.e. Pods) will
|
||||
automatically find the local shard of the Federated Service in their
|
||||
cluster if it exists and is healthy, or the closest healthy shard in a
|
||||
different cluster if it does not.
|
||||
|
||||
## Hybrid cloud capabilities
|
||||
|
||||
Federations of Kubernetes Clusters can include clusters running in
|
||||
different cloud providers (e.g. Google Cloud, AWS), and on-premises
|
||||
(e.g. on OpenStack). Simply create all of the clusters that you
|
||||
require, in the appropriate cloud providers and/or locations, and
|
||||
register each cluster's API endpoint and credentials with your
|
||||
Federation API Server (See the
|
||||
[federation admin guide](/docs/admin/federation/) for details).
|
||||
|
||||
Thereafter, your applications and services can span different clusters
|
||||
and cloud providers as described in more detail below.
|
||||
|
||||
## Creating a federated service
|
||||
|
||||
This is done in the usual way, for example:
|
||||
|
||||
``` shell
|
||||
kubectl --context=federation-cluster create -f services/nginx.yaml
|
||||
```
|
||||
|
||||
The '--context=federation-cluster' flag tells kubectl to submit the
|
||||
request to the Federation API endpoint, with the appropriate
|
||||
credentials. If you have not yet configured such a context, visit the
|
||||
[federation admin guide](/docs/admin/federation/) or one of the
|
||||
[administration tutorials](https://github.com/kelseyhightower/kubernetes-cluster-federation)
|
||||
to find out how to do so.
|
||||
|
||||
As described above, the Federated Service will automatically create
|
||||
and maintain matching Kubernetes services in all of the clusters
|
||||
underlying your federation.
|
||||
|
||||
You can verify this by checking in each of the underlying clusters, for example:
|
||||
|
||||
``` shell
|
||||
kubectl --context=gce-asia-east1a get services nginx
|
||||
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
|
||||
nginx 10.63.250.98 104.199.136.89 80/TCP 9m
|
||||
```
|
||||
|
||||
The above assumes that you have a context named 'gce-asia-east1a'
|
||||
configured in your client for your cluster in that zone. The name and
|
||||
namespace of the underlying services will automatically match those of
|
||||
the Federated Service that you created above (and if you happen to
|
||||
have had services of the same name and namespace already existing in
|
||||
any of those clusters, they will be automatically adopted by the
|
||||
Federation and updated to conform with the specification of your
|
||||
Federated Service - either way, the end result will be the same).
|
||||
|
||||
The status of your Federated Service will automatically reflect the
|
||||
real-time status of the underlying Kubernetes services, for example:
|
||||
|
||||
``` shell
|
||||
$kubectl --context=federation-cluster describe services nginx
|
||||
|
||||
Name: nginx
|
||||
Namespace: default
|
||||
Labels: run=nginx
|
||||
Selector: run=nginx
|
||||
Type: LoadBalancer
|
||||
IP: 10.63.250.98
|
||||
LoadBalancer Ingress: 104.197.246.190, 130.211.57.243, 104.196.14.231, 104.199.136.89, ...
|
||||
Port: http 80/TCP
|
||||
Endpoints: <none>
|
||||
Session Affinity: None
|
||||
No events.
|
||||
```
|
||||
|
||||
Note the 'LoadBalancer Ingress' addresses of your Federated Service
|
||||
correspond with the 'LoadBalancer Ingress' addresses of all of the
|
||||
underlying Kubernetes services (once these have been allocated - this
|
||||
may take a few seconds). For inter-cluster and inter-cloud-provider
|
||||
networking between service shards to work correctly, your services
|
||||
need to have an externally visible IP address. [Service Type:
|
||||
Loadbalancer](/docs/user-guide/services/#type-loadbalancer)
|
||||
is typically used for this, although other options
|
||||
(e.g. [External IP's](/docs/user-guide/services/#external-ips)) exist.
|
||||
|
||||
Note also that we have not yet provisioned any backend Pods to receive
|
||||
the network traffic directed to these addresses (i.e. 'Service
|
||||
Endpoints'), so the Federated Service does not yet consider these to
|
||||
be healthy service shards, and has accordingly not yet added their
|
||||
addresses to the DNS records for this Federated Service (more on this
|
||||
aspect later).
|
||||
|
||||
## Adding backend pods
|
||||
|
||||
To render the underlying service shards healthy, we need to add
|
||||
backend Pods behind them. This is currently done directly against the
|
||||
API endpoints of the underlying clusters (although in future the
|
||||
Federation server will be able to do all this for you with a single
|
||||
command, to save you the trouble). For example, to create backend Pods
|
||||
in 13 underlying clusters:
|
||||
|
||||
``` shell
|
||||
for CLUSTER in asia-east1-c asia-east1-a asia-east1-b \
|
||||
europe-west1-d europe-west1-c europe-west1-b \
|
||||
us-central1-f us-central1-a us-central1-b us-central1-c \
|
||||
us-east1-d us-east1-c us-east1-b
|
||||
do
|
||||
kubectl --context=$CLUSTER run nginx --image=nginx:1.11.1-alpine --port=80
|
||||
done
|
||||
```
|
||||
|
||||
Note that `kubectl run` automatically adds the `run=nginx` labels required to associate the backend pods with their services.
|
||||
|
||||
## Verifying public DNS records
|
||||
|
||||
Once the above Pods have successfully started and have begun listening
|
||||
for connections, Kubernetes will report them as healthy endpoints of
|
||||
the service in that cluster (via automatic health checks). The Cluster
|
||||
Federation will in turn consider each of these
|
||||
service 'shards' to be healthy, and place them in serving by
|
||||
automatically configuring corresponding public DNS records. You can
|
||||
use your preferred interface to your configured DNS provider to verify
|
||||
this. For example, if your Federation is configured to use Google
|
||||
Cloud DNS, and a managed DNS domain 'example.com':
|
||||
|
||||
``` shell
|
||||
$ gcloud dns managed-zones describe example-dot-com
|
||||
creationTime: '2016-06-26T18:18:39.229Z'
|
||||
description: Example domain for Kubernetes Cluster Federation
|
||||
dnsName: example.com.
|
||||
id: '3229332181334243121'
|
||||
kind: dns#managedZone
|
||||
name: example-dot-com
|
||||
nameServers:
|
||||
- ns-cloud-a1.googledomains.com.
|
||||
- ns-cloud-a2.googledomains.com.
|
||||
- ns-cloud-a3.googledomains.com.
|
||||
- ns-cloud-a4.googledomains.com.
|
||||
```
|
||||
|
||||
``` shell
|
||||
$ gcloud dns record-sets list --zone example-dot-com
|
||||
NAME TYPE TTL DATA
|
||||
example.com. NS 21600 ns-cloud-e1.googledomains.com., ns-cloud-e2.googledomains.com.
|
||||
example.com. SOA 21600 ns-cloud-e1.googledomains.com. cloud-dns-hostmaster.google.com. 1 21600 3600 1209600 300
|
||||
nginx.mynamespace.myfederation.svc.example.com. A 180 104.197.246.190, 130.211.57.243, 104.196.14.231, 104.199.136.89,...
|
||||
nginx.mynamespace.myfederation.svc.us-central1-a.example.com. A 180 104.197.247.191
|
||||
nginx.mynamespace.myfederation.svc.us-central1-b.example.com. A 180 104.197.244.180
|
||||
nginx.mynamespace.myfederation.svc.us-central1-c.example.com. A 180 104.197.245.170
|
||||
nginx.mynamespace.myfederation.svc.us-central1-f.example.com. CNAME 180 nginx.mynamespace.myfederation.svc.us-central1.example.com.
|
||||
nginx.mynamespace.myfederation.svc.us-central1.example.com. A 180 104.197.247.191, 104.197.244.180, 104.197.245.170
|
||||
nginx.mynamespace.myfederation.svc.asia-east1-a.example.com. A 180 130.211.57.243
|
||||
nginx.mynamespace.myfederation.svc.asia-east1-b.example.com. CNAME 180 nginx.mynamespace.myfederation.svc.asia-east1.example.com.
|
||||
nginx.mynamespace.myfederation.svc.asia-east1-c.example.com. A 180 130.211.56.221
|
||||
nginx.mynamespace.myfederation.svc.asia-east1.example.com. A 180 130.211.57.243, 130.211.56.221
|
||||
nginx.mynamespace.myfederation.svc.europe-west1.example.com. CNAME 180 nginx.mynamespace.myfederation.svc.example.com.
|
||||
nginx.mynamespace.myfederation.svc.europe-west1-d.example.com. CNAME 180 nginx.mynamespace.myfederation.svc.europe-west1.example.com.
|
||||
... etc.
|
||||
```
|
||||
|
||||
Note: If your Federation is configured to use AWS Route53, you can use one of the equivalent AWS tools, for example:
|
||||
|
||||
``` shell
|
||||
$aws route53 list-hosted-zones
|
||||
```
|
||||
and
|
||||
``` shell
|
||||
$aws route53 list-resource-record-sets --hosted-zone-id Z3ECL0L9QLOVBX
|
||||
```
|
||||
|
||||
Whatever DNS provider you use, any DNS query tool (for example 'dig'
|
||||
or 'nslookup') will of course also allow you to see the records
|
||||
created by the Federation for you. Note that you should either point
|
||||
these tools directly at your DNS provider (e.g. `dig
|
||||
@ns-cloud-e1.googledomains.com...`) or expect delays in the order of
|
||||
your configured TTL (180 seconds, by default) before seeing updates,
|
||||
due to caching by intermediate DNS servers.
|
||||
|
||||
### Some notes about the above example
|
||||
|
||||
1. Notice that there is a normal ('A') record for each service shard that has at least one healthy backend endpoint. For example, in us-central1-a, 104.197.247.191 is the external IP address of the service shard in that zone, and in asia-east1-a the address is 130.211.56.221.
|
||||
2. Similarly, there are regional 'A' records which include all healthy shards in that region. For example, 'us-central1'. These regional records are useful for clients which do not have a particular zone preference, and as a building block for the automated locality and failover mechanism described below.
|
||||
2. For zones where there are currently no healthy backend endpoints, a CNAME ('Canonical Name') record is used to alias (automatically redirect) those queries to the next closest healthy zone. In the example, the service shard in us-central1-f currently has no healthy backend endpoints (i.e. Pods), so a CNAME record has been created to automatically redirect queries to other shards in that region (us-central1 in this case).
|
||||
3. Similarly, if no healthy shards exist in the enclosing region, the search progresses further afield. In the europe-west1-d availability zone, there are no healthy backends, so queries are redirected to the broader europe-west1 region (which also has no healthy backends), and onward to the global set of healthy addresses (' nginx.mynamespace.myfederation.svc.example.com.')
|
||||
|
||||
The above set of DNS records is automatically kept in sync with the
|
||||
current state of health of all service shards globally by the
|
||||
Federated Service system. DNS resolver libraries (which are invoked by
|
||||
all clients) automatically traverse the hierarchy of 'CNAME' and 'A'
|
||||
records to return the correct set of healthy IP addresses. Clients can
|
||||
then select any one of the returned addresses to initiate a network
|
||||
connection (and fail over automatically to one of the other equivalent
|
||||
addresses if required).
|
||||
|
||||
## Discovering a federated service
|
||||
|
||||
### From pods inside your federated clusters
|
||||
|
||||
By default, Kubernetes clusters come pre-configured with a
|
||||
cluster-local DNS server ('KubeDNS'), as well as an intelligently
|
||||
constructed DNS search path which together ensure that DNS queries
|
||||
like "myservice", "myservice.mynamespace",
|
||||
"bobsservice.othernamespace" etc issued by your software running
|
||||
inside Pods are automatically expanded and resolved correctly to the
|
||||
appropriate service IP of services running in the local cluster.
|
||||
|
||||
With the introduction of Federated Services and Cross-Cluster Service
|
||||
Discovery, this concept is extended to cover Kubernetes services
|
||||
running in any other cluster across your Cluster Federation, globally.
|
||||
To take advantage of this extended range, you use a slightly different
|
||||
DNS name (of the form "<servicename>.<namespace>.<federationname>",
|
||||
e.g. myservice.mynamespace.myfederation) to resolve Federated
|
||||
Services. Using a different DNS name also avoids having your existing
|
||||
applications accidentally traversing cross-zone or cross-region
|
||||
networks and you incurring perhaps unwanted network charges or
|
||||
latency, without you explicitly opting in to this behavior.
|
||||
|
||||
So, using our NGINX example service above, and the Federated Service
|
||||
DNS name form just described, let's consider an example: A Pod in a
|
||||
cluster in the `us-central1-f` availability zone needs to contact our
|
||||
NGINX service. Rather than use the service's traditional cluster-local
|
||||
DNS name (```"nginx.mynamespace"```, which is automatically expanded
|
||||
to ```"nginx.mynamespace.svc.cluster.local"```) it can now use the
|
||||
service's Federated DNS name, which is
|
||||
```"nginx.mynamespace.myfederation"```. This will be automatically
|
||||
expanded and resolved to the closest healthy shard of my NGINX
|
||||
service, wherever in the world that may be. If a healthy shard exists
|
||||
in the local cluster, that service's cluster-local (typically
|
||||
10.x.y.z) IP address will be returned (by the cluster-local KubeDNS).
|
||||
This is almost exactly equivalent to non-federated service resolution
|
||||
(almost because KubeDNS actually returns both a CNAME and an A record
|
||||
for local federated services, but applications will be oblivious
|
||||
to this minor technical difference).
|
||||
|
||||
But if the service does not exist in the local cluster (or it exists
|
||||
but has no healthy backend pods), the DNS query is automatically
|
||||
expanded to
|
||||
```"nginx.mynamespace.myfederation.svc.us-central1-f.example.com"```
|
||||
(i.e. logically "find the external IP of one of the shards closest to
|
||||
my availability zone"). This expansion is performed automatically by
|
||||
KubeDNS, which returns the associated CNAME record. This results in
|
||||
automatic traversal of the hierarchy of DNS records in the above
|
||||
example, and ends up at one of the external IP's of the Federated
|
||||
Service in the local us-central1 region (i.e. 104.197.247.191,
|
||||
104.197.244.180 or 104.197.245.170).
|
||||
|
||||
It is of course possible to explicitly target service shards in
|
||||
availability zones and regions other than the ones local to a Pod by
|
||||
specifying the appropriate DNS names explicitly, and not relying on
|
||||
automatic DNS expansion. For example,
|
||||
"nginx.mynamespace.myfederation.svc.europe-west1.example.com" will
|
||||
resolve to all of the currently healthy service shards in Europe, even
|
||||
if the Pod issuing the lookup is located in the U.S., and irrespective
|
||||
of whether or not there are healthy shards of the service in the U.S.
|
||||
This is useful for remote monitoring and other similar applications.
|
||||
|
||||
### From other clients outside your federated clusters
|
||||
|
||||
Much of the above discussion applies equally to external clients,
|
||||
except that the automatic DNS expansion described is no longer
|
||||
possible. So external clients need to specify one of the fully
|
||||
qualified DNS names of the Federated Service, be that a zonal,
|
||||
regional or global name. For convenience reasons, it is often a good
|
||||
idea to manually configure additional static CNAME records in your
|
||||
service, for example:
|
||||
|
||||
``` shell
|
||||
eu.nginx.acme.com CNAME nginx.mynamespace.myfederation.svc.europe-west1.example.com.
|
||||
us.nginx.acme.com CNAME nginx.mynamespace.myfederation.svc.us-central1.example.com.
|
||||
nginx.acme.com CNAME nginx.mynamespace.myfederation.svc.example.com.
|
||||
```
|
||||
That way your clients can always use the short form on the left, and
|
||||
always be automatically routed to the closest healthy shard on their
|
||||
home continent. All of the required failover is handled for you
|
||||
automatically by Kubernetes Cluster Federation. Future releases will
|
||||
improve upon this even further.
|
||||
|
||||
## Handling failures of backend pods and whole clusters
|
||||
|
||||
Standard Kubernetes service cluster-IP's already ensure that
|
||||
non-responsive individual Pod endpoints are automatically taken out of
|
||||
service with low latency (a few seconds). In addition, as alluded
|
||||
above, the Kubernetes Cluster Federation system automatically monitors
|
||||
the health of clusters and the endpoints behind all of the shards of
|
||||
your Federated Service, taking shards in and out of service as
|
||||
required (e.g. when all of the endpoints behind a service, or perhaps
|
||||
the entire cluster or availability zone go down, or conversely recover
|
||||
from an outage). Due to the latency inherent in DNS caching (the cache
|
||||
timeout, or TTL for Federated Service DNS records is configured to 3
|
||||
minutes, by default, but can be adjusted), it may take up to that long
|
||||
for all clients to completely fail over to an alternative cluster in
|
||||
the case of catastrophic failure. However, given the number of
|
||||
discrete IP addresses which can be returned for each regional service
|
||||
endpoint (see e.g. us-central1 above, which has three alternatives)
|
||||
many clients will fail over automatically to one of the alternative
|
||||
IP's in less time than that given appropriate configuration.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
#### I cannot connect to my cluster federation API
|
||||
Check that your
|
||||
|
||||
1. Client (typically kubectl) is correctly configured (including API endpoints and login credentials), and
|
||||
2. Cluster Federation API server is running and network-reachable.
|
||||
|
||||
See the [federation admin guide](/docs/admin/federation/) to learn
|
||||
how to bring up a cluster federation correctly (or have your cluster administrator do this for you), and how to correctly configure your client.
|
||||
|
||||
#### I can create a federated service successfully against the cluster federation API, but no matching services are created in my underlying clusters
|
||||
Check that:
|
||||
|
||||
1. Your clusters are correctly registered in the Cluster Federation API (`kubectl describe clusters`)
|
||||
2. Your clusters are all 'Active'. This means that the cluster Federation system was able to connect and authenticate against the clusters' endpoints. If not, consult the logs of the federation-controller-manager pod to ascertain what the failure might be. (`kubectl --namespace=federation logs $(kubectl get pods --namespace=federation -l module=federation-controller-manager -oname`)
|
||||
3. That the login credentials provided to the Cluster Federation API for the clusters have the correct authorization and quota to create services in the relevant namespace in the clusters. Again you should see associated error messages providing more detail in the above log file if this is not the case.
|
||||
4. Whether any other error is preventing the service creation operation from succeeding (look for `service-controller` errors in the output of `kubectl logs federation-controller-manager --namespace federation`).
|
||||
|
||||
#### I can create a federated service successfully, but no matching DNS records are created in my DNS provider.
|
||||
Check that:
|
||||
|
||||
1. Your federation name, DNS provider, DNS domain name are configured correctly. Consult the [federation admin guide](/docs/admin/federation/) or [tutorial](https://github.com/kelseyhightower/kubernetes-cluster-federation) to learn
|
||||
how to configure your Cluster Federation system's DNS provider (or have your cluster administrator do this for you).
|
||||
2. Confirm that the Cluster Federation's service-controller is successfully connecting to and authenticating against your selected DNS provider (look for `service-controller` errors or successes in the output of `kubectl logs federation-controller-manager --namespace federation`)
|
||||
3. Confirm that the Cluster Federation's service-controller is successfully creating DNS records in your DNS provider (or outputting errors in its logs explaining in more detail what's failing).
|
||||
|
||||
#### Matching DNS records are created in my DNS provider, but clients are unable to resolve against those names
|
||||
Check that:
|
||||
|
||||
1. The DNS registrar that manages your federation DNS domain has been correctly configured to point to your configured DNS provider's nameservers. See for example [Google Domains Documentation](https://support.google.com/domains/answer/3290309?hl=en&ref_topic=3251230) and [Google Cloud DNS Documentation](https://cloud.google.com/dns/update-name-servers), or equivalent guidance from your domain registrar and DNS provider.
|
||||
|
||||
#### This troubleshooting guide did not help me solve my problem
|
||||
|
||||
1. Please use one of our [support channels](http://kubernetes.io/docs/troubleshooting/) to seek assistance.
|
||||
|
||||
## For more information
|
||||
|
||||
* [Federation proposal](https://github.com/kubernetes/kubernetes/blob/{{page.githubbranch}}/docs/proposals/federation.md) details use cases that motivated this work.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user